Sự khác biệt giữa mô-đun urllib, urllib2, urllib3 và request là gì?


750

Trong Python, sự khác biệt giữa urllib , urllib2, urllib3requestsmô-đun? Tại sao có ba? Họ dường như làm điều tương tự ...


77
Yêu cầu là tốt nhất.
Yarin


75
yêu cầu sử dụng urllib3 .. 3 là số lớn hơn
Bro

2
tóm tắt: sử dụng requestshầu hết thời gian. đôi khi urllib2hoạt động nhưng đòi hỏi nhiều mã hơn và kém thanh lịch. không sử dụng urllib.
Trevor Boyd Smith

10
Câu hỏi này cần được cập nhật để làm rõ rằng urllibtrong Python 3 vẫn là một tùy chọn khác, được dọn sạch theo nhiều cách khác nhau. Nhưng rất may, tài liệu chính thức cũng lưu ý rằng " Gói Yêu cầu được khuyến nghị cho giao diện máy khách HTTP cấp cao hơn. " Tại 21.6. urllib.request - Thư viện mở rộng để mở URL - Tài liệu Python 3.6.3
nealmcb

Câu trả lời:


714

Tôi biết điều đó đã được nói rồi, nhưng tôi rất khuyến khích requestsgói Python.

Nếu bạn đã sử dụng các ngôn ngữ khác ngoài python, có lẽ bạn đang suy nghĩ urlliburllib2dễ sử dụng, không cần nhiều mã và có khả năng cao, đó là cách tôi từng nghĩ. Nhưng requestsgói này rất hữu ích và ngắn đến mức mọi người nên sử dụng nó.

Đầu tiên, nó hỗ trợ API đầy đủ và dễ dàng như:

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

Bất kể là GET / POST, bạn không bao giờ phải mã hóa lại các tham số, nó chỉ đơn giản lấy một từ điển làm đối số và rất tốt để đi:

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

Thêm vào đó, nó thậm chí còn có bộ giải mã JSON tích hợp (một lần nữa, tôi biết json.loads()không cần phải viết nhiều nữa, nhưng điều này chắc chắn là tiện lợi):

resp.json()

Hoặc nếu dữ liệu phản hồi của bạn chỉ là văn bản, hãy sử dụng:

resp.text

Đây chỉ là đỉnh của tảng băng trôi. Đây là danh sách các tính năng từ trang yêu cầu:

  • Tên miền và URL quốc tế
  • Keep-Alive & Kết nối
  • Phiên với sự kiên trì của Cookie
  • Xác minh SSL kiểu trình duyệt
  • Xác thực cơ bản / tiêu hóa
  • Cookies Key / Value Elegant
  • Giải nén tự động
  • Cơ quan phản hồi Unicode
  • Tải lên tập tin nhiều phần
  • Hết giờ kết nối
  • hỗ trợ .netrc
  • Danh sách mục
  • Python 2.6 Lọ3.4
  • Chủ đề an toàn.

32
Tôi chọn đây là câu trả lời vì câu trả lời ban đầu đã cũ. Vì vậy, nếu bạn đang tự hỏi tại sao câu trả lời này lại đi trước một câu trả lời với 76 lượt upvote, thì đó là vì Yêu cầu là cách thức chính xác mới để thực hiện.
Paul Biggar

132
@PaulBiggar bạn nói đây là câu trả lời hay nhất. Nhưng nó không thực sự trả lời câu hỏi. Tôi đến đây để tìm hiểu về sự khác biệt giữa urllib và urllib2. Đặc biệt là về các tính năng mã hóa url. Câu trả lời: sử dụng yêu cầu! ;) Chỉ cần nói rằng bạn có thể muốn làm rõ câu hỏi. Như hiện tại, câu trả lời từ Crast thực sự trả lời câu hỏi một cách hoàn hảo.
shoutuma

2
Nó sẽ giúp lưu ý rằng tài liệu Python 3 có một thư viện riêng biệt khác urllibvà tài liệu của nó cũng chính thức lưu ý rằng " Gói Yêu cầu được khuyến nghị cho giao diện máy khách HTTP cấp cao hơn. " Tại 21.6. urllib.request - Thư viện mở rộng để mở URL - Tài liệu Python 3.6.3 và đó urllib3là một thư viện tuyệt vời được sử dụng bởi requests.
nealmcb

Ok ngoại trừ tôi có yêu cầu hiển thị không có thay thế chourllib.parse()
Bob Stein

