Quali sono le differenze tra urllib, urllib2, urllib3 e il modulo richieste?


751

In Python, quali sono le differenze tra i urllib, urllib2, urllib3e requestsmoduli? Perché ce ne sono tre? Sembrano fare la stessa cosa ...


77
Le richieste sono le migliori.
Yarin,


75
richieste utilizza urllib3 .. 3 è un numero maggiore
Bro

2
riepilogo: utilizzare la requestsmaggior parte delle volte. a volte urllib2funziona ma richiede più codice ed è meno elegante. non usare urllib.
Trevor Boyd Smith,

10
Questa domanda dovrebbe essere aggiornata per chiarire che urllibin Python 3 c'è ancora un'altra opzione, ripulita in vari modi. Ma per fortuna la documentazione ufficiale rileva anche che " Il pacchetto Richieste è raccomandato per un'interfaccia client HTTP di livello superiore " a 21.6. urllib.request - Libreria estensibile per l'apertura di URL - Documentazione Python 3.6.3
nealmcb

Risposte:


714

So che è già stato detto, ma consiglio vivamente il requestspacchetto Python.

Se hai usato lingue diverse da Python, probabilmente stai pensando urllibe urllib2sei facile da usare, non molto codice e altamente capace, è così che pensavo. Ma il requestspacchetto è così incredibilmente utile e breve che tutti dovrebbero usarlo.

Innanzitutto, supporta un'API completamente riposante ed è facile come:

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

Indipendentemente dal fatto che GET / POST, non devi mai codificare nuovamente i parametri, basta semplicemente un dizionario come argomento ed è buono per andare:

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

Inoltre ha anche un decoder JSON incorporato (di nuovo, so che json.loads()non c'è molto altro da scrivere, ma questo è sicuramente conveniente):

resp.json()

O se i tuoi dati di risposta sono solo testo, usa:

resp.text

Questa è solo la punta dell'iceberg. Questo è l'elenco delle funzionalità dal sito delle richieste:

  • Domini e URL internazionali
  • Keep-Alive e pool di connessioni
  • Sessioni con persistenza dei cookie
  • Verifica SSL in stile browser
  • Autenticazione di base / digest
  • Eleganti cookie chiave / valore
  • Decompressione automatica
  • Corpi di risposta Unicode
  • Caricamenti di file in più parti
  • Timeout della connessione
  • Supporto .netrc
  • Voce di elenco
  • Python 2.6—3.4
  • Thread-safe.

32
Ho scelto questa come risposta perché la risposta originale è diventata viziata. Quindi, se ti stai chiedendo perché questa risposta è in anticipo rispetto a una risposta con 76 voti positivi, è perché Requests è il nuovo modo defacto di fare le cose.
Paul Biggar,

132
@PaulBiggar dici che questa è la risposta migliore. Ma non risponde davvero alla domanda. Sono venuto qui per scoprire le differenze tra urllib e urllib2. Soprattutto sulle funzionalità di codifica degli URL. La risposta: usa le richieste! ;) Sto solo dicendo che potresti voler chiarire la domanda. Allo stato attuale, la risposta di Crast in realtà risponde perfettamente alla domanda.
exhuma,

2
Aiuterebbe a notare che la documentazione di Python 3 ha ancora un'altra libreria distinta urllibe che la sua documentazione rileva anche ufficialmente che " Il pacchetto Requests è raccomandato per un'interfaccia client HTTP di livello superiore " a 21.6. urllib.request - Libreria estensibile per l'apertura di URL - Documentazione di Python 3.6.3 , e questa urllib3è un'ottima libreria utilizzata da requests.
nealmcb,

Ok, tranne per il fatto che la richiesta di impressione non può essere sostituita daurllib.parse()
Bob Stein,

essere d'accordo. con @PaulBiggar - le richieste sembrano essere di fatto il modo. In effetti sono arrivato qui sulla base del fatto che urllib (e altre versioni) non funzionano o non sono ottimali rispetto alle richieste.
DL

205

urllib2 fornisce alcune funzionalità extra, vale a dire la urlopen()funzione può consentire di specificare le intestazioni (normalmente in passato avresti dovuto usare httplib, che è molto più dettagliato). Ancora più importante, però, urllib2 fornisce la Requestclasse, che consente di approccio dichiarativo all'esecuzione di una richiesta:

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

Nota che urlencode()è solo in urllib, non in urllib2.

Esistono anche gestori per l'implementazione di un supporto URL più avanzato in urllib2. La risposta breve è, a meno che tu non stia lavorando con un codice legacy, probabilmente vorrai utilizzare l'apri URL di urllib2, ma devi comunque importare in urllib per alcune delle funzioni di utilità.

Risposta bonus Con Google App Engine, puoi utilizzare uno qualsiasi di httplib, urllib o urllib2, ma tutti sono solo wrapper per l'API Google Fetch dell'URL. Cioè, sei ancora soggetto alle stesse limitazioni come porte, protocolli e la lunghezza della risposta consentita. Tuttavia, puoi utilizzare il nucleo delle librerie come ti aspetteresti per recuperare gli URL HTTP.


1
In che modo qualcuno crea un URL con una stringa di query codificata utilizzando urllib2? È l'unica ragione per cui sto usando urllib e mi piacerebbe essere sicuro di fare tutto nel modo più recente / migliore.
Gattster,

