Quais são as diferenças entre o urllib, urllib2, urllib3 e o módulo de solicitações?

751

Em Python, quais são as diferenças entre os urllib, urllib2, urllib3e requestsmódulos? Por que existem três? Eles parecem fazer a mesma coisa ...

Paul Biggar
fonte
77
Pedidos é o melhor.
Yarin
2
Sim, use solicitações. stackoverflow.com/questions/22676/…
hughdbrown
75
solicitações usa urllib3 .. 3 é um número maior
Bro
2
resumo: use a requestsmaior parte do tempo. às vezes urllib2funciona, mas requer mais código e é menos elegante. não use urllib.
Trevor Boyd Smith
10
Esta pergunta deve ser atualizada para esclarecer que urllibno Python 3 existe outra opção, limpa de várias maneiras. Mas, felizmente, a documentação oficial também observa que " O pacote de solicitações é recomendado para uma interface de cliente HTTP de nível superior " na 21.6. urllib.request - Biblioteca extensível para abrir URLs - documentação do Python 3.6.3
nealmcb 15/17

Respostas:

714

Eu sei que já foi dito, mas eu recomendo o requestspacote Python.

Se você já usou outras linguagens além do python, provavelmente está pensando urllibe urllib2é fácil de usar, sem muito código e altamente capaz, é assim que eu pensava. Mas o requestspacote é tão incrivelmente útil e curto que todos deveriam usá-lo.

Primeiro, ele suporta uma API totalmente tranquila e é tão fácil quanto:

import requests

resp = requests.get('http://www.mywebsite.com/user')
resp = requests.post('http://www.mywebsite.com/user')
resp = requests.put('http://www.mywebsite.com/user/put')
resp = requests.delete('http://www.mywebsite.com/user/delete')

Independentemente de se GET / POST, você nunca precisa codificar parâmetros novamente, basta usar um dicionário como argumento e é bom:

userdata = {"firstname": "John", "lastname": "Doe", "password": "jdoe123"}
resp = requests.post('http://www.mywebsite.com/user', data=userdata)

Além disso, ele ainda possui um decodificador JSON interno (novamente, eu sei que json.loads()não há muito mais para escrever, mas isso com certeza é conveniente):

resp.json()

Ou, se seus dados de resposta forem apenas texto, use:

resp.text

Esta é apenas a ponta do iceberg. Esta é a lista de recursos do site de solicitações:

  • Domínios e URLs internacionais
  • Pool de manutenção e conexão
  • Sessões com persistência de cookie
  • Verificação SSL no estilo do navegador
  • Autenticação Básica / Digest
  • Cookies elegantes de chave / valor
  • Descompressão automática
  • Corpos de resposta Unicode
  • Uploads de arquivos com várias partes
  • Tempo limite de conexão
  • Suporte .netrc
  • Item da lista
  • Python 2.6—3.4
  • Discussão segura.
Hutch
fonte
32
Eu escolhi isso como a resposta, porque a resposta original ficou obsoleta. Então, se você está se perguntando por que essa resposta está à frente de uma resposta com 76 votos positivos, é porque Requests é a nova maneira padrão de fazer as coisas.
Paul Biggar 11/02
132
@PaulBiggar, você diz que esta é a melhor resposta. Mas isso realmente não responde à pergunta. Eu vim aqui para descobrir as diferenças entre urllib e urllib2. Especialmente sobre os recursos de codificação de URL. A resposta: use solicitações! ;) Apenas dizendo que você pode esclarecer a questão. Tal como está, a resposta de Crast realmente responde à pergunta perfeitamente.
Exhuma 30/10
2
Seria útil observar que a documentação do Python 3 possui outra biblioteca distinta urllibe que também documenta oficialmente que " O pacote de solicitações é recomendado para uma interface de cliente HTTP de nível superior " na seção 21.6. urllib.request - Biblioteca extensível para abrir URLs - documentação do Python 3.6.3 , e urllib3é uma ótima biblioteca usada por requests.
Nellmcb 15/10
Ok, exceto que eu tenho o pedido de impressão que não tem substituto paraurllib.parse()
Bob Stein
aceita. com @PaulBiggar - os pedidos parecem ser a maneira de fato. Na verdade, cheguei aqui com base no fato de que o urllib (e outras versões) não funciona ou é subótimo em comparação com os pedidos.
DL
205

