Introdução ao Web Scraping com Python
O Web Scraping, também conhecido como raspagem de dados, é uma técnica utilizada para extrair informações de websites de forma automatizada. Essencialmente, um programa de web scraping simula a interação de um usuário com um navegador para acessar páginas da web e coletar os dados exibidos. Este guia demonstra como realizar web scraping utilizando Python para coletar dados de filmes.
Bibliotecas Essenciais
Para implementar um coletor de dados em Python, as seguintes bibliotecas são comumente utilizadas:
urllib.requesteurllib.error: Módulos nativos do Python para fazer requisições HTTP a URLs e lidar com possíveis erros de conexão ou resposta.BeautifulSoup4(bs4): Uma biblioteca poderosa para analisar documentos HTML e XML. Ela cria uma árvore de elementos a partir do HTML, fcailitando a navegação e a busca por informações específicas.re: O módulo de expressões regulares do Python, crucial para encontrar padrões de texto e extrair dados de forma precisa do conteúdo HTML.xlwt: Uma biblioteca para ecsrever dados em arquivos Microsoft Excel no formato.xls.tqdm(opcional): Fornece uma maneira fácil de adicionar barras de progresso iteráveis, útil para visualizar o andamento de operações demoradas.
Processo de Coleta de Dados
O processo de web scraping geralmente envolve três etapas principais:
- Obter o conteúdo HTML da página web.
- Analisar o HTML e extrair os dados desejados.
- Salvar os dados extraídos em um formato estruturado.
1. Obtenção do Conteúdo HTML da Página
O primeiro passo é enviar uma requisição HTTP para a URL do site-alvo e obter o código-fonte HTML. É importante configurar um cabeçalho User-Agent na requisição para simular um navegador real, evitando que o servidor identifique a requisição como automatizada e a bloqueie.
import urllib.request, urllib.error
def obter_conteudo_pagina(url_alvo: str) -> str:
"""
Realiza uma requisição HTTP para a URL fornecida e retorna o conteúdo HTML.
Simula um navegador para evitar bloqueios e gerencia erros.
"""
cabecalhos_http = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36"
}
requisicao = urllib.request.Request(url_alvo, headers=cabecalhos_http)
conteudo_html = ""
try:
with urllib.request.urlopen(requisicao) as resposta:
conteudo_html = resposta.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(f"Erro HTTP: {e.code}")
if hasattr(e, "reason"):
print(f"Razão do erro: {e.reason}")
return conteudo_html
A função obter_conteudo_pagina cria uma requisição com um User-Agent e tenta abrir a URL. Em caso de sucesso, ela lê e decodifica o conteúdo para UTF-8. O bloco try-except captura exceções de URLError, imprimindo o código ou a razão do erro, se disponíveis.
2. Análise e Extração de Dados
Uma vez que o conteúdo HTML é obtido, a biblioteca BeautifulSoup é utilizada para criar um objeto "sopa" (soup) que representa a estrutura do HTML. Em seguida, expressões regulares são empregadas para localizar e extrair informações específicas, como títulos de filmes, links de detalhes, URLs de imagens, notas e comentários.
from bs4 import BeautifulSoup
import re
from tqdm import trange
# Expressões regulares pré-compiladas para otimização e clareza
padrao_link_filme = re.compile(r'<a href="(.*?)"')
padrao_imagem_capa = re.compile(r'<img[^>]+src=["\']([^"\']+)["\']')
padrao_titulo_filme = re.compile(r'<span class="title">(.*?)</span>')
padrao_nota_filme = re.compile(r'<span class="rating_num" property="v:average">(.*?)</span>')
padrao_citacao_filme = re.compile(r'<span class="inq">(.*?)</span>')
def extrair_dados_douban(url_base: str, total_paginas: int = 10) -> list:
"""
Percorre as páginas do Douban Top 250, extrai informações dos filmes
e as retorna em uma lista de listas.
"""
lista_registros_filmes = []
# Cada página contém 25 filmes; total_paginas * 25 filmes serão processados
for indice_pagina in trange(total_paginas, desc="Coletando páginas"):
url_pagina = f"{url_base}{indice_pagina * 25}"
conteudo_html = obter_conteudo_pagina(url_pagina)
sopa = BeautifulSoup(conteudo_html, "html.parser")
# Encontra todos os elementos div com a classe "item" que contêm os dados de cada filme
for elemento_filme in sopa.find_all('div', class_="item"):
# Converte o elemento BeautifulSoup para string para aplicar regex
elemento_str = str(elemento_filme)
dados_filme_atual = []
# Extração do título do filme
titulos = re.findall(padrao_titulo_filme, elemento_str)
dados_filme_atual.append(titulos[0].strip() if titulos else "N/A")
# Extração do link de detalhes do filme
links = re.findall(padrao_link_filme, elemento_str)
dados_filme_atual.append(links[0].strip() if links else "N/A")
# Extração do link da imagem da capa
imagens = re.findall(padrao_imagem_capa, elemento_str)
dados_filme_atual.append(imagens[0].strip() if imagens else "N/A")
# Extração da nota de avaliação
notas = re.findall(padrao_nota_filme, elemento_str)
dados_filme_atual.append(notas[0].strip() if notas else "N/A")
# Extração da citação/comentário breve
citacoes = re.findall(padrao_citacao_filme, elemento_str)
if citacoes:
# Remove o caractere "。" (ponto final chinês) e espaços
dados_filme_atual.append(citacoes[0].strip().replace("。", ""))
else:
dados_filme_atual.append("") # Mantém o campo vazio se não houver citação
lista_registros_filmes.append(dados_filme_atual)
return lista_registros_filmes
Na função extrair_dados_douban, um loop itera sobre as páginas, construindo a URL de cada uma. Para cada página, o HTML é obtido e transformado em um objeto BeautifulSoup. Em seguida, ele localiza todos os divs com a classe "item", que correspondem a cada entrada de filme. Dentro de cada "item", expressões regulares são usadas para extrair os pedaços de informação desejados. Os resultados são organizados em uma lista de listas.
3. Salvando os Dados em um Arquivo Excel
Após a coleta e extração, os dados precisam ser armazenados de forma organizada. A biblioteca xlwt permite criar um novo arquivo Excel e preenchê-lo com os dados coletados. Os dados são escritos linha por linha, incluindo um cabeçalho para identificar cada coluna.
import xlwt
def salvar_dados_excel(dados_para_salvar: list, caminho_arquivo: str):
"""
Salva uma lista de dados em um arquivo Excel (.xls).
"""
caderno_excel = xlwt.Workbook(encoding="utf-8", style_compression=0)
planilha = caderno_excel.add_sheet('Filmes_Top250', cell_overwrite_ok=True)
# Define os nomes das colunas (cabeçalhos)
colunas = ('Título do Filme', 'Link de Detalhes', 'Link da Imagem', 'Nota', 'Citação Popular')
for i, nome_coluna in enumerate(colunas):
planilha.write(0, i, nome_coluna) # Escreve os cabeçalhos na primeira linha
# Escreve os dados dos filmes a partir da segunda linha
for i, linha_dados in enumerate(dados_para_salvar):
for j, valor_celula in enumerate(linha_dados):
planilha.write(i + 1, j, valor_celula)
caderno_excel.save(caminho_arquivo)
A função salvar_dados_excel cria um novo caderno e uma planilha. Ela escreve os nomes das colunas na primeira linha e, em seguida, itera sobre a lista de dados coletados, escrevendo cada item em uma célula correspondente. Finalmente, o arquivo Excel é salvo no caminho especificado.
Execução Principal
O ponto de entrada do script coordena as chamadas para as funções de coleta e salvamento de dados.
def main():
url_base_douban = "https://movie.douban.com/top250?start="
print("Iniciando a coleta de dados...")
dados_filmes_coletados = extrair_dados_douban(url_base_douban)
caminho_salvamento = "douban_top250_filmes.xls"
salvar_dados_excel(dados_filmes_coletados, caminho_salvamento)
print(f"Coleta e salvamento concluídos. Dados guardados em: {caminho_salvamento}")
if __name__ == "__main__":
main()