Web scraping com Playwright em Python: guia completo
Scraping de sites com JavaScript usando Playwright: paginação, login e coleta de dados
BeautifulSoup e Requests funcionam bem para páginas HTML estáticas. O problema é que a maioria dos sites modernos renderiza conteúdo com JavaScript — e aí elas não chegam nem perto. Playwright controla um navegador de verdade, então o que você vê no Chrome é exatamente o que você consegue coletar.
Instalação
pip install playwright
playwright install chromium
Estrutura básica
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://exemplo.com")
print(page.title())
browser.close()
Use headless=False durante o desenvolvimento para ver o navegador abrindo na tela — facilita muito o debug.
Selecionando elementos
Playwright usa seletores CSS e texto para localizar elementos:
# Por seletor CSS
titulo = page.locator("h1").inner_text()
# Por texto visível
page.get_by_text("Ver mais").click()
# Todos os itens de uma lista
itens = page.locator(".produto-card").all()
for item in itens:
nome = item.locator(".nome").inner_text()
preco = item.locator(".preco").inner_text()
print(nome, preco)
Lidando com JavaScript e esperas
O maior erro de quem começa é não esperar o conteúdo carregar. Playwright tem esperas inteligentes:
# Espera o elemento aparecer antes de interagir
page.wait_for_selector(".resultados")
# Espera a rede ficar ociosa (útil após cliques que disparam requisições)
page.click("#carregar-mais")
page.wait_for_load_state("networkidle")
Exemplo real: coletando livros com paginação
import json
from playwright.sync_api import sync_playwright
def coletar_livros():
livros = []
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://books.toscrape.com")
while True:
cards = page.locator("article.product_pod").all()
for card in cards:
livros.append({
"titulo": card.locator("h3 a").get_attribute("title"),
"preco": card.locator(".price_color").inner_text(),
})
proximo = page.locator("li.next a")
if proximo.count() == 0:
break
proximo.click()
page.wait_for_load_state("networkidle")
browser.close()
return livros
dados = coletar_livros()
print(f"{len(dados)} livros coletados")
with open("livros.json", "w") as f:
json.dump(dados, f, ensure_ascii=False, indent=2)
Fazendo login antes de coletar
page.goto("https://site.com/login")
page.fill("#email", "seu@email.com")
page.fill("#senha", "suasenha")
page.click("button[type=submit]")
page.wait_for_url("**/dashboard")
# Agora você está autenticado — pode navegar para páginas protegidas
page.goto("https://site.com/dados-privados")
Salvando o estado de login (evitar logar toda vez)
# Salva cookies e storage após login
page.context.storage_state(path="estado.json")
# Na próxima execução, reutiliza:
context = browser.new_context(storage_state="estado.json")
Próximos passos
Com os dados coletados, o próximo passo é limpá-los e analisá-los — e é exatamente isso que o tutorial de Pandas cobre.