Was sind die Unterschiede zwischen dem Modul urllib, urllib2, urllib3 und dem Anforderungsmodul?

750

In Python, was sind die Unterschiede zwischen der urllib, urllib2, urllib3und requestsModule? Warum gibt es drei? Sie scheinen dasselbe zu tun ...

Paul Biggar
quelle
77
Anfragen sind die besten.
Yarin
2
Ja, verwenden Sie Anfragen. stackoverflow.com/questions/22676/…
hughdbrown
75
Anfragen verwendet urllib3 .. 3 ist eine größere Zahl
Bro
2
Zusammenfassung: Verwenden Sie die requestsmeiste Zeit. urllib2funktioniert manchmal , erfordert aber mehr Code und ist weniger elegant. nicht benutzen urllib.
Trevor Boyd Smith
10
Diese Frage sollte aktualisiert werden, um zu verdeutlichen, dass urllibPython 3 eine weitere Option ist, die auf verschiedene Weise bereinigt wird. Zum Glück wird in der offiziellen Dokumentation jedoch auch darauf hingewiesen, dass " Das Requests-Paket für eine übergeordnete HTTP-Client-Schnittstelle empfohlen wird " ( 21.6). urllib.request - Erweiterbare Bibliothek zum Öffnen von URLs - Python 3.6.3-Dokumentation
nealmcb

Antworten:

714

Ich weiß, dass es bereits gesagt wurde, aber ich würde das requestsPython-Paket wärmstens empfehlen .

Wenn Sie andere Sprachen als Python verwendet haben, denken Sie wahrscheinlich urllibund urllib2sind einfach zu bedienen, nicht viel Code und sehr leistungsfähig. So habe ich früher gedacht. Aber das requestsPaket ist so unglaublich nützlich und kurz, dass jeder es verwenden sollte.

Erstens unterstützt es eine vollständig erholsame API und ist so einfach wie:

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

Unabhängig davon, ob GET / POST, Sie müssen nie wieder Parameter codieren, es wird einfach ein Wörterbuch als Argument verwendet und es kann losgehen:

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

Außerdem hat es sogar einen eingebauten JSON-Decoder (ich weiß wieder, dass json.loads()es nicht viel mehr zu schreiben gibt, aber das ist sicher praktisch):

resp.json()

Oder wenn Ihre Antwortdaten nur Text sind, verwenden Sie:

resp.text

Dies ist nur die Spitze des Eisbergs. Dies ist die Liste der Funktionen auf der Anforderungssite:

  • Internationale Domains und URLs
  • Keep-Alive & Verbindungspooling
  • Sitzungen mit Cookie-Persistenz
  • SSL-Überprüfung im Browser-Stil
  • Basic / Digest-Authentifizierung
  • Elegante Schlüssel- / Wert-Cookies
  • Automatische Dekomprimierung
  • Unicode-Antwortkörper
  • Hochladen von mehrteiligen Dateien
  • Verbindungszeitüberschreitungen
  • .netrc Unterstützung
  • Listenpunkt
  • Python 2.6—3.4
  • Gewindesicher.
Stall
quelle
32
Ich habe dies als Antwort gewählt, weil die ursprüngliche Antwort abgestanden ist. Wenn Sie sich also fragen, warum diese Antwort einer Antwort mit 76 positiven Stimmen voraus ist, dann ist Requests die neue Methode, um Dinge zu tun.
Paul Biggar
132
@ PaulBiggar Sie sagen, dies ist die beste Antwort. Aber es beantwortet die Frage nicht wirklich. Ich bin hierher gekommen, um die Unterschiede zwischen urllib und urllib2 herauszufinden. Insbesondere über URL-Codierungsfunktionen. Die Antwort: Verwenden Sie Anfragen! ;) Ich sage nur, dass Sie die Frage vielleicht klären möchten. So wie es aussieht, beantwortet die Antwort von Crast die Frage tatsächlich perfekt.
Exhuma
2
Es ist hilfreich zu beachten, dass die Python 3-Dokumentation über eine weitere Bibliothek verfügt urllibund dass in der Dokumentation auch offiziell angegeben ist, dass " Das Requests-Paket für eine übergeordnete HTTP-Client-Schnittstelle empfohlen wird " ( 21.6). urllib.request - Erweiterbare Bibliothek zum Öffnen von URLs - Python 3.6.3-Dokumentation , und das urllib3ist eine großartige Bibliothek, die von verwendet wird requests.
Nealmcb
Ok, außer ich habe die Impression Anfrage hat keinen Ersatz fürurllib.parse()
Bob Stein
zustimmen. mit @PaulBiggar - Anfragen scheinen de facto der Weg zu sein. Tatsächlich bin ich hier angekommen, weil urllib (und andere Versionen) entweder nicht funktionieren oder im Vergleich zu Anfragen nicht optimal sind.
DL
205

