🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Como construir um web scraper com Python em 2026: guia ético completo

⏱️5 min read  ·  1,074 words

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.

Raspe primeiro com responsabilidade

Antes de escrever qualquer scraper, entenda as regras:

  • Verifique robots.txt: example.com/robots.txt informa 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.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা