---
title: "Web Scraping com BeautifulSoup: Guia"
url: "https://python.dev.br/guias/web-scraping-beautifulsoup/"
markdown_url: "https://python.dev.br/guias/web-scraping-beautifulsoup.MD"
description: "Aprenda web scraping com Python e BeautifulSoup. Extraia dados de sites, parse HTML, trate erros e siga boas práticas de scraping"
date: "2025-12-06"
author: ""
---

# Web Scraping com BeautifulSoup: Guia

Aprenda web scraping com Python e BeautifulSoup. Extraia dados de sites, parse HTML, trate erros e siga boas práticas de scraping


## Introdução

Web scraping é a técnica de extrair dados de páginas web automaticamente. Com Python e a biblioteca BeautifulSoup, você pode coletar informações de sites que não oferecem APIs, como preços de produtos, notícias, dados de pesquisa e muito mais.

Neste guia, vamos aprender a usar BeautifulSoup para extrair dados de páginas HTML, tratar erros e seguir boas práticas de scraping responsável.

## Instalação

Instale BeautifulSoup e Requests:

```bash
pip install beautifulsoup4 requests
```

O `beautifulsoup4` faz o parsing do HTML e o `requests` faz as requisições HTTP para baixar as páginas.

## Primeiro scraping

Vamos extrair dados de uma página HTML simples:

```python
import requests
from bs4 import BeautifulSoup

# Baixar a pagina
url = "https://books.toscrape.com/"
resposta = requests.get(url)
resposta.raise_for_status()  # Levanta erro se a requisicao falhar

# Parsear o HTML
soup = BeautifulSoup(resposta.text, "html.parser")

# Extrair o titulo da pagina
titulo = soup.title.string
print(f"Titulo: {titulo}")
```

O site `books.toscrape.com` é um site de prática para web scraping, feito especificamente para aprendizado.

## Navegando o HTML

### Encontrando elementos

O BeautifulSoup oferece vários métodos para encontrar elementos:

```python
# Encontrar o primeiro elemento por tag
primeiro_h1 = soup.find("h1")

# Encontrar por classe CSS
produtos = soup.find_all("article", class_="product_pod")

# Encontrar por ID
elemento = soup.find(id="meu-id")

# Encontrar por atributo
links = soup.find_all("a", attrs={"data-tipo": "externo"})
```

### Usando seletores CSS

O método `select()` aceita seletores CSS, que são frequentemente mais práticos:

```python
# Seletor de classe
produtos = soup.select("article.product_pod")

# Seletor de descendente
titulos = soup.select("article.product_pod h3 a")

# Seletor de atributo
links_externos = soup.select("a[href^='http']")

# Primeiro resultado apenas
primeiro = soup.select_one("h1")
```

## Exemplo prático: extraindo livros

Vamos extrair informações de livros do site de prática:

```python
import requests
from bs4 import BeautifulSoup


def extrair_livros(url):
    resposta = requests.get(url)
    resposta.raise_for_status()
    soup = BeautifulSoup(resposta.text, "html.parser")

    livros = []
    for artigo in soup.select("article.product_pod"):
        titulo = artigo.select_one("h3 a")["title"]
        preco = artigo.select_one(".price_color").text
        disponivel = artigo.select_one(".availability").text.strip()
        estrelas = artigo.select_one("p.star-rating")["class"][1]

        livros.append({
            "titulo": titulo,
            "preco": preco,
            "disponivel": disponivel,
            "estrelas": estrelas,
        })

    return livros


livros = extrair_livros("https://books.toscrape.com/")
for livro in livros[:5]:
    print(f"{livro['titulo']} - {livro['preco']}")
```

## Navegando entre páginas

Muitos sites dividem conteúdo em múltiplas páginas. Para coletar tudo, siga os links de paginação:

```python
def extrair_todas_paginas(url_base):
    todos_livros = []
    pagina = 1

    while True:
        if pagina == 1:
            url = url_base
        else:
            url = f"{url_base}catalogue/page-{pagina}.html"

        resposta = requests.get(url)
        if resposta.status_code != 200:
            break

        soup = BeautifulSoup(resposta.text, "html.parser")
        livros = soup.select("article.product_pod")

        if not livros:
            break

        for artigo in livros:
            titulo = artigo.select_one("h3 a")["title"]
            todos_livros.append(titulo)

        # Verificar se existe proxima pagina
        proxima = soup.select_one("li.next a")
        if not proxima:
            break

        pagina += 1

    return todos_livros
```