urllib2 bietet einige zusätzliche Funktionen, nämlich die urlopen()Funktion, mit der Sie Header angeben können (normalerweise hätten Sie in der Vergangenheit httplib verwenden müssen, was weitaus ausführlicher ist). Noch wichtiger ist jedoch, dass urllib2 die RequestKlasse bereitstellt , die mehr ermöglicht deklarativer Ansatz zur Bearbeitung einer Anfrage:

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

Beachten Sie, dass dies urlencode()nur in urllib und nicht in urllib2 erfolgt.

Es gibt auch Handler für die Implementierung einer erweiterten URL-Unterstützung in urllib2. Die kurze Antwort lautet: Wenn Sie nicht mit Legacy-Code arbeiten, möchten Sie wahrscheinlich den URL-Öffner von urllib2 verwenden, müssen jedoch für einige der Dienstprogrammfunktionen noch in urllib importieren.

Bonus Antwort Mit Google App Engine, können Sie alle httplib verwenden, urllib oder urllib2, aber alle von ihnen sind nur Wrapper für die Google-URL API abrufen. Das heißt, Sie unterliegen immer noch denselben Einschränkungen wie Ports, Protokollen und der Länge der zulässigen Antwort. Sie können den Kern der Bibliotheken jedoch wie erwartet zum Abrufen von HTTP-URLs verwenden.

Crast
quelle
1
Wie erstellt jemand mit urllib2 eine URL mit einer codierten Abfragezeichenfolge? Dies ist der einzige Grund, warum ich urllib verwende und ich möchte sicherstellen, dass ich alles auf die neueste / beste Weise mache.
Gattster
2
Wie in meinem obigen Beispiel verwenden Sie urlopen()und Requestvon urllib2 und Sie verwenden urlencode()von urllib . Kein wirklicher Schaden bei der Verwendung beider Bibliotheken, solange Sie sicherstellen, dass Sie die richtige URL verwenden. Die [urllib docs] [1] sind sich darüber im Klaren, dass die Verwendung dieser Option akzeptiert wird. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast
Ich habe diesen Kern benutzt für urllib2.urlopen; enthält auch andere Variationen.
Andrei-Niculae Petre
urllib2 unterstützt nicht setzen oder löschen, was ein Schmerz ist
fkl
2
requestsErlaube
Omer Dagan
46

urllib und urllib2 sind beide Python-Module, die URL-Request-bezogene Dinge ausführen, aber unterschiedliche Funktionen bieten.

1) urllib2 kann ein Request-Objekt akzeptieren, um die Header für eine URL-Anfrage festzulegen. Urllib akzeptiert nur eine URL.

2) urllib stellt die urlencode- Methode bereit , die zur Erzeugung von GET-Abfragezeichenfolgen verwendet wird. Urllib2 hat keine solche Funktion. Dies ist einer der Gründe, warum urllib häufig zusammen mit urllib2 verwendet wird.

Requests - Requests 'ist eine einfache, benutzerfreundliche HTTP-Bibliothek, die in Python geschrieben wurde.

1) Python Requests codiert die Parameter automatisch, sodass Sie sie nur als einfache Argumente übergeben, im Gegensatz zu urllib, wo Sie die Methode urllib.encode () verwenden müssen , um die Parameter zu codieren, bevor Sie sie übergeben.

2) Die Antwort wird automatisch in Unicode dekodiert.

3) Anfragen haben auch eine weitaus bequemere Fehlerbehandlung. Wenn Ihre Authentifizierung fehlschlägt, würde urllib2 einen urllib2.URLError auslösen, während Anfragen erwartungsgemäß ein normales Antwortobjekt zurückgeben würden. Alles, was Sie sehen müssen, um zu sehen, ob die Anfrage von boolean response.ok erfolgreich war

