Jakie są różnice między modułem urllib, urllib2, urllib3 i modułem żądań?

750

W Pythonie, jakie są różnice między tymi urllib, urllib2, urllib3oraz requestsmodułów? Dlaczego są trzy? Wydają się robić to samo ...

Paul Biggar
źródło
77
Żądania są najlepsze.
Yarin
2
Tak, korzystaj z żądań. stackoverflow.com/questions/22676/…
hughdbrown
75
wnioski używa urllib3 .. 3 to większa liczba
Bro
2
Podsumowanie: wykorzystuj requestswiększość czasu. czasami urllib2działa, ale wymaga więcej kodu i jest mniej elegancki. nie używaj urllib.
Trevor Boyd Smith
10
To pytanie powinno zostać zaktualizowane, aby wyjaśnić, że urllibw Pythonie 3 jest jeszcze jedna opcja, oczyszczona na różne sposoby. Ale na szczęście oficjalna dokumentacja zauważa również, że „ Pakiet żądań jest zalecany dla interfejsu klienta HTTP wyższego poziomu ” w wersji 21.6. urllib.request - Rozszerzalna biblioteka do otwierania adresów URL - Dokumentacja Python 3.6.3
nealmcb

Odpowiedzi:

714

Wiem, że zostało już powiedziane, ale bardzo polecam requestspakiet Python.

Jeśli używasz języków innych niż python, prawdopodobnie myślisz urllibi urllib2są łatwe w użyciu, nie mają dużo kodu i są bardzo zdolne, tak myślałem. Ale requestspakiet jest tak niewiarygodnie przydatny i krótki, że wszyscy powinni go używać.

Po pierwsze, obsługuje w pełni spokojny interfejs API i jest tak łatwy jak:

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

Bez względu na to, czy GET / POST, nigdy nie musisz ponownie kodować parametrów, wystarczy wziąć słownik jako argument i dobrze jest przejść:

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

Ponadto ma nawet wbudowany dekoder JSON (znowu wiem, że json.loads()nie ma nic więcej do napisania, ale z pewnością jest to wygodne):

resp.json()

Lub jeśli dane odpowiedzi to tylko tekst, użyj:

resp.text

To tylko wierzchołek góry lodowej. Oto lista funkcji z witryny z żądaniami:

  • Międzynarodowe domeny i adresy URL
  • Keep-Alive & Connection Pooling
  • Sesje z trwałością plików cookie
  • Weryfikacja SSL w stylu przeglądarki
  • Podstawowe / uwierzytelnianie szyfrowane
  • Eleganckie ciasteczka z kluczem / wartością
  • Automatyczna dekompresja
  • Organy odpowiedzi Unicode
  • Przesyłanie plików wieloczęściowych
  • Limit czasu połączenia
  • Wsparcie .netrc
  • Element listy
  • Python 2.6–3.4
  • Bezpieczny dla wątków.
Niecka
źródło
32
Wybrałem to jako odpowiedź, ponieważ oryginalna odpowiedź stała się nieaktualna. Więc jeśli zastanawiasz się, dlaczego ta odpowiedź wyprzedza odpowiedź z 76 głosami pozytywnymi, to dlatego, że Żądania to nowy sposób na załatwienie sprawy.
Paul Biggar
132
@PaulBiggar mówisz, że to najlepsza odpowiedź. Ale tak naprawdę nie odpowiada na pytanie. Przybyłem tutaj, aby dowiedzieć się o różnicach między urllib i urllib2. Zwłaszcza o funkcjach kodowania adresów URL. Odpowiedź: prośby o wykorzystanie! ;) Wystarczy powiedzieć, że możesz wyjaśnić pytanie. Na obecną chwilę odpowiedź Crasta właściwie odpowiada na pytanie.
ekshuma
2
Warto zauważyć, że dokumentacja Python 3 ma jeszcze jedną odrębną bibliotekę, urlliba jej dokumentacja oficjalnie zauważa również, że „ Pakiet żądań jest zalecany dla interfejsu klienta HTTP wyższego poziomu ” w wersji 21.6. urllib.request - Rozszerzalna biblioteka do otwierania adresów URL - dokumentacja Python 3.6.3 , i urllib3jest to świetna biblioteka używana przez requests.
nealmcb
Ok, z wyjątkiem mam wrażenie prośba ma zastępstwo dlaurllib.parse()
Bob Stein
Zgodzić się. with @PaulBiggar - żądania wydają się de facto. W rzeczywistości przybyłem tutaj na tej podstawie, że urllib (i inne wersje) albo nie działają, albo nie są optymalne w porównaniu do żądań.
DL
205

