Os melhores clientes HTTP Python para extração de dados da web

Descubra os principais clientes HTTP do Python, seus recursos e os melhores casos de uso para extração de dados da web em 2024.
15 min read
Best Python HTTP Clients blog image

Clientes HTTP são bibliotecas Python úteis que permitem que seu código envie solicitações para servidores web ou APIs e receba respostas. Eles facilitam o envio de vários tipos de solicitações HTTP (GET, POST, PUT, DELETE etc.), a busca de dados, o envio de dados ou a execução de ações em sites ou APIs.

Quando se trata de web scraping, esses clientes geralmente são usados junto com bibliotecas de análise de HTML como Beautiful Soup ou html5lib.

Neste artigo, você verá alguns dos melhores clientes HTTP do Python, incluindo Requests, urllib3, Uplink, GRequests, HTTPX e aiohttp. Você avaliará cada um com base nos recursos oferecidos, facilidade de uso, documentação, suporte e popularidade. No final deste artigo, você terá uma ideia melhor de qual biblioteca é melhor para seu caso de uso.

Requests

Vamos começar com o cliente HTTP Python mais popular: a biblioteca Requests, com impressionantes 30 milhões de downloads por semana.

Aqui está um exemplo de como você pode lidar com solicitações e respostas HTTP com Requests:

import requests

print("Testing `requests` library...")
resp = requests.get('https://httpbin.org/get', params={"foo": "bar"})
if resp.status_code == 200:     # success
    print(f"Response Text: {resp.text} (HTTP-{resp.status_code})")
else:   # error
    print(f"Error: HTTP-{resp.status_code}")

Observe que httpbin.org fornece exemplos de respostas para testar vários métodos HTTP.

Neste trecho de código, o método requests.get(...) usa o URL desejado e um único parâmetro de consulta, foo. Você pode passar qualquer parâmetro de consulta usando o argumento params.

Com Requests e outros clientes HTTP, você não precisa adicionar manualmente strings de consulta aos seus URLs ou codificar seus dados; a biblioteca cuida disso para você. Para enviar dados JSON, você passa um dicionário Python usando o argumento data e pode receber a resposta JSON diretamente com resp.json().

A biblioteca Requests manipula automaticamente redirecionamentos em HTTP (3xx) por padrão, o que é útil na extração de dados da web para acessar conteúdo de URLs redirecionados. Ele também suporta conexões Secure Sockets Layer (SSL).

Nos bastidores, Requests usa urllib3 para gerenciar tarefas HTTP de baixo nível, como pool de conexões e verificação SSL, oferecendo uma API de alto nível e mais pythônica para desenvolvedores.

Além disso, Requests suporta gerenciamento de sessões, permitindo que você mantenha parâmetros, como cookies, cabeçalhos ou tokens de autenticação, em várias solicitações. Isso é particularmente útil para tarefas de extração de dados da web, nas quais manter esses parâmetros é essencial para acessar conteúdo restrito.

A biblioteca Requests também suporta streaming, o que é útil para tarefas de web scraping que envolvem grandes respostas, como baixar arquivos ou processar dados de streaming de APIs.

Para processar dados de resposta com eficiência sem carregar todos na memória, você pode usar métodos como iter_content() ou iter_lines():

import requests

print("Testing `requests` library with streaming...")
resp = requests.get('https://httpbin.org/stream/10', stream=True)
for chunk in resp.iter_content(chunk_size=1024):
    print(chunk.decode('utf-8'))

No entanto, a biblioteca Requests carece de recursos assíncronos integrados e suporte de cache embutido (embora esteja disponível via requests-cache). Além disso, Requests não suporta HTTP/2 e é improvável que seja adicionado em breve, conforme indicado nesta discussão.