Siyaram Malav
quelle
10
was ist mit urllib3?
PirateApp
1
@ PirateApp- Anforderungen basieren auf urllib3 . Ich denke, Code, der urllib3 direkt verwendet, kann effizienter sein, da Sie damit die Sitzung wiederverwenden können, während Anforderungen (mindestens Anforderungen 2, die von allen verwendet werden) für jede Anforderung eine erstellen, aber zitieren Sie mich nicht dazu. Weder sind Teil der Standardbibliothek ( noch )
Boris
12

Ein wesentlicher Unterschied besteht darin, Python2 auf Python3 zu portieren. urllib2 existiert nicht für python3 und seine auf urllib portierten Methoden. Wenn Sie das also stark nutzen und in Zukunft auf Python3 migrieren möchten, sollten Sie urllib verwenden. Das 2to3-Tool erledigt jedoch automatisch den größten Teil der Arbeit für Sie.

Arash
quelle
12

Nur um die vorhandenen Antworten zu ergänzen, sehe ich niemanden, der erwähnt, dass Python-Anfragen keine native Bibliothek sind. Wenn Sie mit dem Hinzufügen von Abhängigkeiten einverstanden sind, sind Anforderungen in Ordnung. Wenn Sie jedoch versuchen, das Hinzufügen von Abhängigkeiten zu vermeiden, ist urllib eine native Python-Bibliothek, die Ihnen bereits zur Verfügung steht.

Zeitgeist
quelle
11

Ich mag die urllib.urlencodeFunktion und sie scheint in nicht zu existieren urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
Gattster
quelle
4
Nur eine Anmerkung, seien Sie vorsichtig mit Urlencode, da er <unicode> -Objekte nicht direkt verarbeiten kann - Sie müssen sie codieren, bevor Sie sie an urlencode (u'blá'.encode ('utf-8') oder was auch immer) senden.
@ user18015: Ich glaube nicht, dass dies für Python 3 gilt. Können Sie das klarstellen?
Janus Troelsen
Wie oben erwähnt, sollten diese Frage und die verschiedenen Antworten aktualisiert werden, um zu verdeutlichen, dass urllibPython 3 eine weitere Option ist, die auf verschiedene Weise bereinigt wird. Zum Glück wird in der offiziellen Dokumentation auch darauf hingewiesen, dass " Das Requests-Paket für eine übergeordnete HTTP-Client-Schnittstelle empfohlen wird " ( 21.6.). urllib.request - Erweiterbare Bibliothek zum Öffnen von URLs - Python 3.6.3-Dokumentation
nealmcb
urllib2 existiert überhaupt nicht in Python 3
Boris
7

So erhalten Sie den Inhalt einer 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.

Es ist schwierig, Python2- und Python3- und requestAbhängigkeitscode für die Antworten zu schreiben, da sie urlopen()funktionieren und requests.get()unterschiedliche Typen zurückgeben:

  • Python2 urllib.request.urlopen()gibt a zurückhttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)gibt eine zurückinstance
  • Anfrage request.get(url)gibt a zurückrequests.models.Response
Alvas
quelle
5

Sie sollten im Allgemeinen urllib2 verwenden, da dies die Dinge manchmal etwas einfacher macht, indem Anforderungsobjekte akzeptiert werden, und auch eine URLException für Protokollfehler auslöst. Mit Google App Engine können Sie jedoch auch nicht verwenden. Sie müssen die URL-Abruf-API verwenden , die Google in seiner Python-Umgebung mit Sandbox bereitstellt.

Chinmay Kanchi
quelle
2
Was Sie über Appengine gesagt haben, ist nicht ganz richtig. Sie können jetzt tatsächlich httplib, urllib und urllib2 in App Engine verwenden (sie sind Wrapper für das Abrufen von URLs, damit mehr Code mit Appengine kompatibel ist.)
Crast
Ah, muss neu sein. Mein Code ist zuletzt fehlgeschlagen, als ich es versuchte, und musste neu geschrieben werden, um mit Fetch zu arbeiten ...
Chinmay Kanchi
urllib2 existiert überhaupt nicht in Python 3
Boris
@ Boris Es wurde nach urllib.request und urllib.error migriert .
Alan
1

Ein wichtiger Punkt, der in den obigen Antworten fehlt, ist, dass urllib ein Objekt vom Typ zurückgibt, <class http.client.HTTPResponse>während es requestszurückgibt <class 'requests.models.Response'>.

Aus diesem Grund kann die read () -Methode mit, urllibaber nicht mit verwendet werden requests.

PS: requestsist bereits reich an so vielen Methoden, dass es kaum noch eine braucht als read();>

Paradoxliebhaber
quelle