Lidando com paginação e conteúdo dinâmico
Acompanhamento de links para a próxima página e uso do Playwright em páginas renderizadas por JavaScript.
Lidando com paginação e conteúdo dinâmico é uma aula grátis de AI Agents no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Agents, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Agents inclui 4 aulas no total.
O problema da paginação
A maioria dos sites reais não disponibiliza todos os seus dados em uma única página. Os resultados são divididos em várias páginas para reduzir a carga. Um agente precisa detectar e seguir a paginação para coletar conjuntos de dados completos.
Há dois padrões comuns de paginação: links para a próxima página e padrões de URL com número de página.
Detectando links para a próxima página
Muitos sites têm um botão "Próximo" ou um link com uma seta. Encontre a tag âncora com rel='next' ou cujo texto seja semelhante a "Próximo", extraia seu href e siga-o em um laço até que não exista mais nenhum.
from bs4 import BeautifulSoup
import httpx
def scrape_all_pages(start_url: str) -> list:
results = []
url = start_url
while url:
response = httpx.get(url, timeout=10.0)
soup = BeautifulSoup(response.text, 'html.parser')
# Collect data from this page
for item in soup.select('.result-item'):
results.append(item.text.strip())
# Find the next page link
next_link = soup.find('a', rel='next') or soup.find('a', string='Next')
url = next_link.get('href') if next_link else None
return resultsPadrões de URL com número de página
Muitas APIs e sites usam padrões previsíveis de URL: /results?page=1, /results?page=2 etc. Um agente pode iterar diretamente por esses padrões, sem analisar o DOM em busca de um link para a próxima página.
import httpx
def scrape_paginated_api(base_url: str, max_pages: int = 10) -> list:
all_items = []
for page in range(1, max_pages + 1):
response = httpx.get(
base_url,
params={'page': page, 'per_page': 50},
timeout=10.0
)
response.raise_for_status()
data = response.json()
items = data.get('results', [])
if not items:
break # No more data
all_items.extend(items)
print(f'Page {page}: fetched {len(items)} items')
return all_itemsPaginação baseada em cursor
APIs modernas (GitHub, Slack, Twitter) usam paginação baseada em cursor. Cada resposta inclui um token de cursor para a página seguinte. Passe o cursor na próxima solicitação até que ele esteja ausente ou seja nulo.
import httpx
def fetch_with_cursor(url: str, headers: dict) -> list:
all_data = []
cursor = None
while True:
params = {'cursor': cursor} if cursor else {}
response = httpx.get(url, headers=headers, params=params, timeout=10.0)
response.raise_for_status()
data = response.json()
all_data.extend(data.get('items', []))
cursor = data.get('next_cursor') # None when done
if not cursor:
break
return all_dataConteúdo estático vs. dinâmico
Algumas páginas carregam conteúdo por meio de JavaScript depois que o HTML inicial é entregue. Um cliente HTTP comum recebe apenas a estrutura vazia — os dados reais são inseridos pelo JS no navegador.
Para essas páginas, ferramentas como Playwright executam um mecanismo de navegador real e aguardam a execução do JavaScript antes de extrair o conteúdo.
Instalando e importando Playwright
Instale o Playwright com pip install playwright e depois execute playwright install chromium para baixar o navegador. Use async_playwright() para fluxos assíncronos do agente.
# Installation (run in terminal):
# pip install playwright
# playwright install chromium
from playwright.async_api import async_playwright
import asyncio
async def fetch_dynamic(url: str) -> str:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
html = await page.content() # Full rendered HTML
await browser.close()
return html
# html = asyncio.run(fetch_dynamic('https://example.com'))Aguardando o carregamento do conteúdo dinâmico
Páginas com JavaScript frequentemente carregam dados de forma assíncrona. Instrua o Playwright a aguardar até que um elemento específico apareça antes de extrair o conteúdo, garantindo que os dados de que você precisa estejam realmente presentes no DOM.
from playwright.async_api import async_playwright
async def scrape_dynamic_table(url: str) -> list:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
# Wait for the table to appear in the DOM
await page.wait_for_selector('table.results', timeout=10000)
html = await page.content()
await browser.close()
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
return [td.text for td in soup.select('table.results td')]Clicando e interagindo com páginas
O Playwright pode simular interações do usuário: cliques, preenchimento de formulários, rolagem e entrada pelo teclado. Isso permite que um agente navegue por fluxos de autenticação, menus suspensos ou páginas com rolagem infinita.
from playwright.async_api import async_playwright
async def click_load_more(url: str) -> str:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
# Click the 'Load More' button
load_more = page.locator('button:text("Load More")')
if await load_more.count() > 0:
await load_more.click()
await page.wait_for_timeout(2000) # wait 2s for content
html = await page.content()
await browser.close()
return htmlLidando com rolagem infinita
Alguns sites carregam mais conteúdo conforme você rola para baixo. O Playwright pode simular a rolagem para acionar esses carregamentos. Role repetidamente e verifique se apareceu conteúdo novo a cada vez.
from playwright.async_api import async_playwright
async def scrape_infinite_scroll(url: str, scroll_count: int = 5) -> str:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
for _ in range(scroll_count):
await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
await page.wait_for_timeout(1500) # wait for new content
html = await page.content()
await browser.close()
return htmlCombinando Playwright com BeautifulSoup
Depois que o Playwright renderizar a página e retornar o HTML completo, passe-o para o BeautifulSoup para facilitar a extração. Isso combina os pontos fortes das duas bibliotecas.
from playwright.async_api import async_playwright
from bs4 import BeautifulSoup
async def extract_js_rendered_data(url: str) -> list:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
await page.wait_for_selector('.product-card')
html = await page.content()
await browser.close()
soup = BeautifulSoup(html, 'html.parser')
products = []
for card in soup.select('.product-card'):
products.append({
'name': card.select_one('.name').text.strip(),
'price': card.select_one('.price').text.strip()
})
return productsEscolhendo a ferramenta certa
Nem toda página precisa do Playwright. Use a abordagem mais simples que funcione:
- HTML estático: httpx + BeautifulSoup (rápido, sem sobrecarga de navegador)
- API JSON com paginação: httpx com parâmetros de página/cursor
- Conteúdo renderizado por JS: Playwright assíncrono (mais lento, mais poderoso)
Comece sempre pela abordagem estática e use o Playwright somente quando necessário.
Verificação de conhecimentos: paginação e conteúdo dinâmico
Teste sua compreensão da paginação e do tratamento de conteúdo dinâmico.
Recapitulação: paginação e conteúdo dinâmico
Agora seus agentes podem lidar com todo o espectro de conteúdo da web:
- Siga links para a próxima página ou itere pelos parâmetros de página da URL
- Use tokens de cursor para a paginação de APIs modernas
- Use
async_playwright()para páginas renderizadas por JavaScript - Aguarde elementos com
page.wait_for_selector() - Combine Playwright com BeautifulSoup para facilitar a extração
Comece sempre pela abordagem mais simples e recorra ao Playwright somente quando a abordagem estática não for suficiente.
Perguntas Frequentes
A aula “Lidando com paginação e conteúdo dinâmico” é grátis?
Sim — o texto completo de “Lidando com paginação e conteúdo dinâmico” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Agents, atualize para CoddyKit PRO. O curso de AI Agents inclui 4 aulas no total.
O que vou aprender em “Lidando com paginação e conteúdo dinâmico”?
Acompanhamento de links para a próxima página e uso do Playwright em páginas renderizadas por JavaScript. Você pratica AI Agents com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar AI Agents?
Nenhuma experiência prévia é necessária. AI Agents no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Lidando com paginação e conteúdo dinâmico”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de AI Agents?
Sim. Cada aula de AI Agents inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Clientes HTTP para agentes: httpx e requests
- Analisando HTML com BeautifulSoup
- Lidando com paginação e conteúdo dinâmico
- Práticas responsáveis de raspagem