Apa perbedaan antara modul urllib, urllib2, urllib3 dan request?

751

Dalam Python, apa perbedaan antara urllib, urllib2, urllib3dan requestsmodul? Kenapa ada tiga? Mereka tampaknya melakukan hal yang sama ...

Paul Biggar
sumber
77
Permintaan adalah yang terbaik.
Yarin
2
Ya, gunakan permintaan. stackoverflow.com/questions/22676/…
hughdbrown
75
permintaan menggunakan urllib3 .. 3 adalah angka yang lebih besar
Bro
2
ringkasan: gunakan requestssebagian besar waktu. terkadang urllib2bekerja tetapi membutuhkan lebih banyak kode dan kurang elegan. jangan gunakan urllib.
Trevor Boyd Smith
10
Pertanyaan ini harus diperbarui untuk memperjelas bahwa urllibdalam Python 3 adalah pilihan lain, dibersihkan dengan berbagai cara. Namun syukurlah dokumentasi resmi juga mencatat bahwa " Paket Permintaan direkomendasikan untuk antarmuka klien HTTP tingkat tinggi. " Di 21,6. urllib.request - Pustaka yang bisa diperluas untuk membuka URL - Dokumentasi Python 3.6.3
nealmcb

Jawaban:

714

Saya tahu itu sudah dikatakan, tapi saya sangat merekomendasikan requestspaket Python.

Jika Anda menggunakan bahasa selain python, Anda mungkin berpikir urllibdan urllib2mudah digunakan, tidak banyak kode, dan sangat cakap, begitulah cara saya berpikir. Tetapi requestspaket ini sangat berguna dan singkat sehingga setiap orang harus menggunakannya.

Pertama, mendukung API yang sepenuhnya tenang, dan semudah:

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

Terlepas dari apakah GET / POST, Anda tidak perlu menyandikan parameter lagi, itu hanya membutuhkan kamus sebagai argumen dan baik untuk pergi:

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

Plus itu bahkan memiliki decoder JSON bawaan (sekali lagi, saya tahu json.loads()tidak banyak lagi yang bisa ditulis, tapi ini pasti nyaman):

resp.json()

Atau jika data respons Anda hanya berupa teks, gunakan:

resp.text

Ini hanya puncak gunung es. Ini adalah daftar fitur dari situs permintaan:

  • Domain dan URL Internasional
  • Keep-Alive & Connection Pooling
  • Sesi dengan Kegigihan Cookie
  • Verifikasi SSL gaya peramban
  • Otentikasi Dasar / Intisari
  • Cookie Kunci / Nilai yang Elegan
  • Dekompresi Otomatis
  • Badan Respons Unicode
  • Unggah File Banyak Bagian
  • Timeout Koneksi
  • Dukungan .netrc
  • Daftar barang
  • Python 2.6—3.4
  • Aman untuk benang.
Kandang kelinci
sumber
32
Saya memilih ini sebagai jawaban karena jawaban aslinya sudah basi. Jadi jika Anda bertanya-tanya mengapa jawaban ini ada di depan jawaban dengan 76 upvotes, itu karena Permintaan adalah cara defacto baru untuk melakukan sesuatu.
Paul Biggar
132
@ PaulBiggar Anda mengatakan ini adalah jawaban terbaik. Tapi itu tidak benar-benar menjawab pertanyaan itu. Saya datang ke sini untuk mencari tahu perbedaan antara urllib dan urllib2. Terutama tentang fitur penyandian url. Jawabannya: gunakan permintaan! ;) Hanya dengan mengatakan Anda mungkin ingin mengklarifikasi pertanyaan. Seperti berdiri, jawaban dari Crast sebenarnya menjawab pertanyaan dengan sempurna.
exhuma
2
Akan membantu untuk mencatat bahwa dokumentasi Python 3 memiliki pustaka lain yang berbeda urllibdan bahwa dokumentasinya juga secara resmi mencatat bahwa " Paket Permintaan direkomendasikan untuk antarmuka klien HTTP tingkat tinggi. " Di 21.6. urllib.request - Pustaka yang dapat diperluas untuk membuka URL - dokumentasi Python 3.6.3 , dan itu urllib3adalah pustaka hebat yang digunakan oleh requests.
nealmcb
Ok kecuali Saya memiliki kesan permintaan tidak memiliki pengganti untukurllib.parse()
Bob Stein
setuju. dengan @PaulBiggar - permintaan tampaknya merupakan cara de-facto. Sebenarnya saya tiba di sini dengan alasan bahwa urllib (dan versi lain) tidak berfungsi atau tidak optimal dibandingkan dengan permintaan.
DL
205