Nota: HTTP/2 é a versão mais recente do protocolo HTTP, projetada para ser mais rápida e eficiente do que o HTTP/1.1. Esta versão permite várias solicitações e respostas em uma única conexão TCP (Transmission Control Protocol) por meio de multiplexação, resultando em conexões cliente-servidor reduzidas e carregamentos de página mais rápidos. No entanto, o suporte para HTTP/2 ainda é limitado.

A biblioteca Requests simplifica as interações HTTP do Python. Ela se destaca por seus métodos simples, sintaxe concisa, agrupamento automático de conexões para maior eficiência e decodificação JSON integrada. Sua facilidade de uso, gerenciamento de sessões, recursos de streaming e extensa documentação fazem dela uma escolha popular para desenvolvedores.

urllib3

urllib3 é uma biblioteca bem testada e amplamente usada para fazer solicitações HTTP — não apenas por desenvolvedores, mas também por muitos outros clientes HTTP. Oferece recursos úteis e opções de personalização para lidar com solicitações HTTP de baixo nível em extração de dados da web.

Aqui está um exemplo básico que usa urllib3 para fazer uma solicitação HTTP:

import urllib3

print("Testing `urllib3` library...")
http = urllib3.PoolManager()    # PoolManager for connection pooling
resp = http.request('GET', 'https://httpbin.org/get', fields={"foo": "bar"})

if resp.status == 200:     # success
    print(f"Response: {resp.data.decode('utf-8')} (HTTP-{resp.status})")
else:    # error
    print(f"Error: HTTP-{resp.status}")

Neste trecho de código, urllib3.PoolManager() cria um pool de conexões que pode ser reutilizado para várias solicitações, melhorando o desempenho ao evitar a sobrecarga de estabelecer novas conexões para cada solicitação. Junto com o URL, você pode passar os parâmetros de consulta necessários usando o argumento fields.

Um recurso notável do urllib3 é sua capacidade de lidar com respostas de streaming, permitindo que você processe grandes quantidades de dados com eficiência sem carregar tudo na memória. Isso é útil para baixar arquivos grandes ou consumir APIs de streaming durante a extração de dados da web.

urllib3 suporta redirecionamento automático por padrão e tem suporte SSL integrado. No entanto, ele carece de recursos assíncronos integrados, suporte de cache e gerenciamento de sessão (como cookies) e não oferece suporte a HTTP/2.

Embora o tratamento do pool de conexões pelo urllib3 o torne menos fácil de usar do que a biblioteca Requests, o urllib3 usa uma sintaxe de script simples, ao contrário de alguns clientes que exigem uma abordagem ou decoradores baseados em classes, tornando o urllib3 útil para interações HTTP básicas. Além disso, o urllib3 vem com uma documentação bem mantida.

Se você quer uma biblioteca poderosa e não precisa de gerenciamento de sessões, o urllib3 é ótimo para tarefas simples de web scraping.

Uplink

Uplink é um cliente HTTP Python poderoso, porém menos conhecido. Ele simplifica as interações com APIs RESTful usando interfaces baseadas em classes, tornando-o particularmente útil para extração de dados da web que envolve chamadas de API.

Dê uma olhada neste exemplo de código usando o Uplink para chamar um endpoint de API:

import uplink

@uplink.json
class JSONPlaceholderAPI(uplink.Consumer):
    @uplink.get("/posts/{post_id}")
    def get_post(self, post_id):
        pass


def demo_uplink():
    print("Testing `uplink` library...")
    api = JSONPlaceholderAPI(base_url="https://jsonplaceholder.typicode.com")
    resp = api.get_post(post_id=1)
    if resp.status_code == 200:     # success
        print(f"Response: {resp.json()} (HTTP-{resp.status_code})")
    else:   # error
        print(f"Error:HTTP-{resp.status_code}")

Esse trecho de código define uma classe JSONPlaceholderAPI que herda de uplink.Consumer. Ele usa o decorador @uplink.get para criar uma solicitação HTTP GET para a API JSONPlaceholder para recuperar uma publicação específica. O parâmetro post_id é incluído dinamicamente no endpoint com este decorador: @uplink.get(“/posts/{post_id}”). O site https://jsonplaceholder.typicode.com simula uma API REST, fornecendo respostas JSON para testes e desenvolvimento.

