Quelles sont les différences entre le module urllib, urllib2, urllib3 et les requêtes?

751

En Python, quelles sont les différences entre les urllib, urllib2, urllib3et requestsmodules? Pourquoi y en a-t-il trois? Ils semblent faire la même chose ...

Paul Biggar
la source
78
Les demandes sont les meilleures.
Yarin
2
Oui, utilisez les demandes. stackoverflow.com/questions/22676/…
hughdbrown
76
demandes utilise urllib3 .. 3 est un plus grand nombre
Bro
2
résumé: utiliser la requestsplupart du temps. urllib2fonctionne parfois mais nécessite plus de code et est moins élégant. ne pas utiliser urllib.
Trevor Boyd Smith
10
Cette question devrait être mise à jour pour clarifier qu'en urllibPython 3 est encore une autre option, nettoyée de diverses manières. Mais heureusement, la documentation officielle note également que " Le package Requests est recommandé pour une interface client HTTP de niveau supérieur. " À 21.6. urllib.request - Bibliothèque extensible pour ouvrir des URL - Documentation Python 3.6.3
nealmcb

Réponses:

714

Je sais que cela a déjà été dit, mais je recommande fortement le requestspackage Python.

Si vous avez utilisé des langages autres que python, vous pensez probablement urllibet urllib2êtes facile à utiliser, pas beaucoup de code et très performant, c'est comme ça que je pensais. Mais le requestspaquet est si incroyablement utile et court que tout le monde devrait l'utiliser.

Tout d'abord, il prend en charge une API entièrement reposante et est aussi simple que:

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')

Peu importe si GET / POST, vous n'avez plus jamais à encoder de paramètres, il prend simplement un dictionnaire comme argument et c'est bon à utiliser:

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

De plus, il a même un décodeur JSON intégré (encore une fois, je sais que ce json.loads()n'est pas beaucoup plus à écrire, mais cela est certainement pratique):

resp.json()

Ou si vos données de réponse ne sont que du texte, utilisez:

resp.text

Ce n'est que la pointe de l'iceberg. Voici la liste des fonctionnalités du site de requêtes:

  • Domaines internationaux et URL
  • Maintien en vie et mise en commun des connexions
  • Sessions avec persistance des cookies
  • Vérification SSL de type navigateur
  • Authentification de base / Digest
  • Cookies clés / valeur élégants
  • Décompression automatique
  • Organes de réponse Unicode
  • Téléchargements de fichiers en plusieurs parties
  • Délais de connexion
  • Prise en charge de .netrc
  • Élément de liste
  • Python 2.6—3.4
  • Thread-safe.
Clapier
la source
32
J'ai choisi cela comme réponse parce que la réponse originale est devenue obsolète. Donc, si vous vous demandez pourquoi cette réponse est en avance sur une réponse avec 76 votes positifs, c'est parce que les demandes sont la nouvelle façon de faire de facto.
Paul Biggar
132
@PaulBiggar vous dites que c'est la meilleure réponse. Mais cela ne répond pas vraiment à la question. Je suis venu ici pour découvrir les différences entre urllib et urllib2. Surtout sur les fonctionnalités de codage d'URL. La réponse: utilisez les demandes! ;) Je dis simplement que vous voudrez peut-être clarifier la question. Dans l'état actuel des choses, la réponse de Crast répond parfaitement à la question.
exhuma
2
Il serait utile de noter que la documentation de Python 3 a encore une autre bibliothèque distincte urllibet que sa documentation note également officiellement que " le package Requests est recommandé pour une interface client HTTP de niveau supérieur. " À 21.6. urllib.request - Bibliothèque extensible pour ouvrir des URL - Documentation Python 3.6.3 , et c'est urllib3une excellente bibliothèque utilisée par requests.
nealmcb
Ok, sauf que j'ai l'impression que la demande n'a pas de remplacement poururllib.parse()
Bob Stein
se mettre d'accord. avec @PaulBiggar - les demandes semblent être de facto le moyen. En fait, je suis arrivé ici sur la base du fait que urllib (et d'autres versions) ne fonctionnent pas ou sont sous-optimales par rapport aux demandes.
DL
205

urllib2 fournit des fonctionnalités supplémentaires, à savoir que la urlopen()fonction peut vous permettre de spécifier des en-têtes (normalement, vous auriez dû utiliser httplib dans le passé, ce qui est beaucoup plus détaillé.) Plus important encore, urllib2 fournit la Requestclasse, ce qui permet une plus approche déclarative pour faire une demande:

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

Notez que urlencode()c'est uniquement dans urllib, pas dans urllib2.

Il existe également des gestionnaires pour implémenter une prise en charge d'URL plus avancée dans urllib2. La réponse courte est que, sauf si vous travaillez avec du code hérité, vous souhaiterez probablement utiliser l'ouvreur d'URL d'urllib2, mais vous devez toujours importer dans urllib pour certaines des fonctions de l'utilitaire.

Réponse bonus Avec Google App Engine, vous pouvez utiliser n'importe lequel de httplib, urllib ou urllib2, mais tous ne sont que des wrappers pour l'API URL Fetch de Google. Autrement dit, vous êtes toujours soumis aux mêmes limitations telles que les ports, les protocoles et la longueur de la réponse autorisée. Vous pouvez cependant utiliser le cœur des bibliothèques comme vous vous en doutez pour récupérer des URL HTTP.

