Name | browser-core JSON |
Version |
0.2.4
JSON |
| download |
home_page | None |
Summary | Um framework robusto e configurável para automação de navegadores, com gestão de perfis, sessões e uma CLI. |
upload_time | 2025-07-09 01:11:04 |
maintainer | None |
docs_url | None |
author | gabigolo |
requires_python | >=3.8 |
license | MIT |
keywords |
automation
selenium
web
browser
framework
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Browser-Core
[](https://badge.fury.io/py/browser-core)
[](https://opensource.org/licenses/MIT)
**Browser-Core** é uma plataforma de orquestração de ambientes de navegador, projetada para automação web em escala, com
foco em eficiência, isolamento e reprodutibilidade total.
---
## Visão Geral
O Browser-Core evoluiu de uma simples biblioteca de automação para uma plataforma de orquestração completa. Ele permite
provisionar, gerir e executar frotas de "Workers" (navegadores) em paralelo, com uma arquitetura robusta e elegante.
A base do framework é um **sistema de snapshots em camadas**, análogo ao Docker e Git, que permite criar, derivar e
reutilizar estados de navegador (como sessões com login efetuado) de forma rápida, eficiente em disco e, crucialmente, *
*100% reprodutível**.
## Conceitos Fundamentais
* **Snapshots em Camadas**: Crie "imagens" do estado do seu navegador (com cookies, `localStorage`, etc.) e derive
outras a partir delas. Diga adeus à necessidade de repetir o login a cada execução.
* **Workers Isolados**: Execute cada tarefa em um "Worker" limpo e isolado, instanciado a partir de um snapshot,
garantindo que execuções paralelas não interfiram umas nas outras.
* **API Fluente e Intuitiva**: Interaja com os elementos da página de forma declarativa e legível com o método
`worker.get()`, que torna a automação mais limpa e de fácil manutenção.
* **Gestão Automática de Drivers**: O `browser-core` faz o download e gere o cache da versão exata do WebDriver
necessária para cada snapshot, eliminando problemas de compatibilidade.
* **CLI Integrada**: Uma ferramenta de linha de comando para listar, inspecionar e gerir seus snapshots e o
armazenamento de objetos.
---
## Instalação
A forma recomendada de instalar o `browser-core` é através do PyPI:
```bash
pip install browser-core
```
---
## Um Fluxo de Trabalho Moderno
O uso do `browser-core` é dividido em duas fases lógicas: a **preparação de ambientes** (criação de snapshots) e a *
*execução de tarefas**.
### Fase 1: Criar um Snapshot Reutilizável
Primeiro, você cria um estado base. O caso de uso mais comum é um snapshot com uma sessão de usuário já autenticada.
Este processo é feito uma única vez e automatizado pelo `WorkforceManager`.
```python
# scripts/create_login_snapshot.py
import os
from browser_core import WorkforceManager, Worker, create_selector, ConfigurationError
from browser_core.types import SelectorType
# De preferência, carregue credenciais como variáveis de ambiente
# Nunca coloque senhas ou dados sensíveis diretamente no código.
# Antes de executar, defina as variáveis no seu terminal:
# export APP_USER="meu_usuario@exemplo.com"
# export APP_PASSWORD="minha-senha-super-segura"
APP_USER = os.getenv("APP_USER")
APP_PASSWORD = os.getenv("APP_PASSWORD")
# 1. Defina a função que executa a lógica de setup
def perform_login(worker: Worker):
"""Esta função navega e realiza o login para criar o estado desejado."""
# Valida se as credenciais foram carregadas do ambiente
if not APP_USER or not APP_PASSWORD:
raise ConfigurationError("As variáveis de ambiente APP_USER e APP_PASSWORD devem ser definidas.")
worker.logger.info("Iniciando processo de login para criar o snapshot...")
worker.navigate_to("https://app.exemplo.com/login")
# Define os seletores de forma clara e reutilizável
EMAIL_INPUT = create_selector("input[name='email']", SelectorType.CSS)
PASSWORD_INPUT = create_selector("input[name='password']", SelectorType.CSS)
LOGIN_BUTTON = create_selector("//button[text()='Entrar']", SelectorType.XPATH)
# Utiliza a API para interagir com a página
worker.get(EMAIL_INPUT).send_keys(APP_USER)
worker.get(PASSWORD_INPUT).send_keys(APP_PASSWORD)
worker.get(LOGIN_BUTTON).click()
# Aguarda a navegação para a página de dashboard, confirmando o login
worker.get(create_selector("#dashboard-welcome-message", SelectorType.CSS))
worker.logger.info("Login realizado com sucesso! Estado pronto para ser capturado.")
# 2. Execute o orquestrador para criar o snapshot
def main():
workforce = WorkforceManager()
# Assumindo que um snapshot base para o Chrome já existe.
# Ele pode ser criado com a CLI ou um script simples.
BASE_SNAPSHOT = "chrome_base" # Ex: um snapshot limpo do Chrome
NEW_SNAPSHOT = "app_logged_in_v1"
try:
workforce.create_snapshot_from_task(
base_snapshot_id=BASE_SNAPSHOT,
new_snapshot_id=NEW_SNAPSHOT,
setup_function=perform_login,
metadata={
"description": "Sessão autenticada no app.exemplo.com.",
"user": APP_USER
}
)
print(f"\nSnapshot '{NEW_SNAPSHOT}' criado com sucesso!")
except Exception as e:
print(f"\n[!!!] Falha ao criar o snapshot: {e}")
if __name__ == "__main__":
main()
```
### Fase 2: Executar Tarefas Usando o Snapshot
Com o snapshot `app_logged_in_v1` pronto, você pode executar inúmeras tarefas que dependem de um usuário autenticado, de
forma massivamente paralela, e **sem nunca mais precisar fazer login**.
```python
# scripts/run_report_tasks.py
from browser_core import WorkforceManager, Worker, create_selector, default_settings
from browser_core.types import SelectorType
# --- Lógica da Tarefa ---
# Esta função já parte do princípio que o worker está logado.
def extract_report_data(worker: Worker, report_id: str):
worker.logger.info(f"Iniciando extração para o relatório: {report_id}")
worker.navigate_to(f"https://app.exemplo.com/reports/{report_id}")
REPORT_TABLE = create_selector("#report-data-table", SelectorType.CSS)
# A simples chamada a .text força o worker a aguardar o elemento aparecer
table_data = worker.get(REPORT_TABLE).text
# ... aqui você processaria os dados da tabela ...
processed_data = {"report_id": report_id, "content_length": len(table_data)}
worker.logger.info(f"Extração do relatório '{report_id}' concluída.")
return processed_data
# --- Lógica de Setup do Worker (opcional) ---
# Função executada uma vez por worker antes de ele começar a processar os itens.
def worker_session_setup(worker: Worker) -> bool:
worker.logger.info(f"Worker {worker.logger.extra['task_id']} está pronto e online.")
# Poderia, por exemplo, navegar para uma página inicial comum.
# Retornar True indica que o setup foi bem-sucedido.
return True
# --- Execução em Lote ---
def main():
settings = default_settings()
# Para depuração, é útil desativar o modo headless
settings["browser"]["headless"] = False
workforce = WorkforceManager(settings)
# Lista de tarefas a serem executadas
reports_to_process = ["Q1-2024", "Q2-2024", "Q3-2024", "Q4-2024"]
try:
results = workforce.run_tasks_in_squad(
squad_size=2, # Executa 2 navegadores em paralelo
base_snapshot_id="app_logged_in_v1", # Usa o estado de login
task_items=reports_to_process,
worker_setup_function=worker_session_setup,
item_processing_function=extract_report_data
)
print("\n--- Processamento Concluído ---")
for res in results:
print(res)
except Exception as e:
print(f"\n[!!!] Uma falha ocorreu durante a execução do esquadrão: {e}")
if __name__ == "__main__":
main()
```
### Uso da CLI
Use o comando `browser-core` no seu terminal para gerir o ecossistema.
* **Listar snapshots disponíveis:**
```bash
browser-core snapshots list
```
* **Inspecionar os detalhes de um snapshot:**
```bash
browser-core snapshots inspect app_logged_in_v1
```
* **Limpar todo o armazenamento (cuidado, operação destrutiva!):**
```bash
browser-core storage clean
```
---
## Desenvolvimento e Contribuição
Se pretende contribuir para o `browser-core`, siga estes passos para configurar seu ambiente.
1. **Clone o repositório:**
```bash
git clone https://github.com/gabrielbarbosel/browser-core.git
cd browser-core
```
2. **Crie e ative um ambiente virtual:**
```bash
python -m venv .venv
source .venv/bin/activate # No Linux/macOS
# .venv\Scripts\activate # No Windows
```
3. **Instale o projeto em modo "editável":**
```bash
pip install -e .
Raw data
{
"_id": null,
"home_page": null,
"name": "browser-core",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "automation, selenium, web, browser, framework",
"author": "gabigolo",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/dc/51/08d0760fd54489af08f9e0a20d096f5089be99765318290b12e60a79e9b6/browser_core-0.2.4.tar.gz",
"platform": null,
"description": "# Browser-Core\n\n[](https://badge.fury.io/py/browser-core)\n[](https://opensource.org/licenses/MIT)\n\n**Browser-Core** \u00e9 uma plataforma de orquestra\u00e7\u00e3o de ambientes de navegador, projetada para automa\u00e7\u00e3o web em escala, com\nfoco em efici\u00eancia, isolamento e reprodutibilidade total.\n\n---\n\n## Vis\u00e3o Geral\n\nO Browser-Core evoluiu de uma simples biblioteca de automa\u00e7\u00e3o para uma plataforma de orquestra\u00e7\u00e3o completa. Ele permite\nprovisionar, gerir e executar frotas de \"Workers\" (navegadores) em paralelo, com uma arquitetura robusta e elegante.\n\nA base do framework \u00e9 um **sistema de snapshots em camadas**, an\u00e1logo ao Docker e Git, que permite criar, derivar e\nreutilizar estados de navegador (como sess\u00f5es com login efetuado) de forma r\u00e1pida, eficiente em disco e, crucialmente, *\n*100% reprodut\u00edvel**.\n\n## Conceitos Fundamentais\n\n* **Snapshots em Camadas**: Crie \"imagens\" do estado do seu navegador (com cookies, `localStorage`, etc.) e derive\n outras a partir delas. Diga adeus \u00e0 necessidade de repetir o login a cada execu\u00e7\u00e3o.\n* **Workers Isolados**: Execute cada tarefa em um \"Worker\" limpo e isolado, instanciado a partir de um snapshot,\n garantindo que execu\u00e7\u00f5es paralelas n\u00e3o interfiram umas nas outras.\n* **API Fluente e Intuitiva**: Interaja com os elementos da p\u00e1gina de forma declarativa e leg\u00edvel com o m\u00e9todo\n `worker.get()`, que torna a automa\u00e7\u00e3o mais limpa e de f\u00e1cil manuten\u00e7\u00e3o.\n* **Gest\u00e3o Autom\u00e1tica de Drivers**: O `browser-core` faz o download e gere o cache da vers\u00e3o exata do WebDriver\n necess\u00e1ria para cada snapshot, eliminando problemas de compatibilidade.\n* **CLI Integrada**: Uma ferramenta de linha de comando para listar, inspecionar e gerir seus snapshots e o\n armazenamento de objetos.\n\n---\n\n## Instala\u00e7\u00e3o\n\nA forma recomendada de instalar o `browser-core` \u00e9 atrav\u00e9s do PyPI:\n\n```bash\npip install browser-core\n```\n\n---\n\n## Um Fluxo de Trabalho Moderno\n\nO uso do `browser-core` \u00e9 dividido em duas fases l\u00f3gicas: a **prepara\u00e7\u00e3o de ambientes** (cria\u00e7\u00e3o de snapshots) e a *\n*execu\u00e7\u00e3o de tarefas**.\n\n### Fase 1: Criar um Snapshot Reutiliz\u00e1vel\n\nPrimeiro, voc\u00ea cria um estado base. O caso de uso mais comum \u00e9 um snapshot com uma sess\u00e3o de usu\u00e1rio j\u00e1 autenticada.\nEste processo \u00e9 feito uma \u00fanica vez e automatizado pelo `WorkforceManager`.\n\n```python\n# scripts/create_login_snapshot.py\nimport os\nfrom browser_core import WorkforceManager, Worker, create_selector, ConfigurationError\nfrom browser_core.types import SelectorType\n\n# De prefer\u00eancia, carregue credenciais como vari\u00e1veis de ambiente\n# Nunca coloque senhas ou dados sens\u00edveis diretamente no c\u00f3digo.\n# Antes de executar, defina as vari\u00e1veis no seu terminal:\n# export APP_USER=\"meu_usuario@exemplo.com\"\n# export APP_PASSWORD=\"minha-senha-super-segura\"\nAPP_USER = os.getenv(\"APP_USER\")\nAPP_PASSWORD = os.getenv(\"APP_PASSWORD\")\n\n\n# 1. Defina a fun\u00e7\u00e3o que executa a l\u00f3gica de setup\ndef perform_login(worker: Worker):\n \"\"\"Esta fun\u00e7\u00e3o navega e realiza o login para criar o estado desejado.\"\"\"\n # Valida se as credenciais foram carregadas do ambiente\n if not APP_USER or not APP_PASSWORD:\n raise ConfigurationError(\"As vari\u00e1veis de ambiente APP_USER e APP_PASSWORD devem ser definidas.\")\n\n worker.logger.info(\"Iniciando processo de login para criar o snapshot...\")\n worker.navigate_to(\"https://app.exemplo.com/login\")\n\n # Define os seletores de forma clara e reutiliz\u00e1vel\n EMAIL_INPUT = create_selector(\"input[name='email']\", SelectorType.CSS)\n PASSWORD_INPUT = create_selector(\"input[name='password']\", SelectorType.CSS)\n LOGIN_BUTTON = create_selector(\"//button[text()='Entrar']\", SelectorType.XPATH)\n\n # Utiliza a API para interagir com a p\u00e1gina\n worker.get(EMAIL_INPUT).send_keys(APP_USER)\n worker.get(PASSWORD_INPUT).send_keys(APP_PASSWORD)\n worker.get(LOGIN_BUTTON).click()\n\n # Aguarda a navega\u00e7\u00e3o para a p\u00e1gina de dashboard, confirmando o login\n worker.get(create_selector(\"#dashboard-welcome-message\", SelectorType.CSS))\n worker.logger.info(\"Login realizado com sucesso! Estado pronto para ser capturado.\")\n\n\n# 2. Execute o orquestrador para criar o snapshot\ndef main():\n workforce = WorkforceManager()\n\n # Assumindo que um snapshot base para o Chrome j\u00e1 existe.\n # Ele pode ser criado com a CLI ou um script simples.\n BASE_SNAPSHOT = \"chrome_base\" # Ex: um snapshot limpo do Chrome\n NEW_SNAPSHOT = \"app_logged_in_v1\"\n\n try:\n workforce.create_snapshot_from_task(\n base_snapshot_id=BASE_SNAPSHOT,\n new_snapshot_id=NEW_SNAPSHOT,\n setup_function=perform_login,\n metadata={\n \"description\": \"Sess\u00e3o autenticada no app.exemplo.com.\",\n \"user\": APP_USER\n }\n )\n print(f\"\\nSnapshot '{NEW_SNAPSHOT}' criado com sucesso!\")\n except Exception as e:\n print(f\"\\n[!!!] Falha ao criar o snapshot: {e}\")\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n### Fase 2: Executar Tarefas Usando o Snapshot\n\nCom o snapshot `app_logged_in_v1` pronto, voc\u00ea pode executar in\u00fameras tarefas que dependem de um usu\u00e1rio autenticado, de\nforma massivamente paralela, e **sem nunca mais precisar fazer login**.\n\n```python\n# scripts/run_report_tasks.py\nfrom browser_core import WorkforceManager, Worker, create_selector, default_settings\nfrom browser_core.types import SelectorType\n\n\n# --- L\u00f3gica da Tarefa ---\n# Esta fun\u00e7\u00e3o j\u00e1 parte do princ\u00edpio que o worker est\u00e1 logado.\ndef extract_report_data(worker: Worker, report_id: str):\n worker.logger.info(f\"Iniciando extra\u00e7\u00e3o para o relat\u00f3rio: {report_id}\")\n worker.navigate_to(f\"https://app.exemplo.com/reports/{report_id}\")\n\n REPORT_TABLE = create_selector(\"#report-data-table\", SelectorType.CSS)\n\n # A simples chamada a .text for\u00e7a o worker a aguardar o elemento aparecer\n table_data = worker.get(REPORT_TABLE).text\n\n # ... aqui voc\u00ea processaria os dados da tabela ...\n processed_data = {\"report_id\": report_id, \"content_length\": len(table_data)}\n worker.logger.info(f\"Extra\u00e7\u00e3o do relat\u00f3rio '{report_id}' conclu\u00edda.\")\n return processed_data\n\n\n# --- L\u00f3gica de Setup do Worker (opcional) ---\n# Fun\u00e7\u00e3o executada uma vez por worker antes de ele come\u00e7ar a processar os itens.\ndef worker_session_setup(worker: Worker) -> bool:\n worker.logger.info(f\"Worker {worker.logger.extra['task_id']} est\u00e1 pronto e online.\")\n # Poderia, por exemplo, navegar para uma p\u00e1gina inicial comum.\n # Retornar True indica que o setup foi bem-sucedido.\n return True\n\n\n# --- Execu\u00e7\u00e3o em Lote ---\ndef main():\n settings = default_settings()\n # Para depura\u00e7\u00e3o, \u00e9 \u00fatil desativar o modo headless\n settings[\"browser\"][\"headless\"] = False\n\n workforce = WorkforceManager(settings)\n\n # Lista de tarefas a serem executadas\n reports_to_process = [\"Q1-2024\", \"Q2-2024\", \"Q3-2024\", \"Q4-2024\"]\n\n try:\n results = workforce.run_tasks_in_squad(\n squad_size=2, # Executa 2 navegadores em paralelo\n base_snapshot_id=\"app_logged_in_v1\", # Usa o estado de login\n task_items=reports_to_process,\n worker_setup_function=worker_session_setup,\n item_processing_function=extract_report_data\n )\n print(\"\\n--- Processamento Conclu\u00eddo ---\")\n for res in results:\n print(res)\n\n except Exception as e:\n print(f\"\\n[!!!] Uma falha ocorreu durante a execu\u00e7\u00e3o do esquadr\u00e3o: {e}\")\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n### Uso da CLI\n\nUse o comando `browser-core` no seu terminal para gerir o ecossistema.\n\n* **Listar snapshots dispon\u00edveis:**\n ```bash\n browser-core snapshots list\n ```\n\n* **Inspecionar os detalhes de um snapshot:**\n ```bash\n browser-core snapshots inspect app_logged_in_v1\n ```\n\n* **Limpar todo o armazenamento (cuidado, opera\u00e7\u00e3o destrutiva!):**\n ```bash\n browser-core storage clean\n ```\n\n---\n\n## Desenvolvimento e Contribui\u00e7\u00e3o\n\nSe pretende contribuir para o `browser-core`, siga estes passos para configurar seu ambiente.\n\n1. **Clone o reposit\u00f3rio:**\n ```bash\n git clone https://github.com/gabrielbarbosel/browser-core.git\n cd browser-core\n ```\n\n2. **Crie e ative um ambiente virtual:**\n ```bash\n python -m venv .venv\n source .venv/bin/activate # No Linux/macOS\n # .venv\\Scripts\\activate # No Windows\n ```\n\n3. **Instale o projeto em modo \"edit\u00e1vel\":**\n ```bash\n pip install -e .\n \n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Um framework robusto e configur\u00e1vel para automa\u00e7\u00e3o de navegadores, com gest\u00e3o de perfis, sess\u00f5es e uma CLI.",
"version": "0.2.4",
"project_urls": {
"Bug Tracker": "https://github.com/gabrielbarbosel/browser-core/issues",
"Homepage": "https://github.com/gabrielbarbosel/browser-core",
"Repository": "https://github.com/gabrielbarbosel/browser-core"
},
"split_keywords": [
"automation",
" selenium",
" web",
" browser",
" framework"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "3f8642001f57d35e5dec21bded66abbc7dc81474a94aa9cb6df7f55921afb159",
"md5": "2f1ce69d1cb275fe96fdc0fe2c09220f",
"sha256": "b801b7f7fde99e9a44d4e7f3a322bf49c7319c67c839809878482477e8f88118"
},
"downloads": -1,
"filename": "browser_core-0.2.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2f1ce69d1cb275fe96fdc0fe2c09220f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 35233,
"upload_time": "2025-07-09T01:11:02",
"upload_time_iso_8601": "2025-07-09T01:11:02.957619Z",
"url": "https://files.pythonhosted.org/packages/3f/86/42001f57d35e5dec21bded66abbc7dc81474a94aa9cb6df7f55921afb159/browser_core-0.2.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "dc5108d0760fd54489af08f9e0a20d096f5089be99765318290b12e60a79e9b6",
"md5": "3341c9d04563a2fb42f85969400fc374",
"sha256": "616c158fa6c5688f9dfef6988b61f4df07e972c30ecb1952ff033eaae85ed77e"
},
"downloads": -1,
"filename": "browser_core-0.2.4.tar.gz",
"has_sig": false,
"md5_digest": "3341c9d04563a2fb42f85969400fc374",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 31494,
"upload_time": "2025-07-09T01:11:04",
"upload_time_iso_8601": "2025-07-09T01:11:04.575338Z",
"url": "https://files.pythonhosted.org/packages/dc/51/08d0760fd54489af08f9e0a20d096f5089be99765318290b12e60a79e9b6/browser_core-0.2.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-09 01:11:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "gabrielbarbosel",
"github_project": "browser-core",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "browser-core"
}