O Uplink suporta SSL e gerencia automaticamente os redirecionamentos para obter a resposta final. Ele também oferece recursos avançados, como trazer sua própria biblioteca HTTP.

No entanto, o Uplink não tem suporte integrado para respostas de streaming, solicitações assíncronas, armazenamento em cache (embora possa usar requests-cache) e HTTP/2.

O Uplink fornece documentação adequada para seus recursos poderosos, mas não é mantido ativamente (a última versão foi 0.9.7 em março de 2022) e não é muito popular. Embora sua abordagem baseada em classes e sintaxe de decorador possam atrair desenvolvedores orientados a objetos, ela oferece apenas facilidade moderada de uso para aqueles que preferem o estilo de script do Python.

Os usuários geralmente escolhem o Uplink quando precisam coletar dados principalmente de diferentes endpoints da API RESTful e não de páginas HTML.

GRequests

GRequests é uma extensão da conhecida biblioteca Requests, com a adição de suporte para solicitações assíncronas. Ele permite a busca simultânea de dados de vários sites ou APIs.

Ao contrário das solicitações sequenciais, que esperam por cada resposta antes de enviar a próxima, o GRequests melhora a eficiência enviando solicitações simultaneamente. Isso é especialmente benéfico para buscar dados de vários sites ou APIs.

Dê uma olhada neste exemplo:

import grequests

print("Testing `grequests` library...")
# Fetching data from multiple URLs
urls = [
    'https://www.python.org/',
    'http://httpbin.org/get',
    'http://httpbin.org/ip',
]

responses = grequests.map((grequests.get(url) for url in urls))
for resp in responses:
    print(f"Response for: {resp.url} ==> HTTP-{resp.status_code}")

Nesse código, o GRequests envia simultaneamente três solicitações GET usando grequests.map(...) para diferentes URLs e reúne as respostas em uma lista chamada responses. Em seguida, ele repete essas respostas para registrá-las. Internamente, o GRequests usa gevent, uma biblioteca de rede baseada em corrotinas, para solicitações HTTP assíncronas. Isso permite que você envie várias solicitações HTTP simultaneamente sem gerenciar a simultaneidade complexa. Uma aplicação prática disso pode ser coletar notícias de sites diferentes sobre um determinado tópico ou categoria.

GRequests também oferece suporte a recursos como tratamento automático de redirecionamentos, suporte a SSL e processamento de respostas de streaming sem carregá-las todas na memória de uma só vez. No entanto, lembre-se de que o GRequests não tem suporte integrado para HTTP/2 ou recursos de cache, embora possa usar requests-cache.

GRequests simplifica solicitações HTTP assíncronas com métodos intuitivos semelhantes à sua biblioteca base, Requests. Ele elimina a necessidade de construções complexas async/await para lidar com a simultaneidade, facilitando o uso. No entanto, sua documentação é mínima devido à sua pequena base de código (213 linhas na versão 0.7.0) e à redução da atividade de desenvolvimento. Esses fatores contribuem para sua baixa popularidade.

Você deve considerar o GRequests por seus recursos assíncronos fáceis de usar quando precisar coletar dados de várias fontes simultaneamente.

HTTPX

HTTPX é um cliente HTTP moderno e rico em recursos para Python, amplamente usado para todos os tipos de projetos de web scraping. Ele foi projetado para substituir a biblioteca Requests do Python e, ao mesmo tempo, fornecer suporte assíncrono e melhor desempenho.

O exemplo a seguir demonstra uma solicitação HTTP GET assíncrona usando HTTPX:

import httpx
import asyncio

async def fetch_posts():
    async with httpx.AsyncClient() as client:
        response = await client.get('https://jsonplaceholder.typicode.com/posts')
        return response.json()