urllib2 zapewnia dodatkową funkcjonalność, a mianowicie urlopen()funkcja może pozwolić ci na określenie nagłówków (normalnie musiałeś używać httplib w przeszłości, co jest znacznie bardziej szczegółowe). Co ważniejsze, urllib2 zapewnia Requestklasę, która pozwala na więcej deklaratywne podejście do robienia zapytania:

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

Pamiętaj, że urlencode()jest tylko w urllib, a nie urllib2.

Istnieją również procedury obsługi bardziej zaawansowanej obsługi adresów URL w urllib2. Krótka odpowiedź brzmi: chyba że pracujesz ze starszym kodem, prawdopodobnie chcesz użyć otwieracza URL z urllib2, ale nadal musisz zaimportować do urllib dla niektórych funkcji narzędziowych.

Dodatkowa odpowiedź Dzięki Google App Engine możesz używać dowolnego z httplib, urllib lub urllib2, ale wszystkie z nich są tylko opakowaniami interfejsu API pobierania URL Google. Oznacza to, że nadal podlegasz tym samym ograniczeniom, takim jak porty, protokoły i dozwolona długość odpowiedzi. Możesz jednak korzystać z rdzenia bibliotek tak, jak można by oczekiwać przy pobieraniu adresów URL HTTP.

Crast
źródło
1
Jak ktoś tworzy adres URL za pomocą zakodowanego ciągu zapytania za pomocą urllib2? To jedyny powód, dla którego używam urllib i chciałbym upewnić się, że robię wszystko w najnowszy / najlepszy sposób.
Gattster,
2
Tak jak w moim powyższym przykładzie, używasz urlopen()i Requestz urllib2 , i używasz urlencode()z urllib . Bez realnej szkody w korzystaniu z obu bibliotek, o ile upewnisz się, że korzystasz z właściwego urlopu. [Dokumenty urllib] [1] jasno mówią, że używanie tego jest zgodne z przeznaczeniem. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast
Kiedyś to sens dla urllib2.urlopen; zawiera również inne odmiany.
Andrei-Niculae Petre
urllib2 nie obsługuje wstawiania ani usuwania, co jest uciążliwe
np.
1
requestszezwól również na niestandardowe nagłówki: docs.python-requests.org/en/master/user/quickstart/…
Omer Dagan
46

urllib i urllib2 to moduły Pythona, które wykonują czynności związane z żądaniami adresów URL, ale oferują różne funkcje.

1) urllib2 może zaakceptować obiekt Request w celu ustawienia nagłówków żądania URL, urllib akceptuje tylko adres URL.

2) urllib zapewnia metodę urlencode , która jest używana do generowania ciągów zapytań GET, urllib2 nie ma takiej funkcji. Jest to jeden z powodów, dla których urllib jest często używany wraz z urllib2.

Requests - Requests 'to prosta, łatwa w użyciu biblioteka HTTP napisana w języku Python.

1) Żądania w Pythonie automatycznie kodują parametry, więc przekazujesz je jako proste argumenty, inaczej niż w przypadku urllib, gdzie musisz użyć metody urllib.encode () do zakodowania parametrów przed ich przekazaniem.

2) Automatycznie dekodował odpowiedź do Unicode.

3) Żądania mają również znacznie wygodniejszą obsługę błędów. Jeśli uwierzytelnienie się nie powiedzie, urllib2 podniósłby błąd urllib2.URLEr, podczas gdy żądania zwróciły normalny obiekt odpowiedzi, zgodnie z oczekiwaniami. Wszystko, co musisz zobaczyć, czy żądanie zakończyło się pomyślnie przez boolean response.ok

