Web Scraping com Python e BeautifulSoup: guia prático
Extraia dados de qualquer site com requests e BeautifulSoup. Do básico ao tratamento de erros.
O que é web scraping?
Web scraping é a técnica de extrair dados de páginas da web automaticamente. Em vez de copiar e colar informações manualmente, você escreve um script que faz isso por você.
import requests
from bs4 import BeautifulSoup
resposta = requests.get("https://example.com")
soup = BeautifulSoup(resposta.text, "html.parser")
titulo = soup.find("h1").text
print(titulo)
Três linhas e você já tem o título de uma página.
Instalação
pip install requests beautifulsoup4
- requests: faz as requisições HTTP (baixa a página)
- beautifulsoup4: interpreta o HTML e permite navegar nele
Entendendo a estrutura HTML
Antes de extrair dados, você precisa entender o HTML da página. No navegador, clique com o botão direito → "Inspecionar elemento":
<div class="produto">
<h2 class="nome">Camiseta Python</h2>
<span class="preco">R$ 59,90</span>
<p class="descricao">100% algodao</p>
</div>
Cada tag (div, h2, span) é um elemento que o BeautifulSoup consegue encontrar.
Buscando elementos
Por tag
# Primeiro <h1> da pagina
titulo = soup.find("h1")
# Todos os <a> (links)
links = soup.find_all("a")
Por classe CSS
# Elemento com classe especifica
preco = soup.find("span", class_="preco")
# Todos com a classe
produtos = soup.find_all("div", class_="produto")
Por ID
menu = soup.find(id="menu-principal")
Por atributo
# Qualquer atributo
campo = soup.find("input", attrs={"name": "email"})
Extraindo texto e atributos
elemento = soup.find("a", class_="link")
# Texto dentro da tag
print(elemento.text) # "Clique aqui"
# Valor de um atributo
print(elemento["href"]) # "https://..."
print(elemento.get("href")) # mesmo resultado, mas nao da erro se nao existir
Exemplo prático: extraindo uma lista de dados
import requests
from bs4 import BeautifulSoup
url = "https://example.com/produtos"
resposta = requests.get(url)
soup = BeautifulSoup(resposta.text, "html.parser")
produtos = []
for item in soup.find_all("div", class_="produto"):
nome = item.find("h2").text.strip()
preco = item.find("span", class_="preco").text.strip()
produtos.append({"nome": nome, "preco": preco})
for p in produtos:
print(f"{p['nome']}: {p['preco']}")
Navegando pela árvore HTML
elemento = soup.find("div", class_="card")
# Filhos diretos
for filho in elemento.children:
print(filho)
# Elemento pai
pai = elemento.parent
# Proximo irmao
proximo = elemento.find_next_sibling()
Usando seletores CSS
O BeautifulSoup aceita seletores CSS com select:
# Todos os links dentro de uma nav
links = soup.select("nav a")
# Classe especifica
precos = soup.select(".preco")
# ID
header = soup.select_one("#header")
# Combinacoes
itens = soup.select("ul.menu > li > a")
select retorna uma lista, select_one retorna o primeiro resultado.
Tratando erros
Nem sempre a página retorna o que você espera:
import requests
from bs4 import BeautifulSoup
def scrape_pagina(url):
try:
resposta = requests.get(url, timeout=10)
resposta.raise_for_status()
except requests.RequestException as e:
print(f"Erro na requisicao: {e}")
return None
soup = BeautifulSoup(resposta.text, "html.parser")
titulo = soup.find("h1")
if titulo is None:
print("Titulo nao encontrado")
return None
return titulo.text.strip()
Headers e User-Agent
Alguns sites bloqueiam requisições sem um User-Agent válido:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
resposta = requests.get(url, headers=headers)
Salvando os dados
Em CSV
import csv
with open("produtos.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["nome", "preco"])
writer.writeheader()
writer.writerows(produtos)
Em JSON
import json
with open("produtos.json", "w", encoding="utf-8") as f:
json.dump(produtos, f, ensure_ascii=False, indent=2)
Boas práticas
- Respeite o
robots.txt— verifique se o site permite scraping - Adicione delays entre requisições — não sobrecarregue o servidor
- Use
timeout— evite que seu script trave esperando resposta - Trate erros — páginas mudam, elementos somem
- Verifique os termos de uso — nem todo site permite extração de dados
import time
for url in urls:
dados = scrape_pagina(url)
time.sleep(2) # espera 2 segundos entre requisicoes
Resumo
| Função | Para que serve |
|---|---|
requests.get(url) |
Baixa o HTML da página |
BeautifulSoup(html, "html.parser") |
Interpreta o HTML |
soup.find() |
Busca o primeiro elemento |
soup.find_all() |
Busca todos os elementos |
soup.select() |
Busca por seletor CSS |
elemento.text |
Extrai o texto |
elemento["atributo"] |
Extrai um atributo |
Web scraping é uma das habilidades mais práticas que você pode aprender. Com requests e BeautifulSoup, qualquer página vira uma fonte de dados.