O urllib2 fornece algumas funcionalidades extras, ou seja, a urlopen()função pode permitir que você especifique cabeçalhos (normalmente você precisaria usar o updplib no passado, o que é muito mais detalhado.) Mais importante ainda, o urllib2 fornece a Requestclasse, o que permite mais abordagem declarativa para fazer uma solicitação:

r = Request(url='http://www.mysite.com')
r.add_header('User-Agent', 'awesome fetcher')
r.add_data(urllib.urlencode({'foo': 'bar'})
response = urlopen(r)

Observe que urlencode()está apenas no urllib, não no urllib2.

Também existem manipuladores para implementar o suporte a URL mais avançado no urllib2. A resposta curta é que, a menos que você esteja trabalhando com código legado, provavelmente desejará usar o abridor de URL do urllib2, mas ainda precisará importar para o urllib algumas das funções do utilitário.

Resposta bônus Com o Google App Engine, você pode usar qualquer um dettttplib, urllib ou urllib2, mas todos são apenas invólucros para a API de busca de URL do Google. Ou seja, você ainda está sujeito às mesmas limitações, como portas, protocolos e a duração da resposta permitida. Você pode usar o núcleo das bibliotecas como seria de esperar para recuperar URLs HTTP.

Crast
fonte
1
Como alguém cria um URL com uma string de consulta codificada usando urllib2? É o único motivo pelo qual estou usando o urllib e gostaria de ter certeza de que estou fazendo tudo da melhor maneira possível.
Gattster 7/01/10
2
Como no exemplo acima, você usa urlopen()e Requestdo urllib2 e urlencode()do urllib . Não há nenhum dano real no uso das duas bibliotecas, desde que você use o urlopen correto. Os [urllib docs] [1] são claros quanto ao uso aceito. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast
Eu usei essa essência para urllib2.urlopen; contém outras variações também.
Andrei-Niculae Petre
urllib2 não suporta colocar ou apagar o que é uma dor
FKL
2
requeststambém permitem que os cabeçalhos personalizados: docs.python-requests.org/en/master/user/quickstart/...
Omer Dagan
46

urllib e urllib2 são dois módulos Python que solicitam URLs relacionados a itens, mas oferecem funcionalidades diferentes.

1) urllib2 pode aceitar um objeto Request para definir os cabeçalhos para uma solicitação de URL, urllib aceita apenas uma URL.

2) urllib fornece o método urlencode que é usado para a geração de strings de consulta GET, urllib2 não possui essa função. Esse é um dos motivos pelos quais o urllib é frequentemente usado junto com o urllib2.

Requests - Requests 'é uma biblioteca HTTP simples e fácil de usar, escrita em Python.

1) O Python Requests codifica os parâmetros automaticamente, para que você os transmita como argumentos simples, ao contrário do caso do urllib, onde você precisa usar o método urllib.encode () para codificar os parâmetros antes de passá-los.

2) Decodificou automaticamente a resposta em Unicode.

3) As solicitações também têm um tratamento de erro muito mais conveniente. Se sua autenticação falhar, o urllib2 gerará um urllib2.URLError, enquanto as solicitações retornarão um objeto de resposta normal, conforme o esperado. Tudo o que você precisa para ver se a solicitação foi bem-sucedida por resposta booleana.ok

Siyaram Malav
fonte
10
e quanto a urllib3?
PirateApp
1
As solicitações do @PirateApp são construídas sobre o urllib3 . Eu acho que o código usando o urllib3 diretamente pode ser mais eficiente, porque permite reutilizar a sessão, enquanto os pedidos (pelo menos os pedidos 2, aquele que todos usam) criam um para cada solicitação, mas não me cite. Nenhum dos dois faz parte da biblioteca padrão ( ainda )
Boris
12