urllib2 menyediakan beberapa fungsionalitas tambahan, yaitu urlopen()fungsi ini memungkinkan Anda untuk menentukan header (biasanya Anda harus menggunakan httplib di masa lalu, yang jauh lebih bertele-tele.) Lebih penting lagi, urllib2 menyediakan Requestkelas, yang memungkinkan untuk lebih pendekatan deklaratif untuk melakukan permintaan:

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

Perhatikan bahwa urlencode()hanya di urllib, bukan urllib2.

Ada juga penangan untuk mengimplementasikan dukungan URL yang lebih canggih di urllib2. Jawaban singkatnya adalah, kecuali Anda bekerja dengan kode lawas, Anda mungkin ingin menggunakan pembuka URL dari urllib2, tetapi Anda masih perlu mengimpor ke urllib untuk beberapa fungsi utilitas.

Jawaban bonus Dengan Google App Engine, Anda dapat menggunakan httplib, urllib, atau urllib2, tetapi semuanya hanyalah pembungkus untuk Google URL Fetch API. Artinya, Anda masih tunduk pada batasan yang sama seperti port, protokol, dan panjang respons yang diizinkan. Anda dapat menggunakan inti dari perpustakaan seperti yang Anda harapkan untuk mengambil URL HTTP.

Crast
sumber
1
Bagaimana cara seseorang membuat url dengan string kueri yang disandikan menggunakan urllib2? Itu satu-satunya alasan saya menggunakan urllib dan saya ingin memastikan saya melakukan semuanya dengan cara terbaru / terhebat.
Gattster
2
Seperti pada contoh saya di atas, Anda menggunakan urlopen()dan Requestdari urllib2 , dan Anda menggunakan urlencode()dari urllib . Tidak ada salahnya menggunakan kedua pustaka, selama Anda memastikan Anda menggunakan urlopen yang benar. The [urllib docs] [1] jelas tentang penggunaan ini adalah penggunaan yang diterima. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast
Saya menggunakan intisari ini untuk urllib2.urlopen; mengandung variasi lain juga.
Andrei-Niculae Petre
urllib2 tidak mendukung put atau delete yang
merepotkan
2
requestsjuga membolehkan tajuk khusus: docs.python-requests.org/en/master/user/quickstart/…
Omer Dagan
46

urllib dan urllib2 adalah modul Python yang melakukan hal-hal terkait permintaan URL tetapi menawarkan fungsionalitas yang berbeda.

1) urllib2 dapat menerima objek Permintaan untuk mengatur tajuk untuk permintaan URL, urllib hanya menerima URL.

2) urllib menyediakan metode urlencode yang digunakan untuk menghasilkan string kueri GET, urllib2 tidak memiliki fungsi seperti itu. Ini adalah salah satu alasan mengapa urllib sering digunakan bersama dengan urllib2.

Permintaan - Permintaan 'adalah perpustakaan HTTP sederhana dan mudah digunakan yang ditulis dengan Python.

1) Permintaan Python mengkodekan parameter secara otomatis sehingga Anda hanya memberikannya sebagai argumen sederhana, tidak seperti pada urllib, di mana Anda perlu menggunakan metode urllib.encode () untuk menyandikan parameter sebelum meneruskannya.

2) Secara otomatis menerjemahkan respons ke Unicode.

3) Permintaan juga memiliki penanganan kesalahan yang jauh lebih mudah. ​​Jika otentikasi Anda gagal, urllib2 akan meningkatkan urllib2.URLError, sementara Permintaan akan mengembalikan objek respons normal, seperti yang diharapkan. Yang harus Anda lihat jika permintaan berhasil oleh boolean response.ok

