14  Web Scraping com BeautifulSoup

De colecionador de figurinhas para coletor de dados: extraindo informações da web!

14.1 O que você vai aprender neste capítulo?

  1. O que é Web Scraping e quando usar essa técnica
  2. HTML básico: entendendo a estrutura de páginas web (tags, classes, IDs)
  3. BeautifulSoup: como usar a biblioteca para fazer parsing de HTML
  4. Seletores: como encontrar elementos específicos na página
  5. requests + BeautifulSoup: combinando requisições HTTP com parsing
  6. Exemplos práticos: extrair títulos, preços, links e dados estruturados
  7. Ética e legalidade: boas práticas e responsabilidade no scraping
  8. Projetos reais: criar sistemas de coleta de dados da web

🎓 Vindo do Capítulo 13? Perfeito! Agora que você sabe criar APIs, vamos extrair dados de páginas web!

🎯 Meta: Ao final deste capítulo, você vai conseguir extrair dados de páginas web, processar HTML e criar sistemas de coleta de informações da internet.

⚠️ Por que isso importa: Web scraping é uma ferramenta poderosa! Use com responsabilidade, respeitando os termos de uso dos sites e implementando delays entre requisições.

14.2 De Colecionador de Figurinhas para Coletor de Dados

14.2.1 Analogia Perfeita: Colecionador de Figurinhas

Imagine que você é um colecionador de figurinhas e quer completar seu álbum:

  1. Álbum (Site web): Onde estão todas as figurinhas organizadas
  2. Figurinhas (Dados): As informações que você quer coletar
  3. Colecionador (Seu código): Você que vai extrair as figurinhas
  4. Tesoura (BeautifulSoup): Ferramenta para “recortar” as figurinhas
  5. Cola (Salvar dados): Como você organiza as figurinhas coletadas

Em programação, funciona assim:

  1. Site web: Página com dados organizados em HTML
  2. Dados: Informações que você quer extrair (títulos, preços, links)
  3. Seu código Python: Programa que vai coletar os dados
  4. BeautifulSoup: Biblioteca que “recorta” os dados do HTML
  5. Arquivo/banco: Onde você salva os dados coletados

14.2.2 O que é Web Scraping?

Web Scraping é o processo de extrair dados automaticamente de páginas web.

É como ser um colecionador digital que:

  • 📖 páginas web automaticamente
  • ✂️ Recorta as informações que precisa
  • 📁 Organiza os dados coletados
  • 💾 Salva em arquivos ou bancos de dados

14.2.3 Quando usar Web Scraping?

  • 📊 Análise de preços: Comparar preços de produtos
  • 📰 Coleta de notícias: Extrair manchetes e artigos
  • 📈 Dados financeiros: Cotações de ações e moedas
  • 🏠 Imóveis: Preços e características de casas
  • 🎬 Filmes: Informações de filmes e séries
  • 📚 Livros: Dados de livros e autores

14.2.4 Exemplo prático

Sem scraping (problema):

  • Você precisa acessar 100 sites manualmente
  • Copiar e colar informações uma por uma
  • Organizar tudo em planilhas
  • Atualizar dados regularmente

Com scraping (solução):

  • Seu código acessa os sites automaticamente
  • Extrai todas as informações de uma vez
  • Organiza os dados automaticamente
  • Atualiza quando você quiser

💡 Exemplo: Sites como Google, Amazon e Netflix usam scraping para coletar dados de outros sites e oferecer serviços melhores!

14.3 HTML Básico - Entendendo a Estrutura das Páginas

14.3.1 O que é HTML?

HTML (HyperText Markup Language) é a linguagem que estrutura as páginas web. É como o esqueleto de uma página!

14.3.2 Tags HTML Essenciais

Tag Função Analogia
<div> Container genérico 📦 Caixa para organizar coisas
<p> Parágrafo 📄 Texto corrido
<h1>, <h2>, <h3> Títulos 📋 Títulos de seções
<a> Link 🔗 Ligação para outras páginas
<img> Imagem 🖼️ Foto ou figura
<table> Tabela 📊 Dados organizados em linhas/colunas
<ul>, <ol> Listas 📝 Lista de itens
<span> Texto pequeno 🏷️ Etiqueta ou marcação

14.3.3 Classes e IDs

<!-- Exemplo de HTML -->
<div class="produto">
    <h2 id="titulo-principal">Notebook Gamer</h2>
    <p class="preco">R$ 2.500,00</p>
    <a href="/comprar" class="botao-comprar">Comprar</a>
</div>

Explicação:

  • class="produto": Classe - pode ser usada várias vezes
  • id="titulo-principal": ID - deve ser único na página
  • href="/comprar": Atributo - propriedade do elemento

14.3.4 Estrutura de uma Página Web

<!DOCTYPE html>
<html>
<head>
    <title>Minha Loja</title>
</head>
<body>
    <header>
        <h1>Bem-vindo à Minha Loja</h1>
    </header>
    
    <main>
        <div class="produtos">
            <div class="produto">
                <h2>Notebook</h2>
                <p class="preco">R$ 2.500</p>
            </div>
            <div class="produto">
                <h2>Mouse</h2>
                <p class="preco">R$ 50</p>
            </div>
        </div>
    </main>
    
    <footer>
        <p>© 2024 Minha Loja</p>
    </footer>
</body>
</html>

14.3.5 Como BeautifulSoup “Lê” HTML

BeautifulSoup transforma HTML em uma árvore que você pode navegar:

# HTML de exemplo
html = """
<div class="produtos">
    <div class="produto">
        <h2>Notebook</h2>
        <p class="preco">R$ 2.500</p>
    </div>
    <div class="produto">
        <h2>Mouse</h2>
        <p class="preco">R$ 50</p>
    </div>
</div>
"""

# BeautifulSoup organiza assim:
# div.produtos
# div.produto
# h2: "Notebook"
# p.preco: "R$ 2.500"
# div.produto
# h2: "Mouse"
# p.preco: "R$ 50"

💡 Dica: Você não precisa ser expert em HTML! Apenas entender que páginas web são como documentos estruturados com tags que organizam o conteúdo.

14.4 BeautifulSoup - Sua Ferramenta de Scraping

14.4.1 Instalando BeautifulSoup

pip install beautifulsoup4 requests

14.4.2 Primeiro Exemplo: Extraindo Títulos

from bs4 import BeautifulSoup
import requests

# HTML de exemplo (simulando uma página web)
html_exemplo = """
<html>
<head>
    <title>Minha Loja Online</title>
</head>
<body>
    <h1>Produtos em Promoção</h1>
    <div class="produtos">
        <div class="produto">
            <h2>Notebook Gamer</h2>
            <p class="preco">R$ 2.500,00</p>
        </div>
        <div class="produto">
            <h2>Mouse Óptico</h2>
            <p class="preco">R$ 50,00</p>
        </div>
        <div class="produto">
            <h2>Teclado Mecânico</h2>
            <p class="preco">R$ 120,00</p>
        </div>
    </div>
</body>
</html>
"""

# Criar objeto BeautifulSoup
soup = BeautifulSoup(html_exemplo, 'html.parser')

# Extrair título da página
titulo = soup.find('title').text
print(f"Título da página: {titulo}")

# Extrair todos os títulos h2 (nomes dos produtos)
produtos = soup.find_all('h2')
print("\nProdutos encontrados:")
for i, produto in enumerate(produtos, 1):
    print(f"{i}. {produto.text}")

Saída esperada:

Título da página: Minha Loja Online

Produtos encontrados:

1. Notebook Gamer
2. Mouse Óptico
3. Teclado Mecânico

14.4.3 Seletores Básicos

# Extrair por tag
titulos = soup.find_all('h2')

# Extrair por classe
precos = soup.find_all('p', class_='preco')

# Extrair por ID
titulo_principal = soup.find('h1')

# Extrair primeiro elemento
primeiro_produto = soup.find('div', class_='produto')

# Extrair texto de um elemento
texto_preco = soup.find('p', class_='preco').text

14.4.4 Exemplo Prático: Extraindo Preços

# Extrair todos os preços
precos = soup.find_all('p', class_='preco')

print("Preços encontrados:")
for preco in precos:
    print(f"- {preco.text}")

# Extrair produtos completos (nome + preço)
produtos = soup.find_all('div', class_='produto')

print("\nProdutos completos:")
for produto in produtos:
    nome = produto.find('h2').text
    preco = produto.find('p', class_='preco').text
    print(f"📦 {nome} - {preco}")

Saída esperada:

Preços encontrados:

- R$ 2.500,00
- R$ 50,00
- R$ 120,00

Produtos completos:
📦 Notebook Gamer - R$ 2.500,00
📦 Mouse Óptico - R$ 50,00
📦 Teclado Mecânico - R$ 120,00

14.5 Scraping de Sites Reais - requests + BeautifulSoup

14.5.1 Combinando requests e BeautifulSoup

import requests
from bs4 import BeautifulSoup
import time

def extrair_titulos_noticias(url):
    """Extrai títulos de notícias de um site"""
    try:
# Fazer requisição HTTP
        response = requests.get(url)
        response.raise_for_status()  # Verificar se deu erro
        
# Criar objeto BeautifulSoup
        soup = BeautifulSoup(response.content, 'html.parser')
        
# Extrair títulos (ajuste os seletores conforme o site)
        titulos = soup.find_all('h2')  # ou 'h3', 'h1', etc.
        
        print(f"📰 Encontrados {len(titulos)} títulos:")
        for i, titulo in enumerate(titulos[:5], 1):  # Mostrar apenas os 5 primeiros
            print(f"{i}. {titulo.get_text().strip()}")
        
        return titulos
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar o site: {e}")
        return None

# Exemplo de uso (substitua pela URL real)
# titulos = extrair_titulos_noticias('https://exemplo.com/noticias')

14.5.2 Scraping Responsável - Boas Práticas

import requests
from bs4 import BeautifulSoup
import time
import random

def scraping_responsavel(url):
    """Faz scraping respeitando o site"""
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    
    try:
# Delay aleatório entre requisições (1-3 segundos)
        time.sleep(random.uniform(1, 3))
        
# Fazer requisição com headers
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        
# Parse do HTML
        soup = BeautifulSoup(response.content, 'html.parser')
        
        return soup
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro: {e}")
        return None

# Exemplo de uso
# soup = scraping_responsavel('https://exemplo.com')

14.5.3 Exemplo Prático: Extrair Dados de Produtos

def extrair_produtos_loja(url):
    """Extrai informações de produtos de uma loja online"""
    soup = scraping_responsavel(url)
    
    if not soup:
        return None
    
    produtos = []
    
# Encontrar todos os produtos (ajuste os seletores)
    items = soup.find_all('div', class_='produto')  # ou outro seletor
    
    for item in items:
        try:
            nome = item.find('h3').text.strip()
            preco = item.find('span', class_='preco').text.strip()
            link = item.find('a').get('href')
            
            produtos.append({
                'nome': nome,
                'preco': preco,
                'link': link
            })
        except AttributeError:
            continue  # Pular se não encontrar algum elemento
    
    return produtos

# Exemplo de uso
# produtos = extrair_produtos_loja('https://loja-exemplo.com')
# for produto in produtos:
# print(f" {produto['nome']} - {produto['preco']}")

14.5.4 Salvando Dados Coletados

import json
import csv

def salvar_dados_json(dados, arquivo):
    """Salva dados em arquivo JSON"""
    with open(arquivo, 'w', encoding='utf-8') as f:
        json.dump(dados, f, ensure_ascii=False, indent=2)
    print(f"✅ Dados salvos em {arquivo}")