Siyaram Malav
źródło
10
co z urllib3?
PirateApp
1
Żądania @PirateApp są oparte na urllib3 . Myślę, że kod korzystający bezpośrednio z urllib3 może być bardziej wydajny, ponieważ pozwala na ponowne użycie sesji, podczas gdy żądania (przynajmniej żądania 2, te, których wszyscy używają) tworzą je dla każdego żądania, ale nie cytuj mnie. Żadne z nich nie jest częścią standardowej biblioteki ( jeszcze )
Boris
12

Jedną znaczącą różnicą jest przenoszenie Python2 na Python3. urllib2 nie istnieje dla Python3 i jego metod przeniesionych do urllib. Więc używasz tego intensywnie i chcesz migrować do Python3 w przyszłości, rozważ użycie urllib. Jednak narzędzie 2to3 automatycznie wykona większość pracy za Ciebie.

Wysypka
źródło
12

Aby dodać do istniejących odpowiedzi, nie widzę, aby ktokolwiek wspomniał, że żądania Pythona nie są biblioteką natywną. Jeśli nie masz nic przeciwko dodawaniu zależności, żądania są w porządku. Jednak jeśli próbujesz uniknąć dodawania zależności, urllib jest rodzimą biblioteką Pythona, która jest już dostępna.

Zeitgeist
źródło
11

Podoba mi się urllib.urlencodefunkcja i wydaje się, że nie istnieje urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
Gattster
źródło
4
Tylko uwaga, bądź ostrożny z urlencode, ponieważ nie może bezpośrednio obsługiwać obiektów <unicode> - musisz je zakodować przed wysłaniem do urlencode (u'blá'.encode ('utf-8') lub cokolwiek innego).
@ user18015: Nie sądzę, że dotyczy to Pythona 3, czy możesz to wyjaśnić?
Janus Troelsen,
Jak zauważyłem powyżej, to pytanie i różne odpowiedzi powinny zostać zaktualizowane, aby wyjaśnić, że urllibw Pythonie 3 jest jeszcze jedna opcja, oczyszczona na różne sposoby. Ale na szczęście oficjalna dokumentacja zauważa również, że „ Pakiet żądań jest zalecany dla interfejsu klienta HTTP wyższego poziomu ” w wersji 21.6. urllib.request - Rozszerzalna biblioteka do otwierania adresów URL - Dokumentacja Python 3.6.3
nealmcb
urllib2 w ogóle nie istnieje w Pythonie 3
Boris
7

Aby uzyskać treść adresu 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.

Trudno jest napisać w odpowiedziach Python2 i Python3 oraz requestkod zależności, ponieważ urlopen()funkcje i requests.get()funkcje zwracają różne typy:

  • Python2 urllib.request.urlopen()zwraca ahttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)zwraca aninstance
  • Żądanie request.get(url)zwraca arequests.models.Response
alvas
źródło
5

Zasadniczo powinieneś używać urllib2, ponieważ czasami jest to nieco łatwiejsze, akceptując obiekty Request, a także podniesie wyjątek URLException na temat błędów protokołu. Jednak w Google App Engine nie można używać żadnego z nich. Musisz użyć interfejsu API pobierania adresu URL udostępnianego przez Google w środowisku piaskownicy w języku Python.

Chinmay Kanchi
źródło
2
To, co powiedziałeś o appengine, nie jest do końca prawdą. Możesz teraz właściwie używać httplib, urllib i urllib2 w App Engine (są to opakowania dla pobierania adresu URL, wykonane tak, aby więcej kodu było kompatybilne z aplikacją).
Crast
Ach, musi być nowy. Mój kod zawiódł ostatnio, kiedy próbowałem i musiałem zostać przepisany do pracy z pobieraniem ...
Chinmay Kanchi,
urllib2 w ogóle nie istnieje w Pythonie 3
Boris
@Boris Migrował do urllib.request i urllib.error .
Alan
1

Kluczowym punktem, którego brakuje mi w powyższych odpowiedziach, jest to, że urllib zwraca obiekt typu <class http.client.HTTPResponse>podczas gdy requestszwraca <class 'requests.models.Response'>.

Z tego powodu metoda read () może być używana z, urllibale nie z requests.

PS: requestsjest już bogaty w tak wiele metod, że prawie nie potrzebuje jeszcze jednej read();

paradoxlover
źródło