đồng ý. với @PaulBiggar - các yêu cầu dường như là cách thực tế. Trong thực tế, tôi đã đến đây trên cơ sở rằng urllib (và các phiên bản khác) không hoạt động hoặc không tối ưu so với yêu cầu.
DL

205

urllib2 cung cấp một số chức năng bổ sung, cụ thể là urlopen()chức năng có thể cho phép bạn chỉ định các tiêu đề (thông thường bạn đã phải sử dụng omeplib trong quá khứ, điều này dài hơn nhiều.) Quan trọng hơn, urllib2 cung cấp Requestlớp, cho phép nhiều hơn phương pháp khai báo để thực hiện một yêu cầu:

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

Lưu ý rằng urlencode()chỉ có trong urllib, không phải urllib2.

Ngoài ra còn có các trình xử lý để triển khai hỗ trợ URL nâng cao hơn trong urllib2. Câu trả lời ngắn gọn là, trừ khi bạn đang làm việc với mã kế thừa, bạn có thể muốn sử dụng trình mở URL từ urllib2, nhưng bạn vẫn cần nhập vào urllib cho một số chức năng tiện ích.

Phần thưởng cho câu trả lời Với Google App Engine, bạn có thể sử dụng bất kỳ omeplib, urllib hoặc urllib2, nhưng tất cả chúng chỉ là các hàm bao cho API tìm nạp URL của Google. Đó là, bạn vẫn phải chịu những hạn chế tương tự như cổng, giao thức và độ dài của phản hồi cho phép. Mặc dù vậy, bạn có thể sử dụng lõi của các thư viện như bạn mong đợi để truy xuất URL HTTP.


1
Làm thế nào để ai đó tạo một url với một chuỗi truy vấn được mã hóa bằng urllib2? Đó là lý do duy nhất tôi sử dụng urllib và tôi muốn chắc chắn rằng tôi đang làm mọi thứ theo cách mới nhất / tốt nhất.
Gattster

2
Giống như trong ví dụ trên của tôi, bạn sử dụng urlopen()Requesttừ urllib2 , và bạn sử dụng urlencode()từ urllib . Không có hại thực sự trong việc sử dụng cả hai thư viện, miễn là bạn chắc chắn rằng bạn sử dụng urlopen chính xác. [Tài liệu urllib] [1] rõ ràng rằng việc sử dụng này là sử dụng được thực hiện. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast

Tôi sử dụng này ý chính cho urllib2.urlopen; chứa các biến thể khác quá.
Andrei-Niculae Petre

urllib2 không hỗ trợ đặt hoặc xóa, đó là một nỗi đau
fkl 18/2/2015

2
requestscũng cho phép các tiêu đề tùy chỉnh: docs.python-requests.org/en/master/user/quickstart/ mẹo
Omer Dagan

46

urlliburllib2 đều là các mô-đun Python thực hiện các yêu cầu liên quan đến URL nhưng cung cấp các chức năng khác nhau.

1) urllib2 có thể chấp nhận một đối tượng Yêu cầu để đặt các tiêu đề cho một yêu cầu URL, urllib chỉ chấp nhận một URL.

2) urllib cung cấp phương thức urlencode được sử dụng để tạo chuỗi truy vấn GET, urllib2 không có chức năng như vậy. Đây là một trong những lý do tại sao urllib thường được sử dụng cùng với urllib2.

Yêu cầu - Yêu cầu 'là một thư viện HTTP đơn giản, dễ sử dụng được viết bằng Python.

1) Yêu cầu Python mã hóa các tham số tự động để bạn chỉ cần truyền chúng dưới dạng đối số đơn giản, không giống như trong trường hợp của urllib, nơi bạn cần sử dụng phương thức urllib.encode () để mã hóa các tham số trước khi truyền chúng.

2) Nó tự động giải mã phản hồi thành Unicode.

3) Yêu cầu cũng có cách xử lý lỗi thuận tiện hơn nhiều. Nếu xác thực của bạn không thành công, urllib2 sẽ tăng urllib2.URLError, trong khi Yêu cầu sẽ trả về một đối tượng phản hồi bình thường, như mong đợi. Tất cả bạn phải xem nếu yêu cầu đã thành công bằng phản hồi boolean.ok


10
Urllib3 thì sao?
PirateApp