Crast
la source
1
Comment quelqu'un crée-t-il une URL avec une chaîne de requête codée en utilisant urllib2? C'est la seule raison pour laquelle j'utilise urllib et je voudrais m'assurer que je fais tout de la manière la plus récente / la plus efficace.
Gattster
2
Comme dans mon exemple ci-dessus, vous utilisez urlopen()et Requestdepuis urllib2 , et vous utilisez urlencode()depuis urllib . Pas de mal réel à utiliser les deux bibliothèques, tant que vous vous assurez d'utiliser l'urlopen correct. Les [documents urllib] [1] sont clairs sur le fait que cette utilisation est une utilisation acceptée. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast
J'ai utilisé cet essentiel pour urllib2.urlopen; contient également d'autres variantes.
Andrei-Niculae Petre
urllib2 ne prend pas en charge put ou delete, ce qui est
pénible
2
requestsautorise également les en-têtes personnalisés: docs.python-requests.org/en/master/user/quickstart/…
Omer Dagan
46

urllib et urllib2 sont tous deux des modules Python qui effectuent des liées aux requêtes URL mais offrent des fonctionnalités différentes.

1) urllib2 peut accepter un objet Request pour définir les en-têtes d'une demande d'URL, urllib n'accepte qu'une URL.

2) urllib fournit la méthode urlencode qui est utilisée pour la génération de chaînes de requête GET, urllib2 n'a pas une telle fonction. C'est l'une des raisons pour lesquelles urllib est souvent utilisé avec urllib2.

Demandes - Requests 'est une bibliothèque HTTP simple et facile à utiliser écrite en Python.

1) Les requêtes Python encodent les paramètres automatiquement, vous les transmettez donc simplement comme des arguments simples, contrairement à urllib, où vous devez utiliser la méthode urllib.encode () pour coder les paramètres avant de les transmettre.

2) Il a décodé automatiquement la réponse en Unicode.

3) Les requêtes ont également une gestion des erreurs beaucoup plus pratique.Si votre authentification a échoué, urllib2 déclencherait une urllib2.URLError, tandis que les requêtes renverraient un objet de réponse normal, comme prévu. Tout ce que vous avez à voir si la demande a abouti par réponse booléenne.ok

Siyaram Malav
la source
10
et urllib3?
PirateApp
1
Les requêtes @PirateApp sont construites sur urllib3 . Je pense que le code utilisant directement urllib3 peut être plus efficace, car il vous permet de réutiliser la session, tandis que les requêtes (au moins les requêtes 2, celle que tout le monde utilise) en créent une pour chaque requête, mais ne me citez pas là-dessus. Ni font partie de la bibliothèque standard ( encore )
Boris
12

Une différence considérable concerne le portage de Python2 vers Python3. urllib2 n'existe pas pour python3 et ses méthodes portées sur urllib. Donc, vous l'utilisez intensément et souhaitez migrer vers Python3 à l'avenir, envisagez d'utiliser urllib. Cependant, l'outil 2to3 fera automatiquement la plupart du travail pour vous.

Arash
la source
12

Juste pour ajouter aux réponses existantes, je ne vois personne mentionner que les requêtes python ne sont pas une bibliothèque native. Si vous êtes d'accord avec l'ajout de dépendances, les demandes sont correctes. Cependant, si vous essayez d'éviter d'ajouter des dépendances, urllib est une bibliothèque Python native qui est déjà à votre disposition.

Zeitgeist
la source
11

J'aime la urllib.urlencodefonction, et elle ne semble pas exister urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
Gattster
la source
4
Juste une note, soyez prudent avec urlencode car il ne peut pas gérer directement les objets <unicode> - vous devez les encoder avant de les envoyer à urlencode (u'blá'.encode ('utf-8'), ou autre).
@ user18015: Je ne pense pas que cela s'applique à Python 3, pouvez-vous clarifier?
Janus Troelsen
Comme je l'ai noté ci-dessus, cette question et les différentes réponses doivent être mises à jour pour clarifier qu'en urllibPython 3 est encore une autre option, nettoyée de diverses manières. Mais heureusement, la documentation officielle note également que « le package Requests est recommandé pour une interface client HTTP de niveau supérieur » à 21.6. urllib.request - Bibliothèque extensible pour ouvrir des URL - Documentation Python 3.6.3
nealmcb
urllib2 n'existe pas du tout dans Python 3
Boris
7

Pour obtenir le contenu d'une 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.

Il est difficile d'écrire requestdu code Python2 et Python3 et des dépendances pour les réponses car ces urlopen()fonctions et requests.get()fonctions renvoient différents types:

  • Python2 urllib.request.urlopen()renvoie unhttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)renvoie uninstance
  • La demande request.get(url)renvoie unrequests.models.Response
alvas
la source
5

Vous devez généralement utiliser urllib2, car cela facilite parfois les choses en acceptant les objets Request et soulèvera également une URLException sur les erreurs de protocole. Avec Google App Engine, vous ne pouvez pas non plus utiliser. Vous devez utiliser l' API URL Fetch fournie par Google dans son environnement Python en bac à sable.

Chinmay Kanchi
la source
2
Ce que vous avez dit sur Appengine n'est pas entièrement vrai. Vous pouvez actuellement utiliser httplib, urllib et urllib2 dans App Engine maintenant (ce sont des wrappers pour la récupération d'URL, fait pour que plus de code soit compatible avec appengine.)
Crast
Ah, ça doit être nouveau. Mon code a échoué la dernière fois que j'ai essayé et j'ai dû être réécrit pour travailler avec
Fetch
urllib2 n'existe pas du tout dans Python 3
Boris
@Boris Il a migré vers urllib.request et urllib.error .
Alan
1

Un point clé que je trouve manquant dans les réponses ci-dessus est que urllib renvoie un objet de type <class http.client.HTTPResponse>alors qu'il requestsretourne <class 'requests.models.Response'>.

Pour cette raison, la méthode read () peut être utilisée avec urllibmais pas avec requests.

PS: requestsest déjà riche de tant de méthodes qu'il en a à peine besoin d'une de plus read();>

paradoxlover
la source