Guia para usar cURL com Python

Comentários: 0

A raspagem da Web envolve a extração de dados de sites para tarefas como análise de dados, pesquisa e automação. Embora o Python ofereça bibliotecas para enviar solicitações HTTPS e realizar raspagem, usar o cURL via PycURL pode ser mais eficiente. Neste tutorial, demonstraremos como usar o Python cURL para raspar páginas da Web. Forneceremos exemplos e compararemos seu desempenho com outras bibliotecas populares, como Requests, HTTPX e AIOHTTP.

Introdução ao cURL e ao Python

Antes de mergulhar na integração com Python, é essencial entender os conceitos básicos do cURL. Pode utilizar comandos cURL diretamente no terminal para executar tarefas como fazer pedidos GET e POST.

Exemplo de comandos cURL:

# Pedido GET
curl -X GET "https://httpbin.org/get"

# Pedido POST
curl -X POST "https://httpbin.org/post"

1.png

2.png

Instalando as bibliotecas necessárias

Para usar o cURL em Python, precisamos da biblioteca pycurl, que fornece uma interface Python para a biblioteca cURL.

Instalando o PycURL:

pip install pycurl

Fazendo requisições HTTP com PycURL

O PycURL oferece um controlo detalhado sobre os pedidos HTTP em Python. Abaixo está um exemplo que demonstra como fazer uma solicitação GET com PycURL:

import pycurl
import certifi
from io import BytesIO

# Criar um objeto BytesIO para guardar os dados da resposta
buffer = BytesIO()

# Inicializar um objeto cURL
c = pycurl.Curl()

# Definir o URL para o pedido HTTP GET
c.setopt(c.URL, 'https://httpbin.org/get')

# Definir a memória intermédia para captar os dados de saída
c.setopt(c.WRITEDATA, buffer)

# Definir o caminho para o ficheiro do pacote CA para verificação SSL/TLS
c.setopt(c.CAINFO, certifi.where())

# Efetuar o pedido HTTP
c.perform()

# Fecha o objeto cURL para libertar recursos
c.close()

# Recuperar o conteúdo da resposta da memória intermédia
body = buffer.getvalue()

# Descodificar e imprimir o corpo da resposta
print(body.decode('iso-8859-1'))

Tratamento de pedidos POST

O envio de dados com solicitações POST é comum. Com o PycURL, use a opção POSTFIELDS. Aqui está um exemplo de como fazer uma solicitação POST com o PycURL:

import pycurl
import certifi
from io import BytesIO

# Criar um objeto BytesIO para guardar os dados da resposta
buffer = BytesIO()

# Inicializar um objeto cURL
c = pycurl.Curl()

# Definir o URL para o pedido HTTP POST
c.setopt(c.URL, 'https://httpbin.org/post')

# Definir os dados a lançar
post_data = 'param1="pycurl"¶m2=article'
c.setopt(c.POSTFIELDS, post_data)

# Definir a memória intermédia para captar os dados de saída
c.setopt(c.WRITEDATA, buffer)

# Definir o caminho para o ficheiro do pacote CA para verificação SSL/TLS
c.setopt(c.CAINFO, certifi.where())

# Efetuar o pedido HTTP
c.perform()

# Fecha o objeto cURL para libertar recursos
c.close()

# Recuperar o conteúdo da resposta da memória intermédia
body = buffer.getvalue()

# Descodificar e imprimir o corpo da resposta
print(body.decode('iso-8859-1'))

Tratando cabeçalhos HTTP personalizados

Cabeçalhos personalizados ou autenticação são frequentemente necessários com solicitações HTTP. Abaixo está um exemplo de configuração de cabeçalhos personalizados com o PycURL:

import pycurl
import certifi
from io import BytesIO

# Criar um objeto BytesIO para guardar os dados da resposta
buffer = BytesIO()

# Inicializar um objeto cURL
c = pycurl.Curl()

# Definir o URL para o pedido HTTP GET
c.setopt(c.URL, 'https://httpbin.org/get')