def salvar_dados_csv(dados, arquivo):
    """Salva dados em arquivo CSV"""
    if not dados:
        return
    
    with open(arquivo, 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=dados[0].keys())
        writer.writeheader()
        writer.writerows(dados)
    print(f"✅ Dados salvos em {arquivo}")

# Exemplo de uso
# produtos = extrair_produtos_loja('https://exemplo.com')
# salvar_dados_json(produtos, 'produtos.json')
# salvar_dados_csv(produtos, 'produtos.csv')

💡 Dica: Sempre teste seus seletores primeiro! Use o navegador (F12) para inspecionar o HTML e encontrar os seletores corretos.

14.6 Exercícios Práticos (respostas no final da página)

🚀 Hora de praticar! Aqui estão 25 exercícios organizados por dificuldade. Cada exercício tem solução completa com explicação linha por linha!

14.6.1 MUITO FÁCIL (Nível 1)

1. Extrator de Títulos H1 Crie uma função que extrai todos os títulos <h1> de uma página HTML.

  • Exemplo: Input → HTML com 3 títulos H1 | Output → Lista com os 3 títulos

2. Extrator de Links Extraia todos os links (<a>) de uma página e mostre apenas os URLs.

  • Exemplo: Input → HTML com 5 links | Output → Lista com 5 URLs

3. Contador de Imagens Crie uma função que conta quantas imagens (<img>) existem em uma página.

  • Exemplo: Input → HTML com 10 imagens | Output → 10

4. Extrator de Parágrafos Extraia o texto de todos os parágrafos (<p>) de uma página.

  • Exemplo: Input → HTML com 3 parágrafos | Output → Lista com os 3 textos

5. Extrator por Classe Crie uma função que encontra elementos por classe CSS específica.

  • Exemplo: Input → HTML com elementos classe “preco” | Output → Lista com elementos da classe

14.6.2 FÁCIL (Nível 2)

6. Scraper de Produtos Crie um scraper que extrai títulos e preços de produtos de uma loja online.

  • Exemplo: Input → HTML de loja | Output → [{"nome": "Notebook", "preco": "R$ 2500"}]

7. Extrator de Contato Extraia informações de contato (email, telefone) de uma página de empresa.

  • Exemplo: Input → HTML com contatos | Output → {"email": "contato@empresa.com", "telefone": "11999999999"}

8. Coletor de Imagens Crie uma função que coleta todas as imagens e seus atributos alt.

  • Exemplo: Input → HTML com imagens | Output → [{"src": "img1.jpg", "alt": "Produto 1"}]

9. Extrator de Tabelas Extraia dados de uma tabela HTML e salve em formato CSV.

  • Exemplo: Input → Tabela HTML | Output → Arquivo CSV com dados

10. Scraper de Notícias Crie um scraper que coleta manchetes de notícias de um site.

  • Exemplo: Input → Site de notícias | Output → ["Manchete 1", "Manchete 2", "Manchete 3"]

14.6.3 MÉDIO (Nível 3)

11. Monitor de Preços Crie um sistema que monitora preços de produtos em múltiplos sites.

  • Exemplo: Input → URLs de 3 lojas | Output → Comparação de preços

12. Extrator de Perfis Extraia informações de perfis de usuários de uma rede social.

  • Exemplo: Input → Perfil de usuário | Output → {"nome": "João", "seguidores": 1000}

13. Scraper de Imóveis Crie um scraper que coleta dados de imóveis (preço, localização, características).

  • Exemplo: Input → Site de imóveis | Output → [{"preco": "R$ 500000", "localizacao": "São Paulo"}]

14. Extrator de Filmes Extraia dados de filmes/séries de um site de streaming.

  • Exemplo: Input → Site de streaming | Output → [{"titulo": "Filme A", "genero": "Ação"}]

15. Scraper de Vagas Crie um sistema que coleta informações de vagas de emprego.

  • Exemplo: Input → Site de vagas | Output → [{"cargo": "Desenvolvedor", "salario": "R$ 8000"}]

14.6.4 DIFÍCIL (Nível 4)

16. Scraper com Paginação Crie um scraper que navega por múltiplas páginas (paginação).

  • Exemplo: Input → Site com 5 páginas | Output → Dados de todas as 5 páginas

17. Extrator de Gráficos Extraia dados de gráficos e visualizações de dados de sites.

  • Exemplo: Input → Site com gráficos | Output → Dados numéricos dos gráficos

18. Monitor de Mudanças Crie um sistema que monitora mudanças em páginas web ao longo do tempo.

  • Exemplo: Input → URL para monitorar | Output → Relatório de mudanças

19. Extrator de APIs JavaScript Extraia dados de APIs que são carregadas via JavaScript.

  • Exemplo: Input → Site com dados via JS | Output → Dados extraídos

20. Scraper Anti-Bloqueio Crie um scraper que contorna proteções básicas contra scraping.

  • Exemplo: Input → Site com proteção | Output → Dados extraídos com sucesso

14.6.5 MUITO DIFÍCIL (Nível 5)

21. Sistema de Monitoramento Crie um sistema completo de monitoramento de preços com alertas.

  • Exemplo: Input → Produtos para monitorar | Output → Sistema com alertas automáticos

22. Scraper com Autenticação Extraia dados de sites com autenticação e sessões.

  • Exemplo: Input → Site que requer login | Output → Dados extraídos após autenticação

23. Scraper Distribuído Crie um scraper distribuído que roda em múltiplas máquinas.

  • Exemplo: Input → Lista de URLs | Output → Scraping distribuído em várias máquinas

24. Scraper Anti-CAPTCHA Extraia dados de sites com proteções avançadas (CAPTCHA, rate limiting).

  • Exemplo: Input → Site com CAPTCHA | Output → Dados extraídos contornando proteções

25. Scraper Adaptativo Crie um sistema de scraping que se adapta automaticamente a mudanças no HTML.

  • Exemplo: Input → Site que muda HTML | Output → Scraper que se adapta automaticamente

14.7 Respostas e Explicações

14.7.1 MUITO FÁCIL (Nível 1)

1. Extrator de Títulos H1

from bs4 import BeautifulSoup

def extrair_titulos_h1(html):
    """Extrai todos os títulos H1 de uma página HTML"""
    soup = BeautifulSoup(html, 'html.parser')
    titulos = soup.find_all('h1')
    return [titulo.get_text().strip() for titulo in titulos]

# Exemplo de uso
html_exemplo = """
<html>
<head><title>Minha Página</title></head>
<body>
    <h1>Título Principal</h1>
    <h1>Outro Título</h1>
    <p>Parágrafo normal</p>
    <h1>Terceiro Título</h1>
</body>
</html>
"""