Uma diferença considerável é sobre a portabilidade do Python2 para o Python3. O urllib2 não existe para python3 e seus métodos portados para urllib. Portanto, você está usando muito isso e deseja migrar para o Python3 no futuro, considere usar o urllib. No entanto, a ferramenta 2to3 fará automaticamente a maior parte do trabalho para você.

Arash
fonte
12

Apenas para adicionar às respostas existentes, não vejo ninguém mencionando que solicitações de python não são uma biblioteca nativa. Se você concorda em adicionar dependências, as solicitações são aceitáveis. No entanto, se você estiver tentando evitar adicionar dependências, o urllib é uma biblioteca python nativa que já está disponível para você.

Zeitgeist
fonte
11

Gosto da urllib.urlencodefunção e ela não parece existir urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
Gattster
fonte
4
Apenas uma observação, tenha cuidado com o urlencode, pois ele não pode manipular objetos <unicode> diretamente - você deve codificá-los antes de enviá-los ao urlencode (u'blá'.encode ('utf-8') ou qualquer outra coisa).
@ user18015: Eu não acho que isso se aplica ao Python 3, você pode esclarecer?
Janus Troelsen
Como observei acima, esta pergunta e as várias respostas devem ser atualizadas para esclarecer que urllibno Python 3 há outra opção, limpa de várias maneiras. Mas, felizmente, a documentação oficial também observa que " O pacote de solicitações é recomendado para uma interface de cliente HTTP de nível superior " na seção 21.6. urllib.request - Biblioteca extensível para abrir URLs - documentação do Python 3.6.3
nealmcb 15/17
O urllib2 não existe em Python 3
Boris
7

Para obter o conteúdo de um URL:

try: # Try importing requests first.
    import requests
except ImportError: 
    try: # Try importing Python3 urllib
        import urllib.request
    except AttributeError: # Now importing Python2 urllib
        import urllib


def get_content(url):
    try:  # Using requests.
        return requests.get(url).content # Returns requests.models.Response.
    except NameError:  
        try: # Using Python3 urllib.
            with urllib.request.urlopen(index_url) as response:
                return response.read() # Returns http.client.HTTPResponse.
        except AttributeError: # Using Python3 urllib.
            return urllib.urlopen(url).read() # Returns an instance.

É difícil escrever o código Python2 e Python3 e requestdependências para as respostas porque elas urlopen()funcionam e requests.get()retornam tipos diferentes:

  • Python2 urllib.request.urlopen()retorna umhttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)retorna uminstance
  • A solicitação request.get(url)retorna umrequests.models.Response
alvas
fonte
5

Você geralmente deve usar o urllib2, pois isso facilita um pouco as coisas ao aceitar objetos Request e também gera uma exceção URLException em erros de protocolo. No entanto, com o Google App Engine, você também não pode usar. Você precisa usar a API de busca de URL fornecida pelo Google em seu ambiente Python em área restrita.

Chinmay Kanchi
fonte
2
O que você disse sobre o appengine não é inteiramente verdade. Na verdade, você pode usar o enableplib, urllib e urllib2 no App Engine agora (são wrappers para busca de url, feitos para que mais código seja compatível com o appengine).
Crast
Ah, deve ser novo. Meu código falhou última vez que tentou e teve que ser reescrito para trabalhar com buscar ...
Chinmay Kanchi
O urllib2 não existe em Python 3
Boris
@Boris Ele migrou para urllib.request e urllib.error .
Alan
1

Um ponto-chave que acho que falta nas respostas acima é que urllib retorna um objeto do tipo <class http.client.HTTPResponse>enquanto requestsretorna <class 'requests.models.Response'>.

Devido a isso, o método read () pode ser usado com urllibmas não com requests.

PS: requestsjá é rico em tantos métodos que dificilmente precisa de mais um read();

paradoxlover
fonte