# Definir cabeçalhos HTTP personalizados
c.setopt(c.HTTPHEADER, ['User-Agent: MyApp', 'Accept: application/json'])

# Definir a memória intermédia para captar os dados de saída
c.setopt(c.WRITEDATA, buffer)

# Definir o caminho para o ficheiro do pacote CA para verificação SSL/TLS
c.setopt(c.CAINFO, certifi.where())

# Efetuar o pedido HTTP
c.perform()

# Fecha o objeto cURL para libertar recursos
c.close()

# Recuperar o conteúdo da resposta da memória intermédia
body = buffer.getvalue()

# Descodificar e imprimir o corpo da resposta
print(body.decode('iso-8859-1'))

Tratamento de respostas XML

Analisar e manipular respostas XML é crucial ao trabalhar com APIs. Abaixo está um exemplo de manipulação de respostas XML com PycURL:

# Importar as bibliotecas necessárias
import pycurl  # Biblioteca para efetuar pedidos HTTP
import certifi  # Biblioteca para verificação de certificados SSL
from io import BytesIO  # Biblioteca para lidar com fluxos de bytes
import xml.etree.ElementTree as ET  # Biblioteca para análise de XML

# Criar uma memória intermédia para guardar os dados da resposta
buffer = BytesIO()

# Inicializar um objeto cURL
c = pycurl.Curl()

# Definir o URL para o pedido HTTP GET
c.setopt(c.URL, 'https://www.google.com/sitemap.xml')

# Definir a memória intermédia para captar os dados de saída
c.setopt(c.WRITEDATA, buffer)

# Definir o caminho para o ficheiro do pacote CA para verificação SSL/TLS
c.setopt(c.CAINFO, certifi.where())

# Efetuar o pedido HTTP
c.perform()

# Fecha o objeto cURL para libertar recursos
c.close()

# Recuperar o conteúdo da resposta da memória intermédia
body = buffer.getvalue()

# Analisar o conteúdo XML num objeto ElementTree
root = ET.fromstring(body.decode('utf-8'))

# Imprime a etiqueta e os atributos do elemento de raiz da árvore XML
print(root.tag, root.attrib)

Tratamento de erros HTTP

O tratamento robusto de erros é essencial para fazer solicitações HTTP confiáveis. Abaixo está um exemplo de tratamento de erros com PycURL:

import pycurl  # Importar a biblioteca pycurl
import certifi  # Importar a biblioteca certifi
from io import BytesIO  # Importar BytesIO para lidar com fluxos de bytes

# Inicializar um objeto Curl
c = pycurl.Curl()

buffer = BytesIO()
# Definir o URL para o pedido HTTP
c.setopt(c.URL, 'http://example.com')
c.setopt(c.WRITEDATA, buffer)
c.setopt(c.CAINFO, certifi.where())

try:
    # Efetuar o pedido HTTP
    c.perform()
except pycurl.error as e:
    # Se ocorrer um erro durante o pedido, captura a exceção pycurl.error
    errno, errstr = e.args  # Recuperar o número e a mensagem de erro
    print(f'Error: {errstr} (errno {errno})')  # Imprimir a mensagem de erro e o número do erro
finally:
    # Close the Curl object to free up resources
    c.close()
    body = buffer.getvalue()
    print(body.decode('iso-8859-1'))  # Descodificar e imprimir o corpo da resposta

3.png

O código corrigido ajusta o URL para https://example.com, resolvendo o problema do protocolo. Repete o processo de configuração do pedido, executando-o e tratando os erros como no snippet inicial. Após a execução bem-sucedida, o corpo da resposta é novamente decodificado e impresso. Esses trechos destacam a importância da configuração correta da URL e do tratamento robusto de erros em solicitações HTTP com pycurl.

import pycurl  # Importar a biblioteca pycurl
import certifi  # Importar a biblioteca certifi
from io import BytesIO  # Importar BytesIO para lidar com fluxos de bytes