async def httpx_demo():
    print("Testing `httpx` library...")
    posts = await fetch_posts()
    for idx, post in enumerate(posts):
        print(f"Post #{idx+1}: {post['title']}")

# async entry point to execute the code
asyncio.run(httpx_demo())

Esse código define uma função assíncrona chamada fetch_posts(), que recupera publicações fictícias de blog da API https://jsonplaceholder.typicode.com/posts usando httpx.AsyncClient(). Outra função assíncrona, httpx_demo(), espera que fetch_posts() retorne essas publicações e depois gera seus títulos em um loop. Finalmente, asyncio.run(httpx_demo()) serve como ponto de entrada para executar httpx_demo() de forma assíncrona.

Além de seu suporte integrado para clientes HTTP assíncronos, o HTTPX também oferece suporte integrado a HTTP/2. Isso permite um carregamento mais rápido de vários recursos simultaneamente em uma única conexão TCP, tornando mais difícil para os sites rastrearem a impressão digital do navegador durante a extração de dados da web.

Para enviar uma solicitação HTTP/2, basta definir o parâmetro http2=True ao criar um cliente HTTPX:

import httpx

client = httpx.Client(http2=True)
response = client.get("https://http2.github.io/")
print(response)

Lembre-se de que, para usar HTTP/2, você precisa instalar o HTTPX com seu suporte a http2:

pip install httpx[http2]

Além disso, o HTTPX fornece excelente suporte para respostas de streaming, permitindo que você gerencie com eficiência grandes respostas ou fluxos de dados sem carregar a resposta inteira na memória.

Aqui está um exemplo de streaming de resposta de texto usando HTTPX:

with httpx.stream("GET", "https://httpbin.org/stream/10") as resp:
   for text in resp.iter_text():
       print(text)

Embora o HTTPX não inclua recursos de cache integrados, você pode usar Hishel no lugar.

HTTPX não segue redirecionamentos HTTP por padrão, mas você pode habilitar isso com o parâmetro follow_redirects:

import httpx

# test http --> https redirect
response = httpx.get('http://github.com/', follow_redirects=True)

Embora seus recursos assíncronos adicionem alguma complexidade, o HTTPX fornece métodos simples para comunicação HTTP e suporta solicitações síncronas fáceis de usar. Isso o torna acessível tanto para iniciantes quanto para desenvolvedores experientes. Além disso, seu uso está crescendo, graças à sua extensa documentação  e a uma comunidade ativa de desenvolvedores que criam ferramentas para integração com HTTPX.

Se você está procurando um cliente HTTP assíncrono e rico em recursos, considere o HTTPX.

aiohttp

Semelhante ao HTTPX, aiohttp oferece suporte assíncrono integrado para solicitações HTTP. No entanto, o aiohttp foi projetado exclusivamente para programação assíncrona, permitindo que ele se destaque em cenários que exigem solicitações simultâneas e sem bloqueio. Isso o torna adequado para projetos de extração de dados da web de alto desempenho e é fácil de usar com proxies.

Veja como você pode usar aiohttp para coletar vários URLs simultaneamente:

import asyncio
import aiohttp

async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()    

async def demo_aiohttp():
    print("Testing `aiohttp` library...")
    urls = [
        'https://www.python.org/',
        'http://httpbin.org/get',
        'http://httpbin.org/ip',
    ]
    tasks = [fetch_data(url) for url in urls]
    responses = await asyncio.gather(*tasks)
    for resp_text in responses:
        print(f"Response: {resp_text}")

# async entry point to execute the code      
asyncio.run(demo_aiohttp())

A função assíncrona fetch_data(...) cria um aiohttp.ClientSession() e envia uma solicitação GET para o URL especificado. Em seguida, ele cria uma lista de tarefas para cada URL e as executa simultaneamente com asyncio.gather(...). Depois que todas as tarefas forem concluídas, os dados coletados (nesse caso, o texto da resposta) são coletados e impressos. A execução real é iniciada com asyncio.run(demo_aiohttp()).

