Які відмінності між urllib, urllib2, urllib3 та модулем запитів?


750

В Python, які відмінності між urllib, urllib2, urllib3і requestsмодулів? Чому їх три? Вони, здається, роблять те саме ...


77
Запити найкращі.
Ярин

2
Так, використовуйте запити. stackoverflow.com/questions/22676 / ...
hughdbrown

75
запитів використовує urllib3 .. 3 є великим числом
Братан

2
резюме: використовуйте requestsбільшість часу. іноді urllib2працює, але вимагає більше коду і менш елегантний. не використовувати urllib.
Тревор Бойд Сміт

10
Це питання слід оновити, щоб уточнити, що urllibв Python 3 є ще один варіант, який очищається різними способами. Але, на щастя, в офіційній документації також зазначається, що " Пакет Запити рекомендується для клієнтського інтерфейсу HTTP вищого рівня ". 21.6. urllib.request - Розширювана бібліотека для відкриття URL-адрес - документація на Python 3.6.3
nealmcb

Відповіді:


714

Я знаю, що це вже було сказано, але я дуже рекомендую requestsпакет Python.

Якщо ви використовували інші мови, крім python, ви, напевно, думаєте urllibі urllib2прості у використанні, не багато коду та дуже здатні, ось так я думав. Але requestsпакунок настільки неймовірно корисний і короткий, що всі повинні його використовувати.

По-перше, він підтримує повністю спокійний API і простий як:

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

Незалежно від того, GET / POST, вам більше ніколи не доведеться кодувати параметри, він просто приймає словник як аргумент і це добре:

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

Плюс до цього навіть є вбудований декодер JSON (знову ж таки, я знаю json.loads(), що писати не набагато більше, але це впевнено зручно):

resp.json()

Або якщо ваші дані відповіді - це лише текст, використовуйте:

resp.text

Це лише верхівка айсберга. Це перелік функцій із сайту запитів:

  • Міжнародні домени та URL-адреси
  • Збереження та підтримка підключення
  • Сеанси із збереженням файлів cookie
  • Перевірка SSL у веб-переглядачі
  • Основна / дайджест аутентифікації
  • Елегантні файли cookie для ключів та цінностей
  • Автоматична декомпресія
  • Органи Unicode Response
  • Завантаження файлів з кількома частинами
  • Часи очікування підключення
  • підтримка .netrc
  • Елемент списку
  • Python 2.6—3.4
  • Нитка безпечна.

32
Я вибрав це як відповідь, оскільки початкова відповідь застаріла. Тож якщо вам цікаво, чому ця відповідь випереджає відповідь із 76 голосами, тому що "Запити" - це новий дефакто-спосіб робити речі.
Пол Біггар

132
@PaulBiggar, ти кажеш, це найкраща відповідь. Але це питання насправді не відповідає. Я прийшов сюди, щоб дізнатися про відмінності між urllib та urllib2. Особливо про функції кодування URL. Відповідь: використовуйте запити! ;) Просто сказавши, що ви можете уточнити питання. На даний момент відповідь Crast насправді відповідає на питання ідеально.
ексгума

2
Це допоможе зауважити, що в документації Python 3 є ще одна окрема бібліотека, urllibі в її документації також офіційно зазначається, що " Пакет запитів рекомендується використовувати для клієнтського інтерфейсу більш високого рівня. " В 21.6. urllib.request - Розширювана бібліотека для відкриття URL-адрес - документація Python 3.6.3 , і urllib3це чудова бібліотека, якою користується requests.
nealmcb

Добре , за винятком того, у мене є враження , запит не має замін дляurllib.parse()
Боб Штейна

згоден. за допомогою @PaulBiggar - запити видаються фактично де-факто. Насправді я приїхав сюди на основі того, що urllib (та інші версії) або не працюють, або є недостатньо оптимальними порівняно із запитами.
DL

205

urllib2 надає деяку додаткову функціональність, а саме ця urlopen()функція дозволяє вам задавати заголовки (як правило, вам довелося б використовувати httplib в минулому, що набагато більш багатослівне.) Що ще важливіше, хоча urllib2 забезпечує Requestклас, який дозволяє отримати більше декларативний підхід до виконання запиту:

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

Зауважте, що urlencode()лише у urllib, а не в urllib2.

Існують також обробники для впровадження більш розширеної підтримки URL в urllib2. Коротка відповідь полягає в тому, що якщо ви працюєте зі застарілим кодом, ви, ймовірно, хочете скористатися відкривачем URL-адреси від urllib2, але вам все одно потрібно імпортувати в urllib для деяких функцій утиліти.

Бонусна відповідь За допомогою Google App Engine ви можете використовувати будь-який з httplib, urllib або urllib2, але всі вони - лише обгортки для API Google Fetch URL. Тобто, ви все ще маєте ті самі обмеження, як порти, протоколи та тривалість відповіді. Ви можете використовувати ядро ​​бібліотек, як ви очікували для отримання HTTP-адрес.


1
Як хтось створює URL з кодованим рядком запиту за допомогою urllib2? Це єдина причина, що я використовую urllib, і я хотів би переконатися, що я роблю все останнім / найкращим способом.
Геттстер