Siyaram Malav
sumber
10
bagaimana dengan urllib3?
PirateApp
1
Permintaan @PirateApp dibuat di atas urllib3 . Saya pikir kode menggunakan urllib3 secara langsung bisa lebih efisien, karena memungkinkan Anda menggunakan kembali sesi, sedangkan permintaan (setidaknya permintaan 2, yang digunakan semua orang) membuat satu untuk setiap permintaan, tetapi jangan mengutip saya tentang itu. Tidak ada bagian dari perpustakaan standar ( belum )
Boris
12

Satu perbedaan besar adalah tentang porting Python2 ke Python3. urllib2 tidak ada untuk python3 dan metodenya porting ke urllib. Jadi Anda menggunakan itu banyak dan ingin bermigrasi ke Python3 di masa depan, pertimbangkan untuk menggunakan urllib. Namun alat 2to3 secara otomatis akan melakukan sebagian besar pekerjaan untuk Anda.

Arash
sumber
12

Hanya untuk menambah jawaban yang ada, saya tidak melihat ada yang menyebutkan bahwa permintaan python bukan perpustakaan asli. Jika Anda setuju dengan menambahkan dependensi, maka permintaan baik-baik saja. Namun, jika Anda berusaha menghindari penambahan dependensi, urllib adalah pustaka python asli yang sudah tersedia untuk Anda.

Zeitgeist
sumber
11

Saya suka urllib.urlencodefungsinya, dan sepertinya tidak ada di urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
Gattster
sumber
4
Hanya sebuah catatan, berhati-hatilah dengan urlencode karena ia tidak dapat menangani objek <unicode> secara langsung - Anda harus menyandikannya sebelum mengirimnya ke urlencode (u'blá'.encode ('utf-8'), atau apa pun).
@ user18015: Saya rasa ini tidak berlaku untuk Python 3, bisakah Anda mengklarifikasi?
Janus Troelsen
Seperti yang saya catat di atas, pertanyaan ini dan berbagai jawaban harus diperbarui untuk memperjelas bahwa urllibdengan Python 3 adalah pilihan lain, dibersihkan dengan berbagai cara. Namun syukurlah, dokumentasi resmi juga mencatat bahwa " Paket Permintaan direkomendasikan untuk antarmuka klien HTTP tingkat tinggi. " Di 21,6. urllib.request - Pustaka yang dapat diperluas untuk membuka URL - Dokumentasi Python 3.6.3
nealmcb
urllib2 tidak ada sama sekali dalam Python 3
Boris
7

Untuk mendapatkan konten dari 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.

Sulit untuk menulis Python2 dan Python3 dan requestkode dependensi untuk respons karena mereka urlopen()berfungsi dan requests.get()mengembalikan tipe yang berbeda:

  • Python2 urllib.request.urlopen()mengembalikan ahttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)mengembalikan sebuahinstance
  • Permintaan request.get(url)pengembalian arequests.models.Response
alva
sumber
5

Anda biasanya harus menggunakan urllib2, karena ini kadang-kadang membuat hal-hal sedikit lebih mudah dengan menerima objek Permintaan dan juga akan meningkatkan URLException pada kesalahan protokol. Dengan Google App Engine, Anda tidak dapat menggunakan keduanya. Anda harus menggunakan URL Ambil API yang Google sediakan di lingkungan Python yang berpasir.

Chinmay Kanchi
sumber
2
Apa yang Anda katakan tentang appengine tidak sepenuhnya benar. Anda benar-benar dapat menggunakan httplib, urllib, dan urllib2 di App Engine sekarang (mereka adalah pembungkus untuk url fetch, dilakukan agar lebih banyak kode yang kompatibel dengan appengine.)
Crast
Ah, pasti baru. Kode saya gagal terakhir saya coba dan harus ditulis ulang untuk bekerja dengan mengambil ...
Chinmay Kanchi
urllib2 tidak ada sama sekali dalam Python 3
Boris
@Boris Ini bermigrasi ke urllib.request dan urllib.error .
Alan
1

Poin kunci yang saya temukan hilang dalam jawaban di atas adalah bahwa urllib mengembalikan objek bertipe <class http.client.HTTPResponse>sedangkan requestsmengembalikan <class 'requests.models.Response'>.

Karena itu, metode read () dapat digunakan dengan urllibtetapi tidak dengan requests.

PS: requestssudah kaya dengan begitu banyak metode sehingga tidak perlu satu lagi seperti read();>

paradoxlover
sumber