aiohttp gerencia automaticamente redirecionamentos HTTP e suporta respostas de streaming, garantindo o gerenciamento eficiente de arquivos grandes ou fluxos de dados sem uso excessivo de memória. Ele também oferece flexibilidade com uma ampla variedade de middleware e extensões de terceiros.

Além disso, aiohttp pode servir como servidor de desenvolvimento se necessário, embora este artigo se concentre exclusivamente em sua funcionalidade de cliente HTTP.

No entanto, aiohttp não tem suporte para HTTP/2 e recursos de cache integrados. No entanto, você pode integrar o cache usando bibliotecas como aiohttp-client-cache quando necessário.

aiohttp pode ser mais complexo de usar do que clientes HTTP mais simples, como Requests, especialmente para iniciantes. Sua natureza assíncrona e seus recursos adicionais exigem uma boa compreensão da programação assíncrona em Python. No entanto, é bastante popular, com 14,7 mil estrelas no GitHub e várias bibliotecas de terceiros construídas sobre ele. O aiohttp também oferece uma documentação abrangente para desenvolvedores.

Se você está procurando suporte assíncrono completo, considere aiohttp. Seu desempenho assíncrono o torna ideal para tarefas de coleta de dados em tempo real, como monitorar os preços de ações ou acompanhar eventos ao vivo, como eleições, à medida que se desenrolam.

Confira a tabela a seguir para uma visão geral rápida dos principais clientes HTTP do Python:

Requests urllib3 Uplink GRequests HTTPX aiohttp
Facilidade de uso Fácil Fácil a moderado Moderado Fácil Moderado Moderado
Redirecionamentos automáticos Sim Sim Sim Sim Precisa ser ativado Sim
Suporte a SSL Sim Sim Sim Sim Sim Sim
Capacidade assíncrona Não Não Não Sim Sim Sim
Respostas de streaming Sim Sim Não Sim Sim Sim
Suporte HTTP/2 Não Não Não Não Sim Não
Suporte de cache Via: requests-cache Não Via:requests-cache Via:requests-cache Via: Hishel Via: aiohttp-client-cache

Conclusão

Neste artigo, você aprendeu tudo sobre alguns clientes HTTP populares do Python, incluindo Requests, urllib3, Uplink, GRequests, HTTPX e aiohttp, cada um com recursos exclusivos como simplicidade, suporte assíncrono, streaming e HTTP/2.

Embora Requests, Uplink e GRequests sejam conhecidos por sua simplicidade, aiohttp e HTTPX oferecem recursos assíncronos poderosos. Embora Requests continue sendo a mais popular, aiohttp e HTTPX estão ganhando força devido às suas habilidades assíncronas. Por fim, você precisará analisar cada um para escolher aquele que atenda às suas necessidades.

Quando se trata de extração de dados da web na vida real, você precisará considerar mais do que apenas seu cliente HTTP, como contornar medidas anti-bot e usar proxies. Felizmente, a Bright Data pode ajudar.

A Bright Data facilita a extração de dados da web com ferramentas como o Web Scraper IDE, que oferece funções e modelos JavaScript prontos, e o Web Unlocker, que contorna CAPTCHAs e medidas anti-bot. O Scraping Browser da Bright Data se integra com Puppeteer, Playwright e Selenium para coleta de dados em várias etapas. Além disso, as redes proxy e serviços da Bright Data permitem o acesso a partir de diferentes locais. Essas ferramentas lidam com tarefas complexas, como gerenciar proxies e resolver CAPTCHAs, para que você possa se concentrar em obter os dados de que precisa.

Comece seu teste gratuito hoje e experimente tudo o que a Bright Data tem a oferecer.

Não é necessário cartão de crédito