# Reinitialize the Curl object
c = pycurl.Curl()

buffer = BytesIO()
# Corrigir o URL para utilizar HTTPS
c.setopt(c.URL, 'https://example.com')
c.setopt(c.WRITEDATA, buffer)
c.setopt(c.CAINFO, certifi.where())

try:
    # Efetuar o pedido HTTP corrigido
    c.perform()
except pycurl.error as e:
    # Se ocorrer um erro durante o pedido, captura a exceção pycurl.error
    errno, errstr = e.args  # Recuperar o número e a mensagem de erro
    print(f'Error: {errstr} (errno {errno})')  # Imprimir a mensagem de erro e o número do erro
finally:
    # Fechar o objeto Curl para libertar recursos
    c.close()
    body = buffer.getvalue()
    print(body.decode('iso-8859-1'))  # Descodificar e imprimir o corpo da resposta

Funcionalidades cURL avançadas

O cURL fornece muitas opções avançadas para controlar o comportamento dos pedidos HTTP, como o tratamento de cookies e tempos limite. Abaixo está um exemplo que demonstra opções avançadas com PycURL.

import pycurl  # Importar a biblioteca pycurl
import certifi  # Importar a biblioteca certifi para verificação do certificado SSL
from io import BytesIO  # Importar BytesIO para lidar com fluxos de bytes

# Criar uma memória intermédia para guardar os dados da resposta
buffer = BytesIO()

# Inicializar um objeto Curl
c = pycurl.Curl()

# Definir o URL para o pedido HTTP
c.setopt(c.URL, 'http://httpbin.org/cookies')

# Ativar cookies definindo um par chave-valor específico
c.setopt(c.COOKIE, 'cookies_key=cookie_value')

# Definir um tempo limite de 30 segundos para o pedido
c.setopt(c.TIMEOUT, 30)

# Definir a memória intermédia para captar os dados de saída
c.setopt(c.WRITEDATA, buffer)

# Definir o caminho para o ficheiro do pacote CA para verificação SSL/TLS
c.setopt(c.CAINFO, certifi.where())

# Efetuar o pedido HTTP
c.perform()

# Fechar o objeto Curl para libertar recursos
c.close()

# Recuperar o conteúdo da resposta da memória intermédia
body = buffer.getvalue()

# Descodificar o corpo da resposta utilizando a codificação UTF-8 e imprimi-lo
print(body.decode('utf-8'))

Comparação de PycURL, Requests, HTTPX e AIOHTTP

Ao trabalhar com pedidos HTTP em Python, quatro bibliotecas populares são PycURL, Requests, HTTPX e AIOHTTP. Cada uma tem os seus pontos fortes e fracos. Aqui está uma comparação para o ajudar a escolher a ferramenta certa para as suas necessidades:

Caraterística PycURL Requests HTTPX AIOHTTP
Facilidade de utilização Moderado Muito fácil Fácil Moderado
Desempenho Elevado Moderado Elevado Elevado
Suporte assíncrono Não Não Sim Sim
Transmissão em fluxo contínuo Sim Limitada Sim Sim
Suporte de protocolo Extensivo (suporta muitos protocolos) HTTP/HTTPS HTTP/HTTPS, HTTP/2, WebSockets HTTP/HTTPS, WebSockets

A análise comparativa indica que o PycURL oferece um elevado desempenho e flexibilidade, tornando-o adequado para utilizadores avançados que necessitam de uma gestão detalhada dos pedidos HTTP. Por outro lado, o Requests e o HTTPX são mais adequados para cenários mais simples e intuitivos. O AIOHTTP se destaca no tratamento de tarefas assíncronas, fornecendo ferramentas eficazes para gerenciar solicitações assíncronas.

A escolha da biblioteca certa depende das necessidades e requisitos específicos do seu projeto, sendo o PycURL uma excelente opção para quem precisa de velocidade e recursos avançados.

Comentários:

0 Comentários