Conceitos centrais
O Pydoll é construído sobre algumas decisões de design que moldam como você escreve cada script: sem webdriver, uma API assíncrona, interações humanizadas e um sistema de eventos. Esta página explica cada uma delas em um nível prático, para que os guias de tarefas a seguir façam sentido.
Sem webdriver
O Pydoll se conecta diretamente ao navegador pelo Chrome DevTools Protocol (CDP), o mesmo protocolo que move o Chrome DevTools quando você abre o inspetor. Não há um executável webdriver no meio, então não há nada para baixar e nenhum "o chromedriver só suporta o Chrome versão X" para depurar.
graph LR
subgraph P["Pydoll"]
direction LR
P1["Seu código"] --> P2["Pydoll"] --> P3["Navegador (CDP)"]
end
subgraph S["Selenium"]
direction LR
S1["Seu código"] --> S2["Cliente WebDriver"] --> S3["chromedriver"] --> S4["Navegador"]
end
Quando você inicia um navegador, o Pydoll lança o Chrome que você já tem instalado com uma porta de depuração remota e abre um WebSocket para o endpoint CDP dele:
import asyncio
from pydoll.browser.chromium import Chrome
async def main():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://quotes.toscrape.com')
asyncio.run(main())
Você não gerencia a porta, a conexão nem o processo do navegador; start() faz isso, e o bloco async with para o navegador quando você termina.
Os objetos browser e tab
Dois objetos cobrem a maior parte do que você faz. O browser (Chrome ou Edge) é o processo que você lança. A tab, retornada por browser.start(), é o que você controla: navegação, busca de elementos, screenshots, tudo na página acontece através dela.
async with Chrome() as browser:
tab = await browser.start() # a primeira aba
await tab.go_to('https://quotes.toscrape.com')
second = await browser.new_tab() # abra mais abas a partir do browser
await second.go_to('https://books.toscrape.com')
Veja Abas para gerenciar várias abas ao mesmo tempo, e Contextos de navegador para isolar sessões.
Tudo é assíncrono
Toda chamada do Pydoll é uma corrotina, então você usa await dentro de uma função async def e inicia o programa com asyncio.run(). Isso não é uma camada de compatibilidade acoplada depois; é assim que o Pydoll controla várias abas e navegadores ao mesmo tempo. Como navegação e esperas por elementos passam a maior parte do tempo ociosas, asyncio.gather as executa concorrentemente em vez de uma após a outra:
import asyncio
from pydoll.browser.chromium import Chrome
async def title_of(browser, url):
tab = await browser.new_tab(url)
title = await tab.title
await tab.close()
return title
async def main():
urls = [
'https://quotes.toscrape.com/page/1/',
'https://quotes.toscrape.com/page/2/',
'https://quotes.toscrape.com/page/3/',
]
async with Chrome() as browser:
await browser.start()
titles = await asyncio.gather(*(title_of(browser, url) for url in urls))
print(titles)
asyncio.run(main())
As três páginas carregam concorrentemente, então tudo leva mais ou menos o tempo da página mais lenta sozinha, não a soma das três.
Novo em Python assíncrono?
Se async, await e gather não são familiares, leia Python assíncrono na prática primeiro. Ele cobre apenas o suficiente de asyncio para você ficar confortável com o restante destes guias.
Interações humanizadas
Por padrão, um clique cai no centro de um elemento e a digitação segue um ritmo fixo. Passe humanize=True e o Pydoll move o cursor por um caminho curvo antes de clicar e digita com timing variável, incluindo o eventual erro de digitação corrigido:
search = await tab.find(id='search')
await search.type_text('web scraping', humanize=True)
await search.click(humanize=True)
A humanização é opcional por interação, então você a usa onde um site observa o comportamento e a dispensa onde velocidade pura importa. Veja Interações parecidas com humanas para o modelo de timing, e Teclado e Mouse para as APIs de entrada completas.
Orientado a eventos
Em vez de consultar a página em um loop, você pode assinar eventos do navegador e executar um callback quando eles disparam. É assim que você captura tráfego de rede, reage a navegações ou espera por uma requisição específica:
import asyncio
from functools import partial
from pydoll.browser.chromium import Chrome
from pydoll.protocol.network.events import NetworkEvent
async def on_request(tab, event):
url = event['params']['request']['url']
if '/api/' in url:
print(f'API call: {url}')
async def main():
async with Chrome() as browser:
tab = await browser.start()
await tab.enable_network_events()
await tab.on(NetworkEvent.REQUEST_WILL_BE_SENT, partial(on_request, tab))
await tab.go_to('https://quotes.toscrape.com')
await asyncio.sleep(2)
asyncio.run(main())
Ative apenas os domínios de evento que você usa, e desative-os quando terminar. Veja Eventos para o modelo completo e Monitoramento de rede para captura de tráfego.
Funciona em todos os navegadores Chromium
A mesma API controla qualquer navegador Chromium. O Chrome é o alvo principal; o Edge tem suporte completo; outras builds Chromium funcionam apontando binary_location para elas.
from pydoll.browser.chromium import Chrome, Edge
from pydoll.browser.options import ChromiumOptions
# Chrome
async with Chrome() as browser:
tab = await browser.start()
# Edge
async with Edge() as browser:
tab = await browser.start()
# Qualquer outra build Chromium (Brave, Vivaldi, Opera, ...)
options = ChromiumOptions()
options.binary_location = '/path/to/brave-browser'
async with Chrome(options=options) as browser:
tab = await browser.start()
Próximos passos
- Encontrar elementos: localize elementos com
find()equery(). - Extração estruturada: obtenha dados tipados de uma página com um modelo.
- Eventos: reaja a eventos de página e de rede conforme disparam.
- Chrome DevTools Protocol: o protocolo que o Pydoll fala com o navegador, em profundidade.