Raspagem na Web extrai dados de sites de forma programática – útil para pesquisa, monitoramento de preços, agregação de dados e automação. Este guia cria scrapers em Python, desde páginas estáticas simples até sites JavaScript dinâmicos, ao mesmo tempo que aborda as práticas legais e éticas que mantêm você longe de problemas.
📋 Table of Contents
- Raspe primeiro com responsabilidade
- Configuração
- Raspando páginas estáticas com solicitações + BeautifulSoup
- Selecionando elementos com precisão
- Scraping de sites dinâmicos (JavaScript) com Playwright
- Limitação de Taxa e Polidez
- Manipulando Paginação
- Salvando dados extraídos
- Perguntas Frequentes
- Conclusão
Raspe primeiro com responsabilidade
Antes de escrever qualquer scraper, entenda as regras:
- Verifique robots.txt:
example.com/robots.txtinforma o que pode ser rastreado - Leia os Termos de Serviço: Alguns sites proíbem explicitamente a raspagem
- Respeite os limites de taxas: Não martele um servidor — adicione atrasos entre as solicitações
- Use APIs oficiais quando disponíveis: Sempre prefira uma API em vez de scraping
- Não raspe dados pessoais sem base jurídica (aplica-se o RGPD e leis semelhantes)
- Identifique-se: Defina um User-Agent adequado, não disfarce seu bot de forma maliciosa
Configuração
pip install requests beautifulsoup4 lxml
# For JavaScript-heavy sites:
pip install playwright
playwright install chromium
Raspando páginas estáticas com solicitações + BeautifulSoup
import requests
from bs4 import BeautifulSoup
import time
def scrape_articles(url):
headers = {
'User-Agent': 'Mozilla/5.0 (compatible; MyResearchBot/1.0)'
}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'lxml')
articles = []
for article in soup.select('article.post'):
title = article.select_one('h2.title')
link = article.select_one('a')
articles.append({
'title': title.get_text(strip=True) if title else None,
'url': link['href'] if link else None,
})
return articles
data = scrape_articles('https://example.com/blog')
for item in data:
print(item)
Selecionando elementos com precisão
soup = BeautifulSoup(html, 'lxml')
# By tag
soup.find('h1') # first h1
soup.find_all('p') # all paragraphs
# By CSS selector (most flexible)
soup.select('div.card > h2') # h2 inside div.card
soup.select_one('#main .price') # first .price inside #main
# Extract data
element.get_text(strip=True) # text content
element['href'] # attribute value
element.get('data-id', 'default') # attribute with fallback
# Navigate
element.parent # parent element
element.find_next_sibling('div') # next sibling
Scraping de sites dinâmicos (JavaScript) com Playwright
Muitos sites modernos renderizam conteúdo com JavaScript — as solicitações não o verão. O dramaturgo executa um navegador real:
from playwright.sync_api import sync_playwright
def scrape_dynamic(url):
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(user_agent='Mozilla/5.0 (MyBot/1.0)')
page.goto(url, wait_until='networkidle')
# Wait for content to load
page.wait_for_selector('.product-card')
# Extract data from the rendered page
products = page.eval_on_selector_all('.product-card', '''
cards => cards.map(card => ({
name: card.querySelector('.name')?.innerText,
price: card.querySelector('.price')?.innerText,
}))
''')
browser.close()
return products
results = scrape_dynamic('https://example.com/products')
Limitação de Taxa e Polidez
import time
import random
def polite_scrape(urls):
results = []
for url in urls:
try:
data = scrape_page(url)
results.append(data)
except requests.RequestException as e:
print(f"Failed {url}: {e}")
# Random delay between requests (1-3 seconds) - be gentle
time.sleep(random.uniform(1, 3))
return results
# Respect Retry-After on 429 responses
response = requests.get(url)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
Manipulando Paginação
def scrape_all_pages(base_url):
all_data = []
page = 1
while True:
url = f"{base_url}?page={page}"
response = requests.get(url, headers=HEADERS, timeout=10)
soup = BeautifulSoup(response.text, 'lxml')
items = soup.select('.item')
if not items:
break # no more items - stop
all_data.extend(extract_items(items))
# Check for a "next" link, or just increment
if not soup.select_one('a.next-page'):
break
page += 1
time.sleep(random.uniform(1, 2))
return all_data
Salvando dados extraídos
import csv
import json
# To CSV
with open('data.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['title', 'url', 'price'])
writer.writeheader()
writer.writerows(data)
# To JSON
with open('data.json', 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# To a database (SQLite example)
import sqlite3
conn = sqlite3.connect('scraped.db')
conn.executemany(
"INSERT INTO products (name, price) VALUES (?, ?)",
[(d['name'], d['price']) for d in data]
)
conn.commit()
Perguntas Frequentes
P: O web scraping é legal?
R: Depende. A extração de dados disponíveis publicamente costuma ser legal, mas violar os Termos de Serviço, extrair dados pessoais sem base ou ignorar os controles de acesso pode ser ilegal. Verifique robots.txt e ToS, prefira APIs oficiais e consulte aconselhamento jurídico para scraping comercial.
P: pedidos/BeautifulSoup ou Playwright?
R: Use requests + BeautifulSoup para páginas HTML estáticas (mais rápidas, mais leves). Use Playwright (ou Selenium) para sites renderizados em JavaScript onde o conteúdo é carregado dinamicamente. Verifique primeiro se os dados estão no HTML inicial – se estiverem, você não precisa de um navegador.
P: Como evito ser bloqueado?
R: Raspe educadamente – respeite os limites de taxa, adicione atrasos, defina um User-Agent adequado e não sobrecarregue os servidores. A melhor maneira de evitar bloqueios é não ser abusivo. A raspagem agressiva é bloqueada (e pode ser ilegal).
P: Devo usar uma API em vez de scraping?
R: Sempre, se existir. As APIs são mais confiáveis, legais, estruturadas e não quebram quando o HTML do site muda. A raspagem é o último recurso quando nenhuma API fornece os dados necessários.
P: Como lidar com sites que exigem login?
R: O Playwright pode automatizar o login (preencher formulários, enviar), mantendo uma sessão. Mas a raspagem de um login geralmente viola os Termos de Serviço – seja especialmente cuidadoso com a legalidade e copie apenas os dados aos quais você está autorizado a acessar.
Conclusão
Web scraping com Python é poderoso para coleta de dados, mas faça isso com responsabilidade. Usarrequests + BeautifulSoup para páginas estáticas e Playwright para sites renderizados em JavaScript, selecione elementos com seletores CSS, manipule a paginação e salve em CSV/JSON/banco de dados. Mais importante ainda:verifique o robots.txt e os Termos de Serviço, respeite os limites de taxas com atrasos, prefira APIs oficiais e não extraia dados pessoais sem base legal. A raspagem ética e educada mantém você longe de problemas legais e técnicos enquanto obtém os dados de que precisa. Quando existir uma API, sempre use-a – scraping é a alternativa, não a primeira escolha.
🔗 Share this article
✍️ Leave a Comment