## Extraindo texto e atributos

```python
# Texto de um elemento
paragrafo = soup.find("p")
texto = paragrafo.text          # Texto sem tags HTML
texto = paragrafo.get_text()    # Equivalente
texto = paragrafo.get_text(strip=True)  # Remove espacos extras

# Atributos de um elemento
link = soup.find("a")
href = link["href"]             # Atributo href
href = link.get("href", "")    # Com valor padrao se nao existir

# Todos os atributos
atributos = link.attrs  # Dicionario com todos os atributos
```

## Tratamento de erros

Scraping envolve muitas situações imprevisíveis. Trate erros adequadamente:

```python
import requests
from bs4 import BeautifulSoup
import time


def scraping_seguro(url, tentativas=3):
    headers = {
        "User-Agent": "Mozilla/5.0 (compatible; MeuBot/1.0)"
    }

    for tentativa in range(tentativas):
        try:
            resposta = requests.get(url, headers=headers, timeout=10)
            resposta.raise_for_status()
            return BeautifulSoup(resposta.text, "html.parser")
        except requests.exceptions.HTTPError as e:
            print(f"Erro HTTP: {e}")
            if resposta.status_code == 429:  # Too Many Requests
                print("Rate limit atingido, aguardando...")
                time.sleep(60)
            else:
                break
        except requests.exceptions.ConnectionError:
            print(f"Erro de conexao. Tentativa {tentativa + 1}/{tentativas}")
            time.sleep(5)
        except requests.exceptions.Timeout:
            print("Timeout. Tentando novamente...")
            time.sleep(5)

    return None
```

## Salvando dados extraídos

### Salvando em CSV

```python
import csv


def salvar_csv(livros, arquivo):
    with open(arquivo, "w", newline="", encoding="utf-8") as f:
        escritor = csv.DictWriter(f, fieldnames=livros[0].keys())
        escritor.writeheader()
        escritor.writerows(livros)

salvar_csv(livros, "livros.csv")
```

### Salvando em JSON

```python
import json


def salvar_json(dados, arquivo):
    with open(arquivo, "w", encoding="utf-8") as f:
        json.dump(dados, f, ensure_ascii=False, indent=2)

salvar_json(livros, "livros.json")
```

### Salvando com Pandas

```python
import pandas as pd

df = pd.DataFrame(livros)
df.to_csv("livros.csv", index=False)
df.to_excel("livros.xlsx", index=False)
```

## Lidando com HTML dinâmico

BeautifulSoup funciona apenas com HTML estático. Se o site carrega conteúdo via JavaScript, você precisará de ferramentas adicionais:

```bash
pip install requests-html
```

```python
from requests_html import HTMLSession

session = HTMLSession()
resposta = session.get("https://exemplo.com")
resposta.html.render()  # Renderiza JavaScript

soup = BeautifulSoup(resposta.html.html, "html.parser")
```

Para sites mais complexos, considere usar Selenium ou Playwright.

## Boas práticas e ética

Web scraping deve ser feito de forma responsável:

- **Respeite o robots.txt**: verifique `https://site.com/robots.txt` antes de fazer scraping
- **Limite a frequência**: adicione delays entre requisições com `time.sleep()`
- **Identifique-se**: use um User-Agent que identifique seu bot
- **Não sobrecarregue o servidor**: faça requisições em intervalos razoáveis
- **Verifique os termos de uso**: alguns sites proíbem scraping explicitamente
- **Prefira APIs**: se o site oferece uma API, use-a em vez de scraping
- **Cache**: salve páginas baixadas para evitar requisições repetidas durante o desenvolvimento

```python
import time

for url in urls:
    dados = scraping_seguro(url)
    processar(dados)
    time.sleep(2)  # Espere 2 segundos entre requisicoes
```

## Conclusão

Web scraping com BeautifulSoup e Python é uma habilidade valiosa para coletar dados que não estão disponíveis via APIs. A combinação de Requests para baixar páginas e BeautifulSoup para parsear HTML é simples e poderosa para a maioria dos casos. Lembre-se sempre de praticar scraping responsável, respeitando os limites dos servidores e os termos de uso dos sites que você acessa.

Para scrapers que precisam de alta performance e concorrência, linguagens como <a href="https://golang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', {source: 'python.dev.br', target: 'golang.com.br', content: 'web-scraping-beautifulsoup'})">Go</a> oferecem goroutines que processam milhares de páginas em paralelo com baixo consumo de memória.