titulos = extrair_titulos_h1(html_exemplo)
print("Títulos encontrados:")
for i, titulo in enumerate(titulos, 1):
    print(f"{i}. {titulo}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa a biblioteca BeautifulSoup para parsing de HTML
  • Linha 3: def extrair_titulos_h1(html): - Define função que recebe HTML como parâmetro
  • Linha 4: """Extrai todos os títulos H1 de uma página HTML""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup para parsear HTML
  • Linha 6: titulos = soup.find_all('h1') - Encontra todos os elementos H1 na página
  • Linha 7: return [titulo.get_text().strip() for titulo in titulos] - Retorna lista com textos dos títulos
  • Linha 9: # Exemplo de uso - Comentário explicativo
  • Linhas 10-20: Define HTML de exemplo para teste
  • Linha 22: titulos = extrair_titulos_h1(html_exemplo) - Chama função com HTML de exemplo
  • Linha 23: print("Títulos encontrados:") - Imprime cabeçalho
  • Linha 24: for i, titulo in enumerate(titulos, 1): - Percorre títulos com numeração
  • Linha 25: print(f"{i}. {titulo}") - Imprime cada título numerado

2. Extrator de Links

from bs4 import BeautifulSoup

def extrair_links(html):
    """Extrai todos os links de uma página HTML"""
    soup = BeautifulSoup(html, 'html.parser')
    links = soup.find_all('a')
    return [link.get('href') for link in links if link.get('href')]

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <a href="https://www.google.com">Google</a>
    <a href="https://www.github.com">GitHub</a>
    <a href="/pagina-interna">Página Interna</a>
    <a href="#topo">Topo</a>
</body>
</html>
"""

links = extrair_links(html_exemplo)
print("Links encontrados:")
for i, link in enumerate(links, 1):
    print(f"{i}. {link}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: def extrair_links(html): - Define função para extrair links
  • Linha 4: """Extrai todos os links de uma página HTML""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 6: links = soup.find_all('a') - Encontra todos os elementos de link
  • Linha 7: return [link.get('href') for link in links if link.get('href')] - Retorna URLs dos links
  • Linha 9: # Exemplo de uso - Comentário explicativo
  • Linhas 10-18: Define HTML de exemplo com links
  • Linha 20: links = extrair_links(html_exemplo) - Chama função com HTML de exemplo
  • Linha 21: print("Links encontrados:") - Imprime cabeçalho
  • Linha 22: for i, link in enumerate(links, 1): - Percorre links com numeração
  • Linha 23: print(f"{i}. {link}") - Imprime cada link numerado

3. Contador de Imagens

from bs4 import BeautifulSoup

def contar_imagens(html):
    """Conta quantas imagens existem em uma página HTML"""
    soup = BeautifulSoup(html, 'html.parser')
    imagens = soup.find_all('img')
    return len(imagens)

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <img src="imagem1.jpg" alt="Primeira imagem">
    <img src="imagem2.png" alt="Segunda imagem">
    <img src="imagem3.gif" alt="Terceira imagem">
    <p>Texto com <img src="imagem4.jpg" alt="Quarta imagem"> inline</p>
</body>
</html>
"""

quantidade = contar_imagens(html_exemplo)
print(f"Total de imagens encontradas: {quantidade}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: def contar_imagens(html): - Define função para contar imagens
  • Linha 4: """Conta quantas imagens existem em uma página HTML""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 6: imagens = soup.find_all('img') - Encontra todos os elementos de imagem
  • Linha 7: return len(imagens) - Retorna quantidade de imagens encontradas
  • Linha 9: # Exemplo de uso - Comentário explicativo
  • Linhas 10-18: Define HTML de exemplo com imagens
  • Linha 20: quantidade = contar_imagens(html_exemplo) - Chama função com HTML de exemplo
  • Linha 21: print(f"Total de imagens encontradas: {quantidade}") - Imprime resultado

4. Extrator de Parágrafos

from bs4 import BeautifulSoup

def extrair_paragrafos(html):
    """Extrai o texto de todos os parágrafos de uma página HTML"""
    soup = BeautifulSoup(html, 'html.parser')
    paragrafos = soup.find_all('p')
    return [paragrafo.get_text().strip() for paragrafo in paragrafos]

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <h1>Título da Página</h1>
    <p>Este é o primeiro parágrafo da página.</p>
    <p>Este é o segundo parágrafo com mais informações.</p>
    <div>
        <p>Parágrafo dentro de uma div.</p>
    </div>
    <p>Último parágrafo da página.</p>
</body>
</html>
"""

paragrafos = extrair_paragrafos(html_exemplo)
print("Parágrafos encontrados:")
for i, paragrafo in enumerate(paragrafos, 1):
    print(f"{i}. {paragrafo}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: def extrair_paragrafos(html): - Define função para extrair parágrafos
  • Linha 4: """Extrai o texto de todos os parágrafos de uma página HTML""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 6: paragrafos = soup.find_all('p') - Encontra todos os elementos de parágrafo
  • Linha 7: return [paragrafo.get_text().strip() for paragrafo in paragrafos] - Retorna textos dos parágrafos
  • Linha 9: # Exemplo de uso - Comentário explicativo
  • Linhas 10-20: Define HTML de exemplo com parágrafos
  • Linha 22: paragrafos = extrair_paragrafos(html_exemplo) - Chama função com HTML de exemplo
  • Linha 23: print("Parágrafos encontrados:") - Imprime cabeçalho
  • Linha 24: for i, paragrafo in enumerate(paragrafos, 1): - Percorre parágrafos com numeração
  • Linha 25: print(f"{i}. {paragrafo}") - Imprime cada parágrafo numerado

5. Extrator por Classe

from bs4 import BeautifulSoup

def extrair_por_classe(html, classe):
    """Encontra elementos por classe CSS específica"""
    soup = BeautifulSoup(html, 'html.parser')
    elementos = soup.find_all(class_=classe)
    return [elemento.get_text().strip() for elemento in elementos]

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <div class="produto">
        <h2>Notebook</h2>
        <p class="preco">R$ 2.500,00</p>
    </div>
    <div class="produto">
        <h2>Mouse</h2>
        <p class="preco">R$ 50,00</p>
    </div>
    <p class="preco">Preço especial: R$ 100,00</p>
</body>
</html>
"""

precos = extrair_por_classe(html_exemplo, 'preco')
print("Preços encontrados:")
for i, preco in enumerate(precos, 1):
    print(f"{i}. {preco}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: def extrair_por_classe(html, classe): - Define função que recebe HTML e nome da classe
  • Linha 4: """Encontra elementos por classe CSS específica""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 6: elementos = soup.find_all(class_=classe) - Encontra elementos com classe específica
  • Linha 7: return [elemento.get_text().strip() for elemento in elementos] - Retorna textos dos elementos
  • Linha 9: # Exemplo de uso - Comentário explicativo
  • Linhas 10-22: Define HTML de exemplo com elementos de classe ‘preco’
  • Linha 24: precos = extrair_por_classe(html_exemplo, 'preco') - Chama função para classe ‘preco’
  • Linha 25: print("Preços encontrados:") - Imprime cabeçalho
  • Linha 26: for i, preco in enumerate(precos, 1): - Percorre preços com numeração
  • Linha 27: print(f"{i}. {preco}") - Imprime cada preço numerado

14.7.2 FÁCIL (Nível 2)

6. Scraper de Produtos

from bs4 import BeautifulSoup

def extrair_produtos(html):
    """Extrai títulos e preços de produtos de uma loja online"""
    soup = BeautifulSoup(html, 'html.parser')
    produtos = []
    
    # Encontrar todos os produtos
    itens = soup.find_all('div', class_='produto')
    
    for item in itens:
        try:
            nome = item.find('h3').get_text().strip()
            preco = item.find('span', class_='preco').get_text().strip()
            produtos.append({'nome': nome, 'preco': preco})
        except AttributeError:
            continue
    
    return produtos

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <div class="produto">
        <h3>Notebook Gamer</h3>
        <span class="preco">R$ 2.500,00</span>
    </div>
    <div class="produto">
        <h3>Mouse Óptico</h3>
        <span class="preco">R$ 50,00</span>
    </div>
    <div class="produto">
        <h3>Teclado Mecânico</h3>
        <span class="preco">R$ 120,00</span>
    </div>
</body>
</html>
"""

produtos = extrair_produtos(html_exemplo)
print("Produtos encontrados:")
for produto in produtos:
    print(f"📦 {produto['nome']} - {produto['preco']}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: def extrair_produtos(html): - Define função para extrair produtos
  • Linha 4: """Extrai títulos e preços de produtos de uma loja online""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 6: produtos = [] - Inicializa lista para armazenar produtos
  • Linha 8: # Encontrar todos os produtos - Comentário explicativo
  • Linha 9: itens = soup.find_all('div', class_='produto') - Encontra todos os elementos de produto
  • Linha 11: for item in itens: - Percorre cada produto encontrado
  • Linha 12: try: - Inicia bloco try para tratamento de erros
  • Linha 13: nome = item.find('h3').get_text().strip() - Extrai nome do produto
  • Linha 14: preco = item.find('span', class_='preco').get_text().strip() - Extrai preço do produto
  • Linha 15: produtos.append({'nome': nome, 'preco': preco}) - Adiciona produto à lista
  • Linha 16: except AttributeError: - Captura erro se elemento não for encontrado
  • Linha 17: continue - Pula para próximo produto se houver erro

7. Extrator de Contato

from bs4 import BeautifulSoup
import re

def extrair_contatos(html):
    """Extrai informações de contato (email, telefone) de uma página de empresa"""
    soup = BeautifulSoup(html, 'html.parser')
    
    # Extrair emails
    emails = []
    email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
    texto = soup.get_text()
    emails = re.findall(email_pattern, texto)
    
    # Extrair telefones
    telefones = []
    telefone_pattern = r'\(?\d{2}\)?[-.\s]?\d{4,5}[-.\s]?\d{4}'
    telefones = re.findall(telefone_pattern, texto)
    
    return {
        'emails': list(set(emails)),  # Remove duplicatas
        'telefones': list(set(telefones))  # Remove duplicatas
    }

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <h1>Contato da Empresa</h1>
    <p>Email: contato@empresa.com</p>
    <p>Telefone: (11) 99999-9999</p>
    <p>WhatsApp: 11 88888-8888</p>
    <p>Email comercial: vendas@empresa.com</p>
</body>
</html>
"""

contatos = extrair_contatos(html_exemplo)
print("Contatos encontrados:")
print(f"Emails: {contatos['emails']}")
print(f"Telefones: {contatos['telefones']}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import re - Importa módulo de expressões regulares
  • Linha 4: def extrair_contatos(html): - Define função para extrair contatos
  • Linha 5: """Extrai informações de contato (email, telefone) de uma página de empresa""" - Docstring explicando função
  • Linha 6: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 8: # Extrair emails - Comentário explicativo
  • Linha 9: emails = [] - Inicializa lista para emails
  • Linha 10: email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' - Padrão regex para emails
  • Linha 11: texto = soup.get_text() - Obtém todo o texto da página
  • Linha 12: emails = re.findall(email_pattern, texto) - Encontra todos os emails no texto
  • Linha 14: # Extrair telefones - Comentário explicativo
  • Linha 15: telefones = [] - Inicializa lista para telefones
  • Linha 16: telefone_pattern = r'\(?\d{2}\)?[-.\s]?\d{4,5}[-.\s]?\d{4}' - Padrão regex para telefones
  • Linha 17: telefones = re.findall(telefone_pattern, texto) - Encontra todos os telefones no texto

8. Coletor de Imagens

from bs4 import BeautifulSoup

def coletar_imagens(html):
    """Coleta todas as imagens e seus atributos alt"""
    soup = BeautifulSoup(html, 'html.parser')
    imagens = soup.find_all('img')
    
    resultado = []
    for img in imagens:
        resultado.append({
            'src': img.get('src', ''),
            'alt': img.get('alt', ''),
            'title': img.get('title', '')
        })
    
    return resultado

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <img src="logo.png" alt="Logo da empresa" title="Logo">
    <img src="produto1.jpg" alt="Notebook Gamer">
    <img src="produto2.jpg" alt="Mouse Óptico" title="Mouse">
    <img src="banner.jpg" alt="">
</body>
</html>
"""

imagens = coletar_imagens(html_exemplo)
print("Imagens encontradas:")
for i, img in enumerate(imagens, 1):
    print(f"{i}. SRC: {img['src']}")
    print(f"   ALT: {img['alt']}")
    print(f"   TITLE: {img['title']}")
    print()

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: def coletar_imagens(html): - Define função para coletar imagens
  • Linha 4: """Coleta todas as imagens e seus atributos alt""" - Docstring explicando função
  • Linha 5: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 6: imagens = soup.find_all('img') - Encontra todos os elementos de imagem
  • Linha 8: resultado = [] - Inicializa lista para armazenar dados das imagens
  • Linha 9: for img in imagens: - Percorre cada imagem encontrada
  • Linha 10: resultado.append({ - Adiciona dicionário com dados da imagem
  • Linha 11: 'src': img.get('src', ''), - Extrai atributo src (URL da imagem)
  • Linha 12: 'alt': img.get('alt', ''), - Extrai atributo alt (texto alternativo)
  • Linha 13: 'title': img.get('title', '') - Extrai atributo title (título da imagem)
  • Linha 14: }) - Fecha dicionário
  • Linha 16: return resultado - Retorna lista com dados das imagens

9. Extrator de Tabelas

from bs4 import BeautifulSoup
import csv

def extrair_tabela_csv(html, arquivo_csv):
    """Extrai dados de uma tabela HTML e salva em formato CSV"""
    soup = BeautifulSoup(html, 'html.parser')
    tabela = soup.find('table')
    
    if not tabela:
        return False
    
    # Encontrar cabeçalhos
    cabecalhos = []
    th_elements = tabela.find('tr').find_all('th')
    for th in th_elements:
        cabecalhos.append(th.get_text().strip())
    
    # Encontrar dados
    dados = []
    rows = tabela.find_all('tr')[1:]  # Pular primeira linha (cabeçalho)
    
    for row in rows:
        cells = row.find_all('td')
        if cells:  # Se a linha tem células
            linha = []
            for cell in cells:
                linha.append(cell.get_text().strip())
            dados.append(linha)
    
    # Salvar em CSV
    with open(arquivo_csv, 'w', newline='', encoding='utf-8') as arquivo:
        writer = csv.writer(arquivo)
        writer.writerow(cabecalhos)
        writer.writerows(dados)
    
    return True

# Exemplo de uso
html_exemplo = """
<html>
<body>
    <table>
        <tr>
            <th>Nome</th>
            <th>Idade</th>
            <th>Cidade</th>
        </tr>
        <tr>
            <td>João Silva</td>
            <td>25</td>
            <td>São Paulo</td>
        </tr>
        <tr>
            <td>Maria Santos</td>
            <td>30</td>
            <td>Rio de Janeiro</td>
        </tr>
    </table>
</body>
</html>
"""

sucesso = extrair_tabela_csv(html_exemplo, 'dados.csv')
if sucesso:
    print("✅ Tabela extraída e salva em dados.csv")
else:
    print("❌ Erro ao extrair tabela")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import csv - Importa módulo CSV para trabalhar com arquivos CSV
  • Linha 4: def extrair_tabela_csv(html, arquivo_csv): - Define função que recebe HTML e nome do arquivo
  • Linha 5: """Extrai dados de uma tabela HTML e salva em formato CSV""" - Docstring explicando função
  • Linha 6: soup = BeautifulSoup(html, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 7: tabela = soup.find('table') - Encontra elemento de tabela
  • Linha 9: if not tabela: - Verifica se tabela foi encontrada
  • Linha 10: return False - Retorna False se tabela não for encontrada
  • Linha 12: # Encontrar cabeçalhos - Comentário explicativo
  • Linha 13: cabecalhos = [] - Inicializa lista para cabeçalhos
  • Linha 14: th_elements = tabela.find('tr').find_all('th') - Encontra elementos de cabeçalho
  • Linha 15: for th in th_elements: - Percorre elementos de cabeçalho
  • Linha 16: cabecalhos.append(th.get_text().strip()) - Adiciona texto do cabeçalho à lista

10. Scraper de Notícias

from bs4 import BeautifulSoup
import requests

def coletar_manchetes(url):
    """Coleta manchetes de notícias de um site"""
    try:
        response = requests.get(url)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Encontrar manchetes (ajuste os seletores conforme o site)
        manchetes = soup.find_all('h2')  # ou 'h1', 'h3', etc.
        
        resultado = []
        for manchete in manchetes:
            texto = manchete.get_text().strip()
            if texto:  # Se não estiver vazio
                resultado.append(texto)
        
        return resultado
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar o site: {e}")
        return None

# Exemplo de uso (com HTML simulado)
html_exemplo = """
<html>
<body>
    <h1>Portal de Notícias</h1>
    <h2>Manchete 1: Novidades em Tecnologia</h2>
    <h2>Manchete 2: Economia em Destaque</h2>
    <h2>Manchete 3: Esportes do Dia</h2>
    <p>Parágrafo normal</p>
    <h2>Manchete 4: Política Nacional</h2>
</body>
</html>
"""

# Simular resposta de site
soup = BeautifulSoup(html_exemplo, 'html.parser')
manchetes = soup.find_all('h2')

print("Manchetes encontradas:")
for i, manchete in enumerate(manchetes, 1):
    print(f"{i}. {manchete.get_text().strip()}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para fazer requisições HTTP
  • Linha 4: def coletar_manchetes(url): - Define função que recebe URL do site
  • Linha 5: """Coleta manchetes de notícias de um site""" - Docstring explicando função
  • Linha 6: try: - Inicia bloco try para tratamento de erros
  • Linha 7: response = requests.get(url) - Faz requisição HTTP para o site
  • Linha 8: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 10: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup com conteúdo da página
  • Linha 12: # Encontrar manchetes (ajuste os seletores conforme o site) - Comentário explicativo
  • Linha 13: manchetes = soup.find_all('h2') - Encontra todos os elementos H2 (manchetes)
  • Linha 15: resultado = [] - Inicializa lista para armazenar manchetes
  • Linha 16: for manchete in manchetes: - Percorre cada manchete encontrada
  • Linha 17: texto = manchete.get_text().strip() - Extrai texto da manchete
  • Linha 18: if texto: - Verifica se texto não está vazio
  • Linha 19: resultado.append(texto) - Adiciona manchete à lista

14.7.3 MÉDIO (Nível 3)

11. Monitor de Preços

from bs4 import BeautifulSoup
import requests
import time
import json

def monitorar_precos(urls_produtos):
    """Monitora preços de produtos em múltiplos sites"""
    resultados = []
    
    for url in urls_produtos:
        try:
            response = requests.get(url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Extrair informações do produto (ajuste seletores conforme site)
            nome = soup.find('h1').get_text().strip()
            preco = soup.find('span', class_='preco').get_text().strip()
            
            resultados.append({
                'url': url,
                'nome': nome,
                'preco': preco,
                'data': time.strftime('%Y-%m-%d %H:%M:%S')
            })
            
            # Delay entre requisições
            time.sleep(2)
            
        except requests.exceptions.RequestException as e:
            print(f"❌ Erro ao acessar {url}: {e}")
            continue
    
    return resultados

# Exemplo de uso
urls_exemplo = [
    'https://loja1.com/produto1',
    'https://loja2.com/produto1',
    'https://loja3.com/produto1'
]

# Simular HTML de produtos
html_produto1 = """
<html>
<body>
    <h1>Notebook Gamer XYZ</h1>
    <span class="preco">R$ 2.500,00</span>
</body>
</html>
"""

html_produto2 = """
<html>
<body>
    <h1>Notebook Gamer XYZ</h1>
    <span class="preco">R$ 2.300,00</span>
</body>
</html>
"""

# Simular monitoramento
produtos = [
    {'url': 'loja1.com', 'nome': 'Notebook Gamer XYZ', 'preco': 'R$ 2.500,00'},
    {'url': 'loja2.com', 'nome': 'Notebook Gamer XYZ', 'preco': 'R$ 2.300,00'},
    {'url': 'loja3.com', 'nome': 'Notebook Gamer XYZ', 'preco': 'R$ 2.400,00'}
]

print("Comparação de preços:")
for produto in produtos:
    print(f"🏪 {produto['url']}: {produto['preco']}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays e timestamps
  • Linha 4: import json - Importa json para trabalhar com dados JSON
  • Linha 6: def monitorar_precos(urls_produtos): - Define função que recebe lista de URLs
  • Linha 7: """Monitora preços de produtos em múltiplos sites""" - Docstring explicando função
  • Linha 8: resultados = [] - Inicializa lista para armazenar resultados
  • Linha 10: for url in urls_produtos: - Percorre cada URL de produto
  • Linha 11: try: - Inicia bloco try para tratamento de erros
  • Linha 12: response = requests.get(url) - Faz requisição HTTP para o site
  • Linha 13: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 15: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 17: # Extrair informações do produto (ajuste seletores conforme site) - Comentário explicativo
  • Linha 18: nome = soup.find('h1').get_text().strip() - Extrai nome do produto
  • Linha 19: preco = soup.find('span', class_='preco').get_text().strip() - Extrai preço do produto

12. Extrator de Perfis

from bs4 import BeautifulSoup
import requests

def extrair_perfil_usuario(url_perfil):
    """Extrai informações de perfil de usuário de uma rede social"""
    try:
        response = requests.get(url_perfil)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Extrair informações do perfil (ajuste seletores conforme site)
        nome = soup.find('h1', class_='nome-usuario').get_text().strip()
        seguidores = soup.find('span', class_='seguidores').get_text().strip()
        seguindo = soup.find('span', class_='seguindo').get_text().strip()
        posts = soup.find('span', class_='posts').get_text().strip()
        
        perfil = {
            'nome': nome,
            'seguidores': seguidores,
            'seguindo': seguindo,
            'posts': posts,
            'url': url_perfil
        }
        
        return perfil
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar perfil: {e}")
        return None

# Exemplo de uso
html_perfil = """
<html>
<body>
    <div class="perfil">
        <h1 class="nome-usuario">João Silva</h1>
        <div class="stats">
            <span class="posts">150</span>
            <span class="seguidores">1.250</span>
            <span class="seguindo">300</span>
        </div>
    </div>
</body>
</html>
"""

soup = BeautifulSoup(html_perfil, 'html.parser')
nome = soup.find('h1', class_='nome-usuario').get_text().strip()
seguidores = soup.find('span', class_='seguidores').get_text().strip()

print(f"👤 Nome: {nome}")
print(f"👥 Seguidores: {seguidores}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 4: def extrair_perfil_usuario(url_perfil): - Define função que recebe URL do perfil
  • Linha 5: """Extrai informações de perfil de usuário de uma rede social""" - Docstring explicando função
  • Linha 6: try: - Inicia bloco try para tratamento de erros
  • Linha 7: response = requests.get(url_perfil) - Faz requisição HTTP para o perfil
  • Linha 8: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 10: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 12: # Extrair informações do perfil (ajuste seletores conforme site) - Comentário explicativo
  • Linha 13: nome = soup.find('h1', class_='nome-usuario').get_text().strip() - Extrai nome do usuário
  • Linha 14: seguidores = soup.find('span', class_='seguidores').get_text().strip() - Extrai número de seguidores
  • Linha 15: seguindo = soup.find('span', class_='seguindo').get_text().strip() - Extrai número de seguindo
  • Linha 16: posts = soup.find('span', class_='posts').get_text().strip() - Extrai número de posts

13. Scraper de Imóveis

from bs4 import BeautifulSoup
import requests
import re

def extrair_imoveis(url_site):
    """Extrai dados de imóveis (preço, localização, características)"""
    try:
        response = requests.get(url_site)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Encontrar todos os imóveis
        imoveis = soup.find_all('div', class_='imovel')
        
        resultado = []
        for imovel in imoveis:
            try:
                preco = imovel.find('span', class_='preco').get_text().strip()
                localizacao = imovel.find('span', class_='localizacao').get_text().strip()
                quartos = imovel.find('span', class_='quartos').get_text().strip()
                banheiros = imovel.find('span', class_='banheiros').get_text().strip()
                
                resultado.append({
                    'preco': preco,
                    'localizacao': localizacao,
                    'quartos': quartos,
                    'banheiros': banheiros
                })
            except AttributeError:
                continue
        
        return resultado
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar site: {e}")
        return None

# Exemplo de uso
html_imoveis = """
<html>
<body>
    <div class="imovel">
        <span class="preco">R$ 500.000</span>
        <span class="localizacao">São Paulo, SP</span>
        <span class="quartos">3 quartos</span>
        <span class="banheiros">2 banheiros</span>
    </div>
    <div class="imovel">
        <span class="preco">R$ 750.000</span>
        <span class="localizacao">Rio de Janeiro, RJ</span>
        <span class="quartos">4 quartos</span>
        <span class="banheiros">3 banheiros</span>
    </div>
</body>
</html>
"""

soup = BeautifulSoup(html_imoveis, 'html.parser')
imoveis = soup.find_all('div', class_='imovel')

print("Imóveis encontrados:")
for i, imovel in enumerate(imoveis, 1):
    preco = imovel.find('span', class_='preco').get_text().strip()
    localizacao = imovel.find('span', class_='localizacao').get_text().strip()
    print(f"{i}. {preco} - {localizacao}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import re - Importa módulo de expressões regulares
  • Linha 5: def extrair_imoveis(url_site): - Define função que recebe URL do site de imóveis
  • Linha 6: """Extrai dados de imóveis (preço, localização, características)""" - Docstring explicando função
  • Linha 7: try: - Inicia bloco try para tratamento de erros
  • Linha 8: response = requests.get(url_site) - Faz requisição HTTP para o site
  • Linha 9: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 11: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 13: # Encontrar todos os imóveis - Comentário explicativo
  • Linha 14: imoveis = soup.find_all('div', class_='imovel') - Encontra todos os elementos de imóvel
  • Linha 16: resultado = [] - Inicializa lista para armazenar dados dos imóveis
  • Linha 17: for imovel in imoveis: - Percorre cada imóvel encontrado
  • Linha 18: try: - Inicia bloco try para tratamento de erros
  • Linha 19: preco = imovel.find('span', class_='preco').get_text().strip() - Extrai preço do imóvel
  • Linha 20: localizacao = imovel.find('span', class_='localizacao').get_text().strip() - Extrai localização do imóvel

14. Extrator de Filmes

from bs4 import BeautifulSoup
import requests

def extrair_filmes(url_site):
    """Extrai dados de filmes/séries de um site de streaming"""
    try:
        response = requests.get(url_site)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Encontrar todos os filmes/séries
        conteudos = soup.find_all('div', class_='conteudo')
        
        resultado = []
        for conteudo in conteudos:
            try:
                titulo = conteudo.find('h3', class_='titulo').get_text().strip()
                genero = conteudo.find('span', class_='genero').get_text().strip()
                ano = conteudo.find('span', class_='ano').get_text().strip()
                avaliacao = conteudo.find('span', class_='avaliacao').get_text().strip()
                
                resultado.append({
                    'titulo': titulo,
                    'genero': genero,
                    'ano': ano,
                    'avaliacao': avaliacao
                })
            except AttributeError:
                continue
        
        return resultado
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar site: {e}")
        return None

# Exemplo de uso
html_filmes = """
<html>
<body>
    <div class="conteudo">
        <h3 class="titulo">Vingadores: Ultimato</h3>
        <span class="genero">Ação</span>
        <span class="ano">2019</span>
        <span class="avaliacao">8.4/10</span>
    </div>
    <div class="conteudo">
        <h3 class="titulo">Stranger Things</h3>
        <span class="genero">Drama</span>
        <span class="ano">2016</span>
        <span class="avaliacao">8.7/10</span>
    </div>
</body>
</html>
"""

soup = BeautifulSoup(html_filmes, 'html.parser')
conteudos = soup.find_all('div', class_='conteudo')

print("Filmes/Séries encontrados:")
for i, conteudo in enumerate(conteudos, 1):
    titulo = conteudo.find('h3', class_='titulo').get_text().strip()
    genero = conteudo.find('span', class_='genero').get_text().strip()
    print(f"{i}. {titulo} ({genero})")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 4: def extrair_filmes(url_site): - Define função que recebe URL do site de streaming
  • Linha 5: """Extrai dados de filmes/séries de um site de streaming""" - Docstring explicando função
  • Linha 6: try: - Inicia bloco try para tratamento de erros
  • Linha 7: response = requests.get(url_site) - Faz requisição HTTP para o site
  • Linha 8: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 10: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 12: # Encontrar todos os filmes/séries - Comentário explicativo
  • Linha 13: conteudos = soup.find_all('div', class_='conteudo') - Encontra todos os elementos de conteúdo
  • Linha 15: resultado = [] - Inicializa lista para armazenar dados dos filmes
  • Linha 16: for conteudo in conteudos: - Percorre cada conteúdo encontrado
  • Linha 17: try: - Inicia bloco try para tratamento de erros
  • Linha 18: titulo = conteudo.find('h3', class_='titulo').get_text().strip() - Extrai título do filme
  • Linha 19: genero = conteudo.find('span', class_='genero').get_text().strip() - Extrai gênero do filme

15. Scraper de Vagas

from bs4 import BeautifulSoup
import requests

def extrair_vagas(url_site):
    """Extrai informações de vagas de emprego"""
    try:
        response = requests.get(url_site)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Encontrar todas as vagas
        vagas = soup.find_all('div', class_='vaga')
        
        resultado = []
        for vaga in vagas:
            try:
                cargo = vaga.find('h3', class_='cargo').get_text().strip()
                empresa = vaga.find('span', class_='empresa').get_text().strip()
                salario = vaga.find('span', class_='salario').get_text().strip()
                localizacao = vaga.find('span', class_='localizacao').get_text().strip()
                
                resultado.append({
                    'cargo': cargo,
                    'empresa': empresa,
                    'salario': salario,
                    'localizacao': localizacao
                })
            except AttributeError:
                continue
        
        return resultado
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar site: {e}")
        return None

# Exemplo de uso
html_vagas = """
<html>
<body>
    <div class="vaga">
        <h3 class="cargo">Desenvolvedor Python</h3>
        <span class="empresa">Tech Corp</span>
        <span class="salario">R$ 8.000 - R$ 12.000</span>
        <span class="localizacao">São Paulo, SP</span>
    </div>
    <div class="vaga">
        <h3 class="cargo">Analista de Dados</h3>
        <span class="empresa">Data Solutions</span>
        <span class="salario">R$ 6.000 - R$ 9.000</span>
        <span class="localizacao">Rio de Janeiro, RJ</span>
    </div>
</body>
</html>
"""

soup = BeautifulSoup(html_vagas, 'html.parser')
vagas = soup.find_all('div', class_='vaga')

print("Vagas encontradas:")
for i, vaga in enumerate(vagas, 1):
    cargo = vaga.find('h3', class_='cargo').get_text().strip()
    empresa = vaga.find('span', class_='empresa').get_text().strip()
    print(f"{i}. {cargo} - {empresa}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 4: def extrair_vagas(url_site): - Define função que recebe URL do site de vagas
  • Linha 5: """Extrai informações de vagas de emprego""" - Docstring explicando função
  • Linha 6: try: - Inicia bloco try para tratamento de erros
  • Linha 7: response = requests.get(url_site) - Faz requisição HTTP para o site
  • Linha 8: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 10: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 12: # Encontrar todas as vagas - Comentário explicativo
  • Linha 13: vagas = soup.find_all('div', class_='vaga') - Encontra todos os elementos de vaga
  • Linha 15: resultado = [] - Inicializa lista para armazenar dados das vagas
  • Linha 16: for vaga in vagas: - Percorre cada vaga encontrada
  • Linha 17: try: - Inicia bloco try para tratamento de erros
  • Linha 18: cargo = vaga.find('h3', class_='cargo').get_text().strip() - Extrai cargo da vaga
  • Linha 19: empresa = vaga.find('span', class_='empresa').get_text().strip() - Extrai empresa da vaga
  • Linha 20: salario = vaga.find('span', class_='salario').get_text().strip() - Extrai salário da vaga
  • Linha 21: localizacao = vaga.find('span', class_='localizacao').get_text().strip() - Extrai localização da vaga

14.7.4 DIFÍCIL (Nível 4)

16. Scraper com Paginação

from bs4 import BeautifulSoup
import requests
import time

def scraper_com_paginacao(url_base, max_paginas=5):
    """Scraper que navega por múltiplas páginas (paginação)"""
    todos_dados = []
    
    for pagina in range(1, max_paginas + 1):
        try:
            # Construir URL da página
            if '?' in url_base:
                url_pagina = f"{url_base}&page={pagina}"
            else:
                url_pagina = f"{url_base}?page={pagina}"
            
            print(f"📄 Acessando página {pagina}...")
            
            response = requests.get(url_pagina)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Extrair dados da página atual
            itens = soup.find_all('div', class_='item')
            
            if not itens:  # Se não há itens, parar
                print(f"⏹️ Nenhum item encontrado na página {pagina}. Parando.")
                break
            
            for item in itens:
                try:
                    titulo = item.find('h3').get_text().strip()
                    preco = item.find('span', class_='preco').get_text().strip()
                    
                    todos_dados.append({
                        'pagina': pagina,
                        'titulo': titulo,
                        'preco': preco
                    })
                except AttributeError:
                    continue
            
            # Delay entre páginas
            time.sleep(2)
            
        except requests.exceptions.RequestException as e:
            print(f"❌ Erro na página {pagina}: {e}")
            continue
    
    return todos_dados

# Exemplo de uso
url_base = "https://exemplo.com/produtos"

# Simular dados de múltiplas páginas
dados_simulados = [
    {'pagina': 1, 'titulo': 'Produto A', 'preco': 'R$ 100'},
    {'pagina': 1, 'titulo': 'Produto B', 'preco': 'R$ 200'},
    {'pagina': 2, 'titulo': 'Produto C', 'preco': 'R$ 300'},
    {'pagina': 2, 'titulo': 'Produto D', 'preco': 'R$ 400'},
]

print("Dados coletados de múltiplas páginas:")
for dados in dados_simulados:
    print(f"Página {dados['pagina']}: {dados['titulo']} - {dados['preco']}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays
  • Linha 5: def scraper_com_paginacao(url_base, max_paginas=5): - Define função com URL base e número máximo de páginas
  • Linha 6: """Scraper que navega por múltiplas páginas (paginação)""" - Docstring explicando função
  • Linha 7: todos_dados = [] - Inicializa lista para armazenar todos os dados
  • Linha 9: for pagina in range(1, max_paginas + 1): - Percorre páginas de 1 até max_paginas
  • Linha 10: try: - Inicia bloco try para tratamento de erros
  • Linha 12: # Construir URL da página - Comentário explicativo
  • Linha 13: if '?' in url_base: - Verifica se URL já tem parâmetros
  • Linha 14: url_pagina = f"{url_base}&page={pagina}" - Adiciona parâmetro page com &
  • Linha 15: else: - Se não tem parâmetros
  • Linha 16: url_pagina = f"{url_base}?page={pagina}" - Adiciona parâmetro page com ?
  • Linha 18: print(f"📄 Acessando página {pagina}...") - Mostra progresso
  • Linha 20: response = requests.get(url_pagina) - Faz requisição para a página
  • Linha 21: response.raise_for_status() - Verifica se requisição foi bem-sucedida

17. Extrator de Gráficos

from bs4 import BeautifulSoup
import requests
import re
import json

def extrair_dados_graficos(url):
    """Extrai dados de gráficos e visualizações de dados de sites"""
    try:
        response = requests.get(url)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Procurar por dados em JavaScript (comum em gráficos)
        scripts = soup.find_all('script')
        
        dados_graficos = []
        
        for script in scripts:
            if script.string:
                # Procurar por padrões de dados JSON
                json_pattern = r'data:\s*(\[.*?\])'
                matches = re.findall(json_pattern, script.string)
                
                for match in matches:
                    try:
                        dados = json.loads(match)
                        dados_graficos.extend(dados)
                    except json.JSONDecodeError:
                        continue
        
        # Procurar por elementos com classes relacionadas a gráficos
        elementos_grafico = soup.find_all(['div', 'span'], class_=re.compile(r'chart|graph|data'))
        
        for elemento in elementos_grafico:
            texto = elemento.get_text().strip()
            if texto and re.match(r'^\d+$', texto):  # Se é um número
                dados_graficos.append(int(texto))
        
        return dados_graficos
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar site: {e}")
        return None

# Exemplo de uso
html_grafico = """
<html>
<body>
    <script>
        var chartData = {
            data: [10, 20, 30, 40, 50]
        };
    </script>
    <div class="chart-container">
        <span class="data-point">15</span>
        <span class="data-point">25</span>
        <span class="data-point">35</span>
    </div>
</body>
</html>
"""

soup = BeautifulSoup(html_grafico, 'html.parser')
scripts = soup.find_all('script')

print("Dados de gráficos encontrados:")
for script in scripts:
    if script.string and 'data:' in script.string:
        print(f"Script encontrado: {script.string[:50]}...")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import re - Importa módulo de expressões regulares
  • Linha 4: import json - Importa módulo json para trabalhar com dados JSON
  • Linha 6: def extrair_dados_graficos(url): - Define função que recebe URL do site
  • Linha 7: """Extrai dados de gráficos e visualizações de dados de sites""" - Docstring explicando função
  • Linha 8: try: - Inicia bloco try para tratamento de erros
  • Linha 9: response = requests.get(url) - Faz requisição HTTP para o site
  • Linha 10: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 12: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 14: # Procurar por dados em JavaScript (comum em gráficos) - Comentário explicativo
  • Linha 15: scripts = soup.find_all('script') - Encontra todos os elementos script
  • Linha 17: dados_graficos = [] - Inicializa lista para armazenar dados dos gráficos
  • Linha 19: for script in scripts: - Percorre cada script encontrado
  • Linha 20: if script.string: - Verifica se script tem conteúdo
  • Linha 22: # Procurar por padrões de dados JSON - Comentário explicativo
  • Linha 23: json_pattern = r'data:\s*(\[.*?\])' - Padrão regex para encontrar dados JSON

18. Monitor de Mudanças

from bs4 import BeautifulSoup
import requests
import time
import hashlib

def monitorar_mudancas(url, intervalo=60):
    """Monitora mudanças em páginas web ao longo do tempo"""
    hash_anterior = None
    contador_mudancas = 0
    
    print(f"🔍 Iniciando monitoramento de {url}")
    print(f"⏰ Intervalo: {intervalo} segundos")
    
    while True:
        try:
            response = requests.get(url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Remover elementos que mudam frequentemente (timestamps, etc.)
            for elemento in soup.find_all(['script', 'style']):
                elemento.decompose()
            
            # Calcular hash do conteúdo
            conteudo = soup.get_text()
            hash_atual = hashlib.md5(conteudo.encode()).hexdigest()
            
            if hash_anterior is None:
                print("📝 Hash inicial calculado")
                hash_anterior = hash_atual
            elif hash_atual != hash_anterior:
                contador_mudancas += 1
                timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
                print(f"🔄 MUDANÇA DETECTADA #{contador_mudancas} em {timestamp}")
                print(f"   Hash anterior: {hash_anterior[:10]}...")
                print(f"   Hash atual: {hash_atual[:10]}...")
                hash_anterior = hash_atual
            else:
                print("✅ Nenhuma mudança detectada")
            
            time.sleep(intervalo)
            
        except requests.exceptions.RequestException as e:
            print(f"❌ Erro ao acessar site: {e}")
            time.sleep(intervalo)
            continue
        except KeyboardInterrupt:
            print("\n⏹️ Monitoramento interrompido pelo usuário")
            break

# Exemplo de uso (simulado)
def simular_monitoramento():
    """Simula monitoramento de mudanças"""
    print("🔍 Simulando monitoramento de mudanças...")
    
    # Simular diferentes estados da página
    estados = [
        "Conteúdo original",
        "Conteúdo modificado",
        "Conteúdo modificado novamente"
    ]
    
    for i, estado in enumerate(estados):
        print(f"📄 Estado {i+1}: {estado}")
        time.sleep(1)

simular_monitoramento()

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays e timestamps
  • Linha 4: import hashlib - Importa hashlib para calcular hashes
  • Linha 6: def monitorar_mudancas(url, intervalo=60): - Define função com URL e intervalo de monitoramento
  • Linha 7: """Monitora mudanças em páginas web ao longo do tempo""" - Docstring explicando função
  • Linha 8: hash_anterior = None - Inicializa variável para hash anterior
  • Linha 9: contador_mudancas = 0 - Inicializa contador de mudanças
  • Linha 11: print(f"🔍 Iniciando monitoramento de {url}") - Mostra início do monitoramento
  • Linha 12: print(f"⏰ Intervalo: {intervalo} segundos") - Mostra intervalo de monitoramento
  • Linha 14: while True: - Loop infinito para monitoramento contínuo
  • Linha 15: try: - Inicia bloco try para tratamento de erros
  • Linha 16: response = requests.get(url) - Faz requisição HTTP para o site
  • Linha 17: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 19: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 21: # Remover elementos que mudam frequentemente (timestamps, etc.) - Comentário explicativo
  • Linha 22: for elemento in soup.find_all(['script', 'style']): - Percorre elementos que mudam frequentemente
  • Linha 23: elemento.decompose() - Remove elemento da árvore HTML

19. Extrator de APIs JavaScript

from bs4 import BeautifulSoup
import requests
import re
import json

def extrair_apis_javascript(url):
    """Extrai dados de APIs que são carregadas via JavaScript"""
    try:
        response = requests.get(url)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Procurar por URLs de APIs em scripts
        scripts = soup.find_all('script')
        apis_encontradas = []
        
        for script in scripts:
            if script.string:
                # Procurar por padrões de URLs de API
                api_patterns = [
                    r'fetch\(["\']([^"\']+)["\']',
                    r'axios\.get\(["\']([^"\']+)["\']',
                    r'\.get\(["\']([^"\']+)["\']',
                    r'api_url["\']?\s*[:=]\s*["\']([^"\']+)["\']'
                ]
                
                for pattern in api_patterns:
                    matches = re.findall(pattern, script.string)
                    apis_encontradas.extend(matches)
        
        # Procurar por elementos com data-attributes relacionados a APIs
        elementos_api = soup.find_all(attrs={'data-api': True})
        
        for elemento in elementos_api:
            api_url = elemento.get('data-api')
            if api_url:
                apis_encontradas.append(api_url)
        
        # Remover duplicatas
        apis_unicas = list(set(apis_encontradas))
        
        return apis_unicas
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar site: {e}")
        return None

# Exemplo de uso
html_js_api = """
<html>
<body>
    <script>
        fetch('/api/produtos')
            .then(response => response.json())
            .then(data => console.log(data));
        
        var api_url = 'https://api.exemplo.com/dados';
        axios.get(api_url);
    </script>
    <div data-api="/api/usuarios">Carregar usuários</div>
</body>
</html>
"""

soup = BeautifulSoup(html_js_api, 'html.parser')
scripts = soup.find_all('script')

print("APIs JavaScript encontradas:")
for script in scripts:
    if script.string:
        if 'fetch(' in script.string or 'axios' in script.string:
            print(f"Script com API: {script.string[:100]}...")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import re - Importa módulo de expressões regulares
  • Linha 4: import json - Importa módulo json para trabalhar com dados JSON
  • Linha 6: def extrair_apis_javascript(url): - Define função que recebe URL do site
  • Linha 7: """Extrai dados de APIs que são carregadas via JavaScript""" - Docstring explicando função
  • Linha 8: try: - Inicia bloco try para tratamento de erros
  • Linha 9: response = requests.get(url) - Faz requisição HTTP para o site
  • Linha 10: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 12: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 14: # Procurar por URLs de APIs em scripts - Comentário explicativo
  • Linha 15: scripts = soup.find_all('script') - Encontra todos os elementos script
  • Linha 16: apis_encontradas = [] - Inicializa lista para armazenar APIs encontradas
  • Linha 18: for script in scripts: - Percorre cada script encontrado
  • Linha 19: if script.string: - Verifica se script tem conteúdo
  • Linha 21: # Procurar por padrões de URLs de API - Comentário explicativo
  • Linha 22: api_patterns = [ - Inicia lista de padrões regex para encontrar APIs
  • Linha 23: r'fetch\(["\']([^"\']+)["\']', - Padrão para fetch()
  • Linha 24: r'axios\.get\(["\']([^"\']+)["\']', - Padrão para axios.get()
  • Linha 25: r'\.get\(["\']([^"\']+)["\']', - Padrão genérico para .get()
  • Linha 26: r'api_url["\']?\s*[:=]\s*["\']([^"\']+)["\']' - Padrão para variáveis de API

20. Scraper Anti-Bloqueio

from bs4 import BeautifulSoup
import requests
import time
import random
from urllib.parse import urljoin

def scraping_anti_bloqueio(url):
    """Scraper que contorna proteções básicas contra scraping"""
    
    # Headers para simular navegador real
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language': 'pt-BR,pt;q=0.9,en;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'DNT': '1',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1',
    }
    
    try:
        # Delay aleatório entre 1-3 segundos
        time.sleep(random.uniform(1, 3))
        
        # Fazer requisição com headers
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Verificar se página foi bloqueada
        if soup.find(text=re.compile(r'blocked|access denied|captcha', re.I)):
            print("🚫 Página bloqueada detectada")
            return None
        
        # Extrair dados
        dados = []
        elementos = soup.find_all('div', class_='item')
        
        for elemento in elementos:
            try:
                titulo = elemento.find('h3').get_text().strip()
                preco = elemento.find('span', class_='preco').get_text().strip()
                
                dados.append({
                    'titulo': titulo,
                    'preco': preco
                })
            except AttributeError:
                continue
        
        return dados
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Erro ao acessar site: {e}")
        return None

# Exemplo de uso
def simular_scraping_anti_bloqueio():
    """Simula scraping anti-bloqueio"""
    print("🛡️ Simulando scraping anti-bloqueio...")
    
    # Simular headers
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    
    print(f"📡 Headers configurados: {len(headers)} headers")
    print("⏰ Delay aleatório aplicado")
    print("🔍 Dados extraídos com sucesso")

simular_scraping_anti_bloqueio()

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays
  • Linha 4: import random - Importa random para delays aleatórios
  • Linha 5: from urllib.parse import urljoin - Importa urljoin para construir URLs
  • Linha 7: def scraping_anti_bloqueio(url): - Define função que recebe URL do site
  • Linha 8: """Scraper que contorna proteções básicas contra scraping""" - Docstring explicando função
  • Linha 10: # Headers para simular navegador real - Comentário explicativo
  • Linha 11: headers = { - Inicia dicionário com headers de navegador
  • Linha 12: 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', - User-Agent de navegador real
  • Linha 13: 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', - Headers de aceitação
  • Linha 14: 'Accept-Language': 'pt-BR,pt;q=0.9,en;q=0.8', - Idioma preferido
  • Linha 15: 'Accept-Encoding': 'gzip, deflate, br', - Codificação aceita
  • Linha 16: 'DNT': '1', - Do Not Track
  • Linha 17: 'Connection': 'keep-alive', - Conexão persistente
  • Linha 18: 'Upgrade-Insecure-Requests': '1', - Upgrade para HTTPS
  • Linha 19: } - Fecha dicionário de headers
  • Linha 21: try: - Inicia bloco try para tratamento de erros
  • Linha 23: # Delay aleatório entre 1-3 segundos - Comentário explicativo
  • Linha 24: time.sleep(random.uniform(1, 3)) - Delay aleatório para evitar detecção
  • Linha 26: # Fazer requisição com headers - Comentário explicativo
  • Linha 27: response = requests.get(url, headers=headers, timeout=10) - Faz requisição com headers e timeout

14.7.5 MUITO DIFÍCIL (Nível 5)

21. Sistema de Monitoramento

from bs4 import BeautifulSoup
import requests
import time
import json
import smtplib
from email.mime.text import MIMEText

class SistemaMonitoramento:
    def __init__(self, produtos_monitorados):
        self.produtos = produtos_monitorados
        self.historico_precos = {}
        
    def monitorar_precos(self):
        """Monitora preços e envia alertas"""
        for produto in self.produtos:
            try:
                preco_atual = self.extrair_preco(produto['url'])
                
                if preco_atual:
                    # Verificar se preço mudou
                    if produto['nome'] in self.historico_precos:
                        preco_anterior = self.historico_precos[produto['nome']]
                        
                        if preco_atual < preco_anterior:
                            self.enviar_alerta(produto, preco_anterior, preco_atual)
                    
                    self.historico_precos[produto['nome']] = preco_atual
                    
                time.sleep(2)  # Delay entre requisições
                
            except Exception as e:
                print(f"❌ Erro ao monitorar {produto['nome']}: {e}")
    
    def extrair_preco(self, url):
        """Extrai preço de um produto"""
        try:
            response = requests.get(url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            preco_element = soup.find('span', class_='preco')
            
            if preco_element:
                preco_texto = preco_element.get_text().strip()
                # Extrair apenas números do preço
                preco_numerico = float(re.sub(r'[^\d,.]', '', preco_texto).replace(',', '.'))
                return preco_numerico
            
            return None
            
        except Exception as e:
            print(f"❌ Erro ao extrair preço: {e}")
            return None
    
    def enviar_alerta(self, produto, preco_anterior, preco_atual):
        """Envia alerta de queda de preço"""
        mensagem = f"""
        🎉 ALERTA DE PREÇO!
        
        Produto: {produto['nome']}
        Preço anterior: R$ {preco_anterior:.2f}
        Preço atual: R$ {preco_atual:.2f}
        Economia: R$ {preco_anterior - preco_atual:.2f}
        
        Link: {produto['url']}
        """
        
        print(f"📧 Alerta enviado: {produto['nome']} - R$ {preco_atual:.2f}")

# Exemplo de uso
produtos = [
    {'nome': 'Notebook Gamer', 'url': 'https://loja.com/notebook'},
    {'nome': 'Mouse Óptico', 'url': 'https://loja.com/mouse'}
]

sistema = SistemaMonitoramento(produtos)
print("🔍 Sistema de monitoramento iniciado")
print("📊 Monitorando preços...")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays
  • Linha 4: import json - Importa json para trabalhar com dados JSON
  • Linha 5: import smtplib - Importa smtplib para envio de emails
  • Linha 6: from email.mime.text import MIMEText - Importa MIMEText para emails
  • Linha 8: class SistemaMonitoramento: - Define classe para sistema de monitoramento
  • Linha 9: def __init__(self, produtos_monitorados): - Construtor da classe
  • Linha 10: self.produtos = produtos_monitorados - Armazena produtos para monitorar
  • Linha 11: self.historico_precos = {} - Inicializa dicionário para histórico de preços
  • Linha 13: def monitorar_precos(self): - Define método para monitorar preços
  • Linha 14: """Monitora preços e envia alertas""" - Docstring explicando método
  • Linha 15: for produto in self.produtos: - Percorre cada produto para monitorar
  • Linha 16: try: - Inicia bloco try para tratamento de erros
  • Linha 17: preco_atual = self.extrair_preco(produto['url']) - Extrai preço atual do produto
  • Linha 19: if preco_atual: - Verifica se preço foi extraído com sucesso
  • Linha 21: # Verificar se preço mudou - Comentário explicativo
  • Linha 22: if produto['nome'] in self.historico_precos: - Verifica se produto já foi monitorado antes
  • Linha 23: preco_anterior = self.historico_precos[produto['nome']] - Obtém preço anterior
  • Linha 25: if preco_atual < preco_anterior: - Verifica se preço diminuiu
  • Linha 26: self.enviar_alerta(produto, preco_anterior, preco_atual) - Envia alerta de queda de preço

22. Scraper com Autenticação

from bs4 import BeautifulSoup
import requests
import time

class ScraperAutenticado:
    def __init__(self, base_url):
        self.base_url = base_url
        self.session = requests.Session()
        self.logado = False
    
    def fazer_login(self, username, password):
        """Faz login no site"""
        try:
            # Página de login
            login_url = f"{self.base_url}/login"
            response = self.session.get(login_url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Encontrar token CSRF
            csrf_token = soup.find('input', {'name': 'csrf_token'})
            if csrf_token:
                csrf_value = csrf_token.get('value')
            else:
                csrf_value = None
            
            # Dados do login
            login_data = {
                'username': username,
                'password': password,
                'csrf_token': csrf_value
            }
            
            # Fazer login
            response = self.session.post(login_url, data=login_data)
            response.raise_for_status()
            
            # Verificar se login foi bem-sucedido
            if 'dashboard' in response.url or 'welcome' in response.text.lower():
                self.logado = True
                print("✅ Login realizado com sucesso!")
                return True
            else:
                print("❌ Falha no login")
                return False
                
        except Exception as e:
            print(f"❌ Erro no login: {e}")
            return False
    
    def extrair_dados_protegidos(self, url):
        """Extrai dados de páginas protegidas"""
        if not self.logado:
            print("❌ É necessário fazer login primeiro")
            return None
        
        try:
            response = self.session.get(url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Extrair dados da página protegida
            dados = []
            elementos = soup.find_all('div', class_='dados-protegidos')
            
            for elemento in elementos:
                try:
                    titulo = elemento.find('h3').get_text().strip()
                    conteudo = elemento.find('p').get_text().strip()
                    
                    dados.append({
                        'titulo': titulo,
                        'conteudo': conteudo
                    })
                except AttributeError:
                    continue
            
            return dados
            
        except Exception as e:
            print(f"❌ Erro ao extrair dados: {e}")
            return None

# Exemplo de uso
scraper = ScraperAutenticado('https://site-exemplo.com')

# Simular login
print("🔐 Simulando login...")
print("✅ Login simulado com sucesso!")

# Simular extração de dados
print("🔍 Extraindo dados protegidos...")
dados_simulados = [
    {'titulo': 'Dados Pessoais', 'conteudo': 'Informações confidenciais'},
    {'titulo': 'Histórico', 'conteudo': 'Dados históricos'}
]

for dados in dados_simulados:
    print(f"📄 {dados['titulo']}: {dados['conteudo']}")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays
  • Linha 5: class ScraperAutenticado: - Define classe para scraper com autenticação
  • Linha 6: def __init__(self, base_url): - Construtor da classe
  • Linha 7: self.base_url = base_url - Armazena URL base do site
  • Linha 8: self.session = requests.Session() - Cria sessão para manter cookies
  • Linha 9: self.logado = False - Inicializa flag de login
  • Linha 11: def fazer_login(self, username, password): - Define método para fazer login
  • Linha 12: """Faz login no site""" - Docstring explicando método
  • Linha 13: try: - Inicia bloco try para tratamento de erros
  • Linha 15: # Página de login - Comentário explicativo
  • Linha 16: login_url = f"{self.base_url}/login" - Constrói URL de login
  • Linha 17: response = self.session.get(login_url) - Faz requisição para página de login
  • Linha 18: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 20: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 22: # Encontrar token CSRF - Comentário explicativo
  • Linha 23: csrf_token = soup.find('input', {'name': 'csrf_token'}) - Procura token CSRF
  • Linha 24: if csrf_token: - Verifica se token foi encontrado
  • Linha 25: csrf_value = csrf_token.get('value') - Obtém valor do token
  • Linha 26: else: - Se token não foi encontrado
  • Linha 27: csrf_value = None - Define token como None

23. Scraper Distribuído

import multiprocessing
from bs4 import BeautifulSoup
import requests
import time
import json

def processar_url(url_data):
    """Processa uma URL em um processo separado"""
    url = url_data['url']
    processo_id = url_data['processo_id']
    
    try:
        print(f"🔄 Processo {processo_id}: Processando {url}")
        
        response = requests.get(url)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Extrair dados
        dados = []
        elementos = soup.find_all('div', class_='item')
        
        for elemento in elementos:
            try:
                titulo = elemento.find('h3').get_text().strip()
                preco = elemento.find('span', class_='preco').get_text().strip()
                
                dados.append({
                    'url': url,
                    'titulo': titulo,
                    'preco': preco,
                    'processo': processo_id
                })
            except AttributeError:
                continue
        
        print(f"✅ Processo {processo_id}: {len(dados)} itens extraídos")
        return dados
        
    except Exception as e:
        print(f"❌ Processo {processo_id}: Erro ao processar {url}: {e}")
        return []

class ScraperDistribuido:
    def __init__(self, num_processos=4):
        self.num_processos = num_processos
    
    def processar_urls(self, urls):
        """Processa múltiplas URLs em paralelo"""
        print(f"🚀 Iniciando scraping distribuído com {self.num_processos} processos")
        
        # Preparar dados para cada processo
        dados_processos = []
        for i, url in enumerate(urls):
            dados_processos.append({
                'url': url,
                'processo_id': i + 1
            })
        
        # Executar em paralelo
        with multiprocessing.Pool(self.num_processos) as pool:
            resultados = pool.map(processar_url, dados_processos)
        
        # Consolidar resultados
        todos_dados = []
        for resultado in resultados:
            todos_dados.extend(resultado)
        
        print(f"📊 Total de dados extraídos: {len(todos_dados)}")
        return todos_dados

# Exemplo de uso
urls = [
    'https://site1.com/produtos',
    'https://site2.com/produtos',
    'https://site3.com/produtos',
    'https://site4.com/produtos'
]

scraper = ScraperDistribuido(num_processos=2)

# Simular scraping distribuído
print("🔄 Simulando scraping distribuído...")
for i, url in enumerate(urls):
    print(f"Processo {i+1}: Processando {url}")
    time.sleep(0.5)  # Simular processamento

print("✅ Scraping distribuído concluído!")

Explicação linha por linha:

  • Linha 1: import multiprocessing - Importa módulo multiprocessing para processamento paralelo
  • Linha 2: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 3: import requests - Importa requests para requisições HTTP
  • Linha 4: import time - Importa time para delays
  • Linha 5: import json - Importa json para trabalhar com dados JSON
  • Linha 7: def processar_url(url_data): - Define função para processar uma URL
  • Linha 8: """Processa uma URL em um processo separado""" - Docstring explicando função
  • Linha 9: url = url_data['url'] - Extrai URL dos dados
  • Linha 10: processo_id = url_data['processo_id'] - Extrai ID do processo
  • Linha 12: try: - Inicia bloco try para tratamento de erros
  • Linha 13: print(f"🔄 Processo {processo_id}: Processando {url}") - Mostra progresso do processo
  • Linha 15: response = requests.get(url) - Faz requisição HTTP para a URL
  • Linha 16: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 18: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 20: # Extrair dados - Comentário explicativo
  • Linha 21: dados = [] - Inicializa lista para armazenar dados
  • Linha 22: elementos = soup.find_all('div', class_='item') - Encontra elementos para extrair
  • Linha 24: for elemento in elementos: - Percorre cada elemento encontrado
  • Linha 25: try: - Inicia bloco try para tratamento de erros
  • Linha 26: titulo = elemento.find('h3').get_text().strip() - Extrai título do elemento
  • Linha 27: preco = elemento.find('span', class_='preco').get_text().strip() - Extrai preço do elemento

24. Scraper Anti-CAPTCHA

from bs4 import BeautifulSoup
import requests
import time
import random
from PIL import Image
import pytesseract

class ScraperAntiCaptcha:
    def __init__(self):
        self.session = requests.Session()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
    
    def resolver_captcha(self, captcha_url):
        """Resolve CAPTCHA usando OCR"""
        try:
            # Baixar imagem do CAPTCHA
            response = self.session.get(captcha_url)
            response.raise_for_status()
            
            # Salvar imagem temporariamente
            with open('captcha_temp.png', 'wb') as f:
                f.write(response.content)
            
            # Usar OCR para ler CAPTCHA
            imagem = Image.open('captcha_temp.png')
            texto_captcha = pytesseract.image_to_string(imagem).strip()
            
            print(f"🔍 CAPTCHA resolvido: {texto_captcha}")
            return texto_captcha
            
        except Exception as e:
            print(f"❌ Erro ao resolver CAPTCHA: {e}")
            return None
    
    def contornar_rate_limiting(self, url):
        """Contorna rate limiting com delays inteligentes"""
        try:
            # Delay aleatório entre 3-8 segundos
            delay = random.uniform(3, 8)
            print(f"⏰ Aguardando {delay:.1f} segundos...")
            time.sleep(delay)
            
            # Fazer requisição
            response = self.session.get(url, headers=self.headers)
            
            # Verificar se foi rate limited
            if response.status_code == 429:
                print("🚫 Rate limited detectado, aguardando mais tempo...")
                time.sleep(random.uniform(10, 20))
                response = self.session.get(url, headers=self.headers)
            
            response.raise_for_status()
            return response
            
        except Exception as e:
            print(f"❌ Erro ao contornar rate limiting: {e}")
            return None
    
    def extrair_dados_protegidos(self, url):
        """Extrai dados de sites com proteções avançadas"""
        try:
            # Primeira tentativa
            response = self.contornar_rate_limiting(url)
            
            if not response:
                return None
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Verificar se há CAPTCHA
            captcha_img = soup.find('img', {'alt': re.compile(r'captcha', re.I)})
            if captcha_img:
                captcha_url = captcha_img.get('src')
                if captcha_url:
                    texto_captcha = self.resolver_captcha(captcha_url)
                    if texto_captcha:
                        # Submeter CAPTCHA
                        form_data = {
                            'captcha': texto_captcha,
                            'submit': 'Submit'
                        }
                        response = self.session.post(url, data=form_data)
                        soup = BeautifulSoup(response.content, 'html.parser')
            
            # Extrair dados
            dados = []
            elementos = soup.find_all('div', class_='dados')
            
            for elemento in elementos:
                try:
                    titulo = elemento.find('h3').get_text().strip()
                    conteudo = elemento.find('p').get_text().strip()
                    
                    dados.append({
                        'titulo': titulo,
                        'conteudo': conteudo
                    })
                except AttributeError:
                    continue
            
            return dados
            
        except Exception as e:
            print(f"❌ Erro ao extrair dados protegidos: {e}")
            return None

# Exemplo de uso
scraper = ScraperAntiCaptcha()

# Simular contorno de proteções
print("🛡️ Simulando contorno de proteções avançadas...")
print("⏰ Aplicando delays inteligentes...")
print("🔍 Resolvendo CAPTCHA...")
print("✅ Dados extraídos com sucesso!")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays
  • Linha 4: import random - Importa random para delays aleatórios
  • Linha 5: from PIL import Image - Importa PIL para trabalhar com imagens
  • Linha 6: import pytesseract - Importa pytesseract para OCR
  • Linha 8: class ScraperAntiCaptcha: - Define classe para scraper anti-CAPTCHA
  • Linha 9: def __init__(self): - Construtor da classe
  • Linha 10: self.session = requests.Session() - Cria sessão para manter cookies
  • Linha 11: self.headers = { - Define headers para simular navegador
  • Linha 12: 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' - User-Agent de navegador
  • Linha 13: } - Fecha dicionário de headers
  • Linha 15: def resolver_captcha(self, captcha_url): - Define método para resolver CAPTCHA
  • Linha 16: """Resolve CAPTCHA usando OCR""" - Docstring explicando método
  • Linha 17: try: - Inicia bloco try para tratamento de erros
  • Linha 19: # Baixar imagem do CAPTCHA - Comentário explicativo
  • Linha 20: response = self.session.get(captcha_url) - Faz requisição para imagem do CAPTCHA
  • Linha 21: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 23: # Salvar imagem temporariamente - Comentário explicativo
  • Linha 24: with open('captcha_temp.png', 'wb') as f: - Abre arquivo para salvar imagem
  • Linha 25: f.write(response.content) - Salva conteúdo da imagem no arquivo

25. Scraper Adaptativo

from bs4 import BeautifulSoup
import requests
import time
import re
from urllib.parse import urljoin

class ScraperAdaptativo:
    def __init__(self):
        self.session = requests.Session()
        self.estrategias = {
            'produtos': self.extrair_produtos,
            'noticias': self.extrair_noticias,
            'contatos': self.extrair_contatos
        }
    
    def detectar_tipo_site(self, url):
        """Detecta automaticamente o tipo de site"""
        try:
            response = self.session.get(url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Analisar conteúdo para detectar tipo
            texto = soup.get_text().lower()
            
            if any(palavra in texto for palavra in ['produto', 'preço', 'comprar', 'loja']):
                return 'produtos'
            elif any(palavra in texto for palavra in ['notícia', 'artigo', 'manchete']):
                return 'noticias'
            elif any(palavra in texto for palavra in ['contato', 'email', 'telefone']):
                return 'contatos'
            else:
                return 'generico'
                
        except Exception as e:
            print(f"❌ Erro ao detectar tipo do site: {e}")
            return 'generico'
    
    def extrair_produtos(self, soup):
        """Estratégia para extrair produtos"""
        dados = []
        
        # Tentar diferentes seletores comuns
        seletores_produto = [
            'div.produto',
            'div.item',
            'div.product',
            'article',
            '.product-item'
        ]
        
        for seletor in seletores_produto:
            elementos = soup.select(seletor)
            if elementos:
                print(f"✅ Encontrados {len(elementos)} produtos com seletor: {seletor}")
                
                for elemento in elementos:
                    try:
                        titulo = elemento.find(['h1', 'h2', 'h3', 'h4']).get_text().strip()
                        preco = elemento.find(text=re.compile(r'R\$\s*\d+'))
                        
                        if titulo and preco:
                            dados.append({
                                'titulo': titulo,
                                'preco': preco.strip()
                            })
                    except AttributeError:
                        continue
                
                break
        
        return dados
    
    def extrair_noticias(self, soup):
        """Estratégia para extrair notícias"""
        dados = []
        
        # Tentar diferentes seletores comuns
        seletores_noticia = [
            'div.noticia',
            'div.news',
            'article',
            '.news-item',
            'div.article'
        ]
        
        for seletor in seletores_noticia:
            elementos = soup.select(seletor)
            if elementos:
                print(f"✅ Encontradas {len(elementos)} notícias com seletor: {seletor}")
                
                for elemento in elementos:
                    try:
                        titulo = elemento.find(['h1', 'h2', 'h3', 'h4']).get_text().strip()
                        resumo = elemento.find('p').get_text().strip()
                        
                        if titulo:
                            dados.append({
                                'titulo': titulo,
                                'resumo': resumo[:100] + '...' if len(resumo) > 100 else resumo
                            })
                    except AttributeError:
                        continue
                
                break
        
        return dados
    
    def extrair_contatos(self, soup):
        """Estratégia para extrair contatos"""
        dados = {}
        
        # Procurar por emails
        emails = re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', soup.get_text())
        if emails:
            dados['emails'] = list(set(emails))
        
        # Procurar por telefones
        telefones = re.findall(r'\(?\d{2}\)?[-.\s]?\d{4,5}[-.\s]?\d{4}', soup.get_text())
        if telefones:
            dados['telefones'] = list(set(telefones))
        
        return dados
    
    def extrair_dados_adaptativo(self, url):
        """Extrai dados adaptando-se automaticamente ao site"""
        try:
            print(f"🔍 Analisando site: {url}")
            
            # Detectar tipo do site
            tipo_site = self.detectar_tipo_site(url)
            print(f"📊 Tipo detectado: {tipo_site}")
            
            # Fazer requisição
            response = self.session.get(url)
            response.raise_for_status()
            
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # Aplicar estratégia apropriada
            if tipo_site in self.estrategias:
                dados = self.estrategias[tipo_site](soup)
                print(f"📄 Dados extraídos: {len(dados) if isinstance(dados, list) else 'contatos'}")
                return dados
            else:
                print("❓ Tipo de site não reconhecido, usando estratégia genérica")
                return {'tipo': 'generico', 'conteudo': soup.get_text()[:500]}
                
        except Exception as e:
            print(f"❌ Erro ao extrair dados: {e}")
            return None

# Exemplo de uso
scraper = ScraperAdaptativo()

# Simular extração adaptativa
print("🤖 Simulando scraper adaptativo...")
print("🔍 Analisando site...")
print("📊 Tipo detectado: produtos")
print("✅ Estratégia de produtos aplicada")
print("📄 15 produtos extraídos com sucesso!")

Explicação linha por linha:

  • Linha 1: from bs4 import BeautifulSoup - Importa BeautifulSoup
  • Linha 2: import requests - Importa requests para requisições HTTP
  • Linha 3: import time - Importa time para delays
  • Linha 4: import re - Importa módulo de expressões regulares
  • Linha 5: from urllib.parse import urljoin - Importa urljoin para construir URLs
  • Linha 7: class ScraperAdaptativo: - Define classe para scraper adaptativo
  • Linha 8: def __init__(self): - Construtor da classe
  • Linha 9: self.session = requests.Session() - Cria sessão para manter cookies
  • Linha 10: self.estrategias = { - Define dicionário com estratégias de extração
  • Linha 11: 'produtos': self.extrair_produtos, - Mapeia tipo ‘produtos’ para método
  • Linha 12: 'noticias': self.extrair_noticias, - Mapeia tipo ‘noticias’ para método
  • Linha 13: 'contatos': self.extrair_contatos - Mapeia tipo ‘contatos’ para método
  • Linha 14: } - Fecha dicionário de estratégias
  • Linha 16: def detectar_tipo_site(self, url): - Define método para detectar tipo do site
  • Linha 17: """Detecta automaticamente o tipo de site""" - Docstring explicando método
  • Linha 18: try: - Inicia bloco try para tratamento de erros
  • Linha 19: response = self.session.get(url) - Faz requisição HTTP para o site
  • Linha 20: response.raise_for_status() - Verifica se requisição foi bem-sucedida
  • Linha 22: soup = BeautifulSoup(response.content, 'html.parser') - Cria objeto BeautifulSoup
  • Linha 24: # Analisar conteúdo para detectar tipo - Comentário explicativo
  • Linha 25: texto = soup.get_text().lower() - Obtém todo o texto da página em minúsculas
  • Linha 27: if any(palavra in texto for palavra in ['produto', 'preço', 'comprar', 'loja']): - Verifica se é site de produtos
  • Linha 28: return 'produtos' - Retorna tipo ‘produtos’
  • Linha 29: elif any(palavra in texto for palavra in ['notícia', 'artigo', 'manchete']): - Verifica se é site de notícias
  • Linha 30: return 'noticias' - Retorna tipo ‘noticias’
  • Linha 31: elif any(palavra in texto for palavra in ['contato', 'email', 'telefone']): - Verifica se é site de contatos
  • Linha 32: return 'contatos' - Retorna tipo ‘contatos’
  • Linha 33: else: - Se não é nenhum tipo específico
  • Linha 34: return 'generico' - Retorna tipo ‘generico’

Solução: Extrair títulos H1

from bs4 import BeautifulSoup

html = '''
<html>
<head><title>Minha Página</title></head>
<body>
    <h1>Título Principal</h1>
    <h1>Outro Título</h1>
    <p>Parágrafo normal</p>
</body>
</html>
'''

soup = BeautifulSoup(html, 'html.parser')
titulos = soup.find_all('h1')

for titulo in titulos:
    print(titulo.text)

Conceitos-chave: BeautifulSoup, find_all, extração de texto

14.8 Próximos Passos: Continue Aprendendo!

Parabéns! Você agora domina web scraping com BeautifulSoup! 🎉

14.8.1 O que você aprendeu:

  • Conceito de Web Scraping: Como extrair dados de páginas web
  • HTML básico: Estrutura de páginas web e tags essenciais
  • BeautifulSoup: Como usar a biblioteca para parsing de HTML
  • Seletores: Como encontrar elementos específicos na página
  • requests + BeautifulSoup: Combinando requisições HTTP com parsing
  • Scraping responsável: Boas práticas e ética no scraping
  • Salvando dados: Como organizar dados coletados em arquivos
  • Projetos práticos: Sistemas de coleta de dados da web

14.8.2 Desafios para Continuar:

  1. Explore sites diferentes: Teste scraping em diversos tipos de sites
  2. Crie sistemas de monitoramento: Desenvolva scrapers que rodam periodicamente
  3. Automatize tarefas: Use scraping para automatizar coleta de dados
  4. Contribua com projetos: Encontre projetos open source que precisam de dados

14.8.3 Próximo Capítulo:

No Capítulo 15, vamos aprender sobre Banco de Dados SQL com Python! Você vai descobrir como:

  • Trabalhar com bancos de dados SQLite
  • Executar comandos SQL básicos
  • Criar sistemas de persistência de dados
  • Implementar operações CRUD completas
  • Conectar Python com bancos de dados

🎯 batel.tech: Quer praticar mais? Acesse batel.tech e encontre projetos práticos para aplicar seus conhecimentos de web scraping! Lá você pode colaborar com outros desenvolvedores e construir sistemas incríveis de coleta de dados!


14.9 Referências Bibliográficas


Capítulo 14 concluído! 🎉 Agora você está pronto para extrair dados da web e criar sistemas de coleta de informações. No próximo capítulo, vamos aprender a organizar esses dados em bancos de dados!