Каковы различия между urllib, urllib2, urllib3 и модулем запросов?

751

В Python, каковы различия между urllib, urllib2, urllib3и requestsмодулей? Почему их три? Кажется, они делают то же самое ...

Пол Биггар
источник
78
Запросы это лучшее.
Ярин
2
Да, используйте запросы. stackoverflow.com/questions/22676/…
hughdbrown
76
запросы использует urllib3 .. 3 - большее число
Bro
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
  • Keep-Alive & Connection Pooling
  • Сессии с сохранением Cookie
  • Проверка SSL в стиле браузера
  • Базовая / дайджест-аутентификация
  • Элегантный ключ / ценное печенье
  • Автоматическая декомпрессия
  • Ответные органы Unicode
  • Загрузка нескольких файлов
  • Время ожидания подключения
  • Поддержка .netrc
  • Пункт списка
  • Python 2.6—3.4
  • Потокобезопасна.
закром
источник
32
Я выбрал это как ответ, потому что оригинальный ответ устарел. Так что, если вам интересно, почему этот ответ опережает ответ с 76 голосами против, то это потому, что Requests - это новый де-факто способ сделать что-то.
Пол Биггар
132
@PaulBiggar вы говорите, что это лучший ответ. Но это не совсем отвечает на вопрос. Я пришел сюда, чтобы узнать о различиях между urllib и urllib2. Особенно о функциях кодирования URL. Ответ: используйте запросы! ;) Просто говорю, что вы можете уточнить вопрос. На самом деле, ответ от Crast действительно отвечает на вопрос идеально.
exhuma
2
Было бы полезно отметить, что в документации по Python 3 есть еще одна отдельная библиотека, urllibи что в ее документации также официально отмечается, что « пакет Requests рекомендуется для высокоуровневого клиентского интерфейса HTTP » на 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, но все они являются просто оболочками для Google Fetch API Google Fetch. Это значит, что вы по-прежнему подвержены тем же ограничениям, что и порты, протоколы и допустимая длина ответа. Вы можете использовать ядро ​​библиотек так, как вы ожидаете получить HTTP-URL.

Crast
источник
1
Как кто-то создает URL с закодированной строкой запроса, используя urllib2? Это единственная причина, по которой я использую urllib, и я хотел бы убедиться, что я делаю все по-новому.
Гатстер
2
Как и в моем примере выше, вы используете urlopen()и Requestиз urllib2 , и вы используете urlencode()из urllib . Никакого реального вреда в использовании обеих библиотек, при условии, что вы используете правильный urlopen. В [urllib docs] [1] ясно, что это допустимое использование. [1]: docs.python.org/library/urllib2.html#urllib2.urlopen
Crast
Я использовал этот смысл для urllib2.urlopen; содержит и другие варианты.
Андрей-Никулае Петре
urllib2 не поддерживает put или delete, что является болью
fkl
2
requestsтакже разрешить использование пользовательских заголовков: docs.python-requests.org/en/master/user/quickstart/…
Омер Даган,
46

urllib и urllib2 оба являются модулями Python, которые выполняют связанные с URL запросы, но предлагают разные функциональные возможности.

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

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

Запросы - Запросы '- это простая и простая в использовании библиотека HTTP, написанная на Python.

1) Python Requests автоматически кодирует параметры, поэтому вы просто передаете их как простые аргументы, в отличие от случая с urllib, где вам необходимо использовать метод urllib.encode () для кодирования параметров перед их передачей.

2) Он автоматически декодирует ответ в Unicode.

3) Запросы также имеют гораздо более удобную обработку ошибок. Если ваша аутентификация не удалась, urllib2 вызовет urllib2.URLError, тогда как Запросы вернут обычный объект ответа, как и ожидалось. Все, что вы должны увидеть, если запрос был успешно выполнен boolean response.ok

Сиярам Малав
источник
10
как насчет urllib3?
PirateApp
1
@PirateApp запросы построен на вершине urllib3 . Я думаю, что код, использующий urllib3 напрямую, может быть более эффективным, потому что он позволяет вам повторно использовать сеанс, тогда как запросы (по крайней мере, запросы 2, которые используют все) создают один для каждого запроса, но не указывайте меня на этом. Ни одна из них не является частью стандартной библиотеки ( пока )
Борис
12

Одно существенное отличие заключается в переносе Python2 на Python3. urllib2 не существует для python3, а его методы перенесены в urllib. Так что вы интенсивно используете это и хотите в будущем перейти на Python3, подумайте об использовании urllib. Однако инструмент 2to3 автоматически сделает большую часть работы за вас.

Сыпь
источник
12

Просто чтобы добавить к существующим ответам, я не вижу, чтобы кто-то упоминал, что запросы Python не являются нативной библиотекой. Если у вас все в порядке с добавлением зависимостей, тогда запросы в порядке. Однако, если вы пытаетесь избежать добавления зависимостей, urllib - это нативная библиотека Python, которая уже доступна для вас.

дух времени
источник
11

Мне нравится urllib.urlencodeфункция, и она, кажется, не существует в urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
Gattster
источник
4
Только примечание, будьте осторожны с urlencode, так как он не может напрямую обрабатывать объекты <unicode> - вы должны закодировать их перед отправкой в ​​urlencode (u'blá'.encode ('utf-8') или что-то еще).
@ user18015: Я не думаю, что это относится к Python 3, вы можете уточнить?
Янус Троелсен
Как я отмечал выше, этот вопрос и различные ответы должны быть обновлены, чтобы уточнить, что urllibв Python 3 есть еще один вариант, очищенный различными способами. Но , к счастью, официальная документация также отмечает , что « Пакет запросов рекомендуется для 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()возвращаетhttp.client.HTTPResponse
  • Python3 urllib.urlopen(url)возвращаетinstance
  • Запрос request.get(url)возвращаетrequests.models.Response
Alvas
источник
5

Как правило, вы должны использовать urllib2, поскольку это иногда упрощает принятие объектов запроса и также вызывает исключение URLEx при ошибках протокола. Однако с Google App Engine вы не можете использовать ни того, ни другого. Вы должны использовать API URL Fetch, который Google предоставляет в изолированной среде Python.

Чинмай Канчи
источник
2
То, что вы сказали о appengine, не совсем верно. Теперь вы можете использовать httplib, urllib и urllib2 в App Engine (они являются обертками для извлечения URL-адресов, так как больше кода будет совместимо с appengine.)
Crast
Ах, должно быть, новый. Мой код потерпел неудачу в последний раз, когда я пытался, и его пришлось переписать для работы с fetch ...
Chinmay Kanchi
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();>

paradoxlover
источник