2
Come nel mio esempio sopra, usi urlopen()e Requestda urllib2 e usi urlencode()da urllib . Nessun danno reale nell'uso di entrambe le librerie, purché si assicuri di utilizzare l'urlopen corretto. I [documenti urllib] [1] sono chiari sul fatto che l'utilizzo di questo è un utilizzo accettato. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast

Ho usato questa sostanza per urllib2.urlopen; contiene anche altre varianti.
Andrei-Niculae Petre,

urllib2 non supporta put o delete che è una seccatura
fkl

2
requestsconsenti anche le intestazioni personalizzate: docs.python-requests.org/en/master/user/quickstart/…
Omer Dagan,

46

urllib e urllib2 sono entrambi moduli Python che eseguono richieste relative a URL ma offrono funzionalità diverse.

1) urllib2 può accettare un oggetto Request per impostare le intestazioni per una richiesta URL, urllib accetta solo un URL.

2) urllib fornisce il metodo urlencode utilizzato per la generazione di stringhe di query GET, urllib2 non ha tale funzione. Questo è uno dei motivi per cui urllib viene spesso utilizzato insieme a urllib2.

Richieste - Richieste 'è una libreria HTTP semplice e facile da usare scritta in Python.

1) Python Requests codifica automaticamente i parametri in modo da passarli come semplici argomenti, a differenza del caso di urllib, dove è necessario utilizzare il metodo urllib.encode () per codificare i parametri prima di passarli.

2) Decodifica automaticamente la risposta in Unicode.

3) Le richieste hanno anche una gestione degli errori molto più conveniente. Se l'autenticazione fallisce, urllib2 genererebbe un urllib2.URLError, mentre Requests restituirà un normale oggetto di risposta, come previsto. Tutto quello che devi vedere se la richiesta ha avuto esito positivo da response.ok booleano


10
che dire di urllib3?
PirateApp

1
Le richieste di @PirateApp si basano su urllib3 . Penso che usare direttamente il codice urllib3 possa essere più efficiente, perché ti consente di riutilizzare la sessione, mentre le richieste (almeno le richieste 2, quella che tutti usano) ne creano una per ogni richiesta, ma non citarmi su questo. Né fanno parte della libreria standard ( ancora )
Boris,

12

Una differenza considerevole riguarda il porting da Python2 a Python3. urllib2 non esiste per python3 e i suoi metodi sono stati portati su urllib. Quindi lo stai usando pesantemente e vuoi migrare su Python3 in futuro, considera l'utilizzo di urllib. Tuttavia lo strumento 2to3 farà automaticamente la maggior parte del lavoro per te.


12

Solo per aggiungere alle risposte esistenti, non vedo nessuno menzionare che le richieste di Python non sono una libreria nativa. Se sei d'accordo con l'aggiunta di dipendenze, allora le richieste vanno bene. Tuttavia, se stai cercando di evitare di aggiungere dipendenze, urllib è una libreria nativa di Python che è già disponibile per te.


11

Mi piace la urllib.urlencodefunzione e non sembra esistere in urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'

4
Solo una nota, fai attenzione con urlencode in quanto non è in grado di gestire direttamente gli oggetti <unicode>: devi codificarli prima di inviarli a urlencode (u'blá'.encode ('utf-8') o qualsiasi altra cosa).

@ user18015: Non penso che questo si applichi a Python 3, puoi chiarire?
Janus Troelsen,

Come ho notato sopra, questa domanda e le varie risposte dovrebbero essere aggiornate per chiarire che urllibin Python 3 c'è ancora un'altra opzione, ripulita in vari modi. Ma per fortuna, la documentazione ufficiale rileva anche che " Il pacchetto Richieste è raccomandato per un'interfaccia client HTTP di livello superiore " a 21.6. urllib.request - Libreria estensibile per l'apertura di URL - Documentazione Python 3.6.3
nealmcb

urllib2 non esiste affatto in Python 3
Boris il

7

Per ottenere il contenuto di un 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.

È difficile scrivere Python2 e Python3 e il requestcodice delle dipendenze per le risposte perché le urlopen()funzioni e le requests.get()funzioni restituiscono tipi diversi:

  • Python2 urllib.request.urlopen()restituisce ahttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)restituisce uninstance
  • La richiesta request.get(url)restituisce arequests.models.Response

5

In genere dovresti usare urllib2, poiché questo a volte rende le cose un po 'più semplici accettando gli oggetti Request e genererà anche una URLException sugli errori del protocollo. Con Google App Engine, tuttavia, non è possibile utilizzare neanche. Devi utilizzare l' API URL Fetch fornita da Google nel suo ambiente Python in modalità sandbox.


2
Quello che hai detto su Appengine non è del tutto vero. Ora puoi effettivamente utilizzare httplib, urllib e urllib2 in App Engine (sono wrapper per il recupero dell'URL, fatto in modo che più codice sia compatibile con appengine.)
Crast

Ah, deve essere nuovo. Il mio codice non è riuscito l'ultima volta che ho provato e ho dovuto essere riscritto per funzionare con fetch ...
Chinmay Kanchi


urllib2 non esiste affatto in Python 3
Boris il

@Boris È migrato su urllib.request e urllib.error .
Alan,

1

Un punto chiave che trovo mancante nelle risposte sopra è che urllib restituisce un oggetto di tipo <class http.client.HTTPResponse>mentre requestsrestituisce <class 'requests.models.Response'>.

Per questo motivo, il metodo read () può essere utilizzato con urllibma non con requests.

PS: requestsè già ricco con così tanti metodi che non ne ha quasi più bisogno come read();>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.