Este artigo explora conceitos e técnicas de web scraping usando Python, abordando desde os fundamentos do protocolo HTTP até a aplicação prática de bibliotecas como Requests e BeautifulSoup4 (BS4).
Fundamentos do Protocolo HTTP para Web Scraping
A comunicação na web é baseada no protocolo HTTP. Uma requisição HTTP típica segue o formato:
GET /caminho/do/recurso HTTP/1.1\r\nHost: www.exemplo.com\r\n\r\n
Uma requisição POST para envio de dados no corpo segue este padrão:
POST /caminho/do/recurso HTTP/1.1\r\nHost: www.exemplo.com\r\n\r\ncampo1=valor1&campo2=valor2
É crucial entender que HTTP é sem estado, significando que cada requisição/resposta é independente, a menos que cookies ou sessões sejam gerenciados explicitamente. Os métodos de requisição comuns incluem GET, POST, PUT e DELETE.
Utilizando a Biblioteca Requests
A biblioteca requests simplifica a criação de requisições HTTP em Python.
Parâmetros Principais
url: O endereço do recurso.params: Parâmetros de query string.headers: Cabeçalhos HTTP customizados.cookies: Um dicionário de cookies.data: Dados para enviar no corpo de uma requisição POST, codificados como formulário.json: Dados para enviar no corpo como JSON.files: Para upload de arquivos.timeout: Tempo limite para a conexão.proxies: Dicionário para mapear protocolos a endereços de proxy.allow_redirects: Booleano para seguir redirecionamentos.
Gerenciamento de Sessões
A classe Session é útil para manter parâmetros persistentes, como cookies e cabeçalhos, entre múltiplas requisições.
import requests
# Cria uma instância de sessão para persistir cookies
minha_sessao = requests.Session()
# Acessa a página inicial
resposta_inicial = minha_sessao.get('https://site.com/pagina_inicial')
# Realiza login usando a mesma sessão
dados_login = {'usuario': 'meu_user', 'senha': 'minha_senha'}
minha_sessao.post('https://site.com/login', data=dados_login)
# Acessa uma página protegida após o login
resposta_protegida = minha_sessao.get('https://site.com/perfil')
print(resposta_protegida.text)
Análise de HTML com BeautifulSoup4 (BS4)
Após obter o conteúdo HTML de uma página, usamos o BeautifulSoup4 para analisá-lo e navegar pela árvore de sintaxe (DOM).
from bs4 import BeautifulSoup
# Supondo que 'html_content' é uma string contendo o HTML da página
soup = BeautifulSoup(html_content, 'html.parser')
# Encontrar um elemento por tag e atributos
elemento_login = soup.find('input', {'name': 'campo_login'})
# Obter o valor do atributo 'value' do elemento encontrado
valor_token = elemento_login.get('value')
# Encontrar todos os elementos com uma classe específica
todos_os_itens = soup.find_all('div', {'class': 'item'})
# Iterar e extrair texto
for item in todos_os_itens:
titulo = item.find('h2').text
print(titulo)
Exemplo Prático: Login Automatizado
Muitos sites possuem proteções como tokens CSRF. O processo de login automatizado geralmente envolve:
- Acessar a página de login para obter tokens escondidos nos campos ou cookies.
- Enviar os dados de credenciais junto com esses tokens.
- Gerenciar a cadeia de cookies para manter a autenticação.
Abaixo, um esqueleto ilustrando o fluxo:
import requests
from bs4 import BeautifulSoup
sessao = requests.Session()
# Passo 1: GET na página de login para obter o token CSRF
resp_login_page = sessao.get('https://site.com/login')
sopa = BeautifulSoup(resp_login_page.text, 'html.parser')
csrf_token = sopa.find('input', {'name': 'csrf_token'})['value']
# Passo 2: POST com credenciais e token
payload = {
'username': 'usuario',
'password': 'senha',
'csrf_token': csrf_token
}
resp_login = sessao.post('https://site.com/login', data=payload)
# Passo 3: Usar a sessão autenticada para acessar dados
if resp_login.ok:
resp_dados = sessao.get('https://site.com/dados_privados')
print(resp_dados.text)
Considerações Avançadas
- Redirecionamentos: Defina
allow_redirects=Falsepara inspecionar manualmente o cabeçalhoLocatione entender o fluxo. - Assinaturas e JavaScript: Alguns sites, como redes sociais, usam assinaturas complexas geradas por JavaScript (e.g.,
_bytedAcrawler). Nesses casos, pode ser necessário usar ferramentas como Selenium ou interpretar o código JS. - Proxies e User-Agent: Para evitar bloqueios, é comum rotacionar user-agents e usar proxies.
- Streaming: Para baixar arquivos grandes, use o parâmetro
stream=Truee itere sobre o conteúdo.
# Exemplo de download de arquivo em streaming
with sessao.get('https://site.com/video.mp4', stream=True) as resposta:
resposta.raise_for_status()
with open('video.mp4', 'wb') as arquivo:
for pedaco in resposta.iter_content(chunk_size=8192):
arquivo.write(pedaco)