1
Các yêu cầu @PirateApp được xây dựng dựa trên urllib3 . Tôi nghĩ rằng mã sử dụng urllib3 trực tiếp có thể hiệu quả hơn, bởi vì nó cho phép bạn sử dụng lại phiên, trong khi các yêu cầu (ít nhất là yêu cầu 2, mọi người sử dụng) tạo một cho mỗi yêu cầu, nhưng đừng trích dẫn tôi về điều đó. Không phải là một phần của thư viện tiêu chuẩn ( chưa )
Boris

12

Một sự khác biệt đáng kể là về việc chuyển Python2 sang Python3. urllib2 không tồn tại cho python3 và các phương thức của nó được chuyển sang urllib. Vì vậy, bạn đang sử dụng rất nhiều và muốn chuyển sang Python3 trong tương lai, hãy cân nhắc sử dụng urllib. Tuy nhiên, công cụ 2to3 sẽ tự động làm hầu hết công việc cho bạn.


12

Chỉ cần thêm vào các câu trả lời hiện có, tôi không thấy ai đề cập rằng các yêu cầu python không phải là một thư viện riêng. Nếu bạn ổn với việc thêm phụ thuộc, thì yêu cầu vẫn ổn. Tuy nhiên, nếu bạn đang cố gắng tránh thêm phụ thuộc, urllib là một thư viện python bản địa đã có sẵn cho bạn.


11

Tôi thích urllib.urlencodechức năng này và nó dường như không tồn tại urllib2.

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

4
Chỉ cần một lưu ý, hãy cẩn thận với urlencode vì nó không thể xử lý trực tiếp các đối tượng <unicode> - bạn phải mã hóa chúng trước khi gửi chúng tới urlencode (u'blá'.encode ('utf-8') hoặc bất cứ điều gì).

@ user18015: Tôi không nghĩ điều này áp dụng cho Python 3, bạn có thể làm rõ không?
Janus Troelsen

Như tôi đã lưu ý ở trên, câu hỏi này và các câu trả lời khác nhau cần được cập nhật để làm rõ rằng urllibtrong Python 3 là một tùy chọn khác, được làm sạch theo nhiều cách khác nhau. Nhưng may mắn thay, tài liệu chính thức cũng lưu ý rằng " Gói Yêu cầu được khuyến nghị cho giao diện máy khách HTTP cấp cao hơn. " Tại 21.6. urllib.request - Thư viện mở rộng để mở URL - Tài liệu Python 3.6.3
nealmcb

urllib2 hoàn toàn không tồn tại trong Python 3
Boris

7

Để có được nội dung của một 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.

Thật khó để viết Python2 và Python3 và requestmã phụ thuộc cho các phản hồi vì các urlopen()hàm và requests.get()hàm trả về các loại khác nhau:

  • Python2 urllib.request.urlopen()trả về mộthttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)trả về mộtinstance
  • Yêu cầu request.get(url)trả lại mộtrequests.models.Response

5

Nói chung, bạn nên sử dụng urllib2, vì điều này đôi khi làm mọi thứ dễ dàng hơn một chút bằng cách chấp nhận các đối tượng Yêu cầu và cũng sẽ đưa ra một URLException về lỗi giao thức. Tuy nhiên, với Google App Engine, bạn không thể sử dụng. Bạn phải sử dụng API tìm nạp URL mà Google cung cấp trong môi trường Python có hộp cát.


2
Những gì bạn nói về appengine không hoàn toàn đúng. Bây giờ bạn thực sự có thể sử dụng omeplib, urllib và urllib2 trong Máy ứng dụng (chúng là các trình bao bọc để tìm nạp url, được thực hiện sao cho nhiều mã hơn sẽ tương thích với appengine.)
Crast

À, phải mới. Mã của tôi thất bại tôi cuối cùng đã cố gắng và phải được viết lại để làm việc với lấy ...
Chinmay Kanchi


urllib2 hoàn toàn không tồn tại trong Python 3
Boris

@Boris Nó di chuyển đến urllib.requesturllib.error .
Alan

1

Một điểm quan trọng mà tôi thấy thiếu trong các câu trả lời ở trên là urllib trả về một đối tượng thuộc loại <class http.client.HTTPResponse>trong khi requeststrả về <class 'requests.models.Response'>.

Do đó, phương thức read () có thể được sử dụng urllibnhưng không sử dụng requests.

PS: requestsđã phong phú với rất nhiều phương thức mà hầu như không cần thêm một phương thức nào nữa read();>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.