2
Як і в моєму вище прикладі, ви використовуєте urlopen()і Requestвід urllib2 , і ви використовуєте urlencode()від urllib . Немає реальної шкоди у використанні обох бібліотек, якщо ви переконайтеся, що використовуєте правильний urlopen. [Urllib dokcs] [1] зрозуміло, що для цього використовується прийняте використання. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast

Я використовував цю суть для urllib2.urlopen; містить і інші варіанти.
Андрій-Нікулае Петре

urllib2 не підтримує ставити чи видаляти, що є болем
fkl

1
requestsтакож дозволити користувацькі заголовки: docs.python-requests.org/en/master/user/quickstart/…
Omer Dagan

46

urllib та urllib2 - це модулі Python, які виконують пов'язані із запитом URL-адреси, але пропонують різні функції.

1) urllib2 може прийняти об’єкт Request для встановлення заголовків для запиту URL, urllib приймає лише URL.

2) urllib забезпечує метод urlencode, який використовується для генерації рядків запитів GET, urllib2 не має такої функції. Це одна з причин, чому urllib часто використовується разом з urllib2.

Запити - Запити '- це проста, проста у використанні бібліотека HTTP, написана на Python.

1) Запити Python автоматично кодує параметри, тож ви просто передаєте їх у вигляді простих аргументів, на відміну від urllib, де вам потрібно використовувати метод urllib.encode () для кодування параметрів перед їх передачею.

2) Він автоматично розшифровує відповідь в Unicode.

3) У запитах також є набагато зручніше поводження з помилками. Якщо ваша автентифікація не вдалася, urllib2 викликає помилку urllib2.URLE, тоді як запити повертають нормальний об'єкт відповіді, як і очікувалося. Все, що вам потрібно побачити, чи був запит успішним boolean response.ok


10
що з urllib3?
PirateApp

1
@PirateApp запити побудовані поверх urllib3 . Я думаю, що код, що використовує urllib3 безпосередньо, може бути більш ефективним, оскільки він дозволяє повторно використовувати сеанс, тоді як запити (принаймні запити 2, той, хто всі використовують) створює один для кожного запиту, але не цитуйте мене з цього приводу. Також вони не є частиною стандартної бібліотеки ( поки що )
Борис

12

Важлива різниця полягає у перенесенні Python2 на Python3. urllib2 не існує для python3 і його методи переносяться на urllib. Отже, ви активно використовуєте це і хочете в майбутньому перейти на Python3, подумайте про використання urllib. Однак інструмент 2to3 автоматично зробить більшу частину роботи за вас.


12

Просто додати до існуючих відповідей, я не бачу, щоб хтось згадував, що запити python - це не рідна бібліотека. Якщо ви все добре з додаванням залежностей, то запити добре. Однак, якщо ви намагаєтеся уникнути додавання залежностей, urllib - це надійна бібліотека пітонів, яка вже доступна для вас.


11

Мені подобається urllib.urlencodeфункція, і вона, здається, не існує в urllib2.

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

4
Просто зауважте, будьте обережні з urlencode, оскільки він не може безпосередньо обробляти об'єкти <unicode> - вам потрібно кодувати їх, перш ніж надсилати їх до urlencode (u'blá'.encode ('utf-8') або будь-що інше).

@ user18015: Я не думаю, що це стосується Python 3, ви можете уточнити?
Янус Троельсен

Як я вже зазначав вище, це питання та різні відповіді слід оновити, щоб уточнити, що urllibв Python 3 є ще один варіант, який очищається різними способами. Але, на щастя, в офіційній документації також зазначається, що " Пакет Requests рекомендується для клієнтського інтерфейсу HTTP вищого рівня ". 21.6. urllib.request - Розширювана бібліотека для відкриття URL-адрес - документація на Python 3.6.3
nealmcb

urllib2 взагалі не існує в Python 3
Борис

7

Щоб отримати вміст 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.

Важко написати Python2 та Python3 та requestкод залежності для відповідей, оскільки вони urlopen()функціонують та requests.get()повертають різні типи:

  • Python2 urllib.request.urlopen()повертає ahttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)повертаєinstance
  • Запит request.get(url)повертає arequests.models.Response

5

Як правило, ви використовуєте urllib2, оскільки це часом полегшує справи, приймаючи об’єкти Request, а також підвищить URLException щодо помилок протоколу. З Google App Engine ви не можете використовувати жодне з них. Ви повинні використовувати API вилучення URL-адрес, який надає Google у своєму пісочному середовищі Python.


2
Те, що ви сказали про апенгін, не зовсім правдиве. Ви можете реально використовувати httplib, urllib та urllib2 в App Engine зараз (вони обгортки для отримання URL-адреси, зроблено так, щоб більше коду було сумісним з аппендином.)
Crast

Ах, має бути новим. Мій код не вдався востаннє, я спробував, і мені довелося переписати для роботи з
програмою


urllib2 взагалі не існує в Python 3
Борис

@Boris Він перейшов на urllib.request та urllib.error .
Алан

1

Ключовим моментом, який я вважаю відсутнім у вищезазначених відповідях, є те, що urllib повертає об’єкт типу, <class http.client.HTTPResponse>тоді як requestsповертається <class 'requests.models.Response'>.

Завдяки цьому метод read () може використовуватися, urllibале не з requests.

PS: requestsвже багатий такою кількістю методів, що навряд чи потрібен ще один, як read();>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.