urllib,urllib2和requests模块之间有什么区别?

Pau*_*gar 690 python urllib urllib2 python-2.x python-requests

在Python,有什么之间的差异urllib,urllib2以及urllib3模块?为什么有三个?他们似乎做同样的事情......

Hut*_*tch 657

我知道它已经说过,但我强烈推荐Requests python包:http: //docs.python-requests.org/en/latest/index.html

如果您使用的语言不是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')
Run Code Online (Sandbox Code Playgroud)

无论GET/POST是否你再也不必编码参数,它只需要一个字典作为参数,并且很好.

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

此外,它甚至还有一个内置的json解码器(再次,我知道json.loads()写的不多,但这肯定很方便):

resp.json()
Run Code Online (Sandbox Code Playgroud)

或者,如果您的响应数据只是文本,请使用:

resp.text
Run Code Online (Sandbox Code Playgroud)

这只是冰山一角.这是请求站点的功能列表:

  • 国际域名和URL
  • 保持活力和连接池
  • Cookie持久性的会话
  • 浏览器式SSL验证
  • 基本/摘要式身份验证
  • 优雅的钥匙/价值饼干
  • 自动减压
  • Unicode响应机构
  • 多部分文件上传
  • 连接超时
  • .netrc支持
  • 项目清单
  • Python 2.6-3.4
  • 线程安全的.

  • @PaulBiggar你说这是最好的答案.但它并没有真正回答这个问题.我来这里是为了找出urllib和urllib2之间的区别.特别是关于url编码功能.答案:使用请求!;)只是说你可能想澄清这个问题.就目前而言,Crast的答案实际上确实完美地回答了这个问题. (113认同)
  • 我选择这个作为答案,因为原来的答案已经过时了.因此,如果你想知道为什么这个答案提前76个upvotes答案,那是因为Requests是事实上新的事实方式. (31认同)
  • 如果其他人在2016年发现这一点,你可能想写`requests.post('http://www.mywebsite.com/user',data = userdata)`而不是`requests.post('http:// www.mywebsite.com/user',params = userdata)` (5认同)
  • ty @LGenzelis,我修复了这个bug!我无法确切地看到更改发生的时间,但至少是2015年.现在示例:http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests; 文档:http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests (2认同)
  • 注意到 Python 3 文档还有另一个独特的库 `urllib` 会有所帮助,并且其文档还正式指出“_The Requests 包被推荐用于更高级别的 HTTP 客户端接口。_”在 [21.6。urllib.request — 用于打开 URL 的可扩展库 — Python 3.6.3 文档](https://docs.python.org/3/library/urllib.request.html),并且 `urllib3` 是 `urllib3` 使用的一个很棒的库请求`。 (2认同)
  • 好的,除了我对 `urllib.parse()` 的印象 [请求没有替代品](/sf/answers/1983024361/) (2认同)
  • 我不明白为什么这是公认的答案。它没有回答OP的问题。 (2认同)
  • @TylerCrompton 因为它回答了真正的问题 - 使用哪一个? (2认同)

Cra*_*ast 195

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)
Run Code Online (Sandbox Code Playgroud)

请注意,urlencode()仅在urllib中,而不是urllib2.

还有一些处理程序用于在urllib2中实现更高级的URL支持.简短的回答是,除非您使用遗留代码,否则您可能希望使用urllib2中的URL开启工具,但您仍需要导入urllib以获取某些实用程序功能.

奖励回答 使用Google App Engine,您可以使用httplib,urllib或urllib2中的任何一个,但所有这些只是Google的URL Fetch API的包装.也就是说,您仍然受到相同的限制,例如端口,协议和允许的响应长度.但是,您可以像检索HTTP URL一样使用库的核心.

  • 就像我在上面的例子中一样,你使用来自*urllib2*的`urlopen()`和`Request`,你使用来自*urllib*的`urlencode()`.只要您确保使用正确的urlopen,使用两个库都没有真正的危害.[urllib docs] [1]很清楚,使用这个是acecepted用法.[1]:http://docs.python.org/library/urllib2.html#urllib2.urlopen (2认同)
  • `requests` 还允许自定义标头:http://docs.python-requests.org/en/master/user/quickstart/#custom-headers (2认同)

pdw*_*pdw 103

这是我对各种“urllibs”之间关系的理解:

在 Python 2 标准库中,并排存在两个 HTTP 库。尽管名称相似,但它们并不相关:它们具有不同的设计和不同的实现。

  • urllib是最初的 Python HTTP 客户端,添加到Python 1.2的标准库中。早期的文档urllib可以在Python 1.4 中找到。

  • urllib2是一个功能更强大的 HTTP 客户端,在 Python 1.6 中添加,旨在替代urllib

    urllib2 - 新的和改进但不兼容的 urllib 版本(仍处于试验阶段)。

    早期的文档urllib2可以在Python 2.1 中找到。

Python 3 标准库有一个新的 urllib,它是旧模块的合并/重构/重写版本。

urllib3是第三方包(即不在 CPython 的标准库中)。尽管有这个名字,但它与标准库包无关,将来也无意将其包含在标准库中。

最后,requests内部使用urllib3,但它旨在提供更易于使用的 API。

  • 谢谢你!接受的答案根本没有回答OP的问题,只是促进了请求库的使用。 (3认同)

Siy*_*lav 40

urlliburllib2都是Python模块,它们执行URL请求相关的东西,但提供不同的功能.

1)urllib2可以接受Request对象来设置URL请求的头,urllib只接受一个URL.

2)urllib提供了用于生成GET查询字符串的urlencode方法,urllib2没有这样的功能.这是urllib经常与urllib2一起使用的原因之一.

Requests - Requests'是一个用Python编写的简单易用的HTTP库.

1)Python请求自动对参数进行编码,因此您只需将它们作为简单参数传递,与urllib的情况不同,在urllib中,您需要使用方法urllib.encode()在传递参数之前对其进行编码.

2)它自动将响应解码为Unicode.

3)请求也有更方便的错误处理.如果您的身份验证失败,urllib2将引发urllib2.URLError,而Requests将返回正常的响应对象,如预期的那样.所有你必须通过boolean response.ok查看请求是否成功

例如参考 - https://dancallahan.info/journal/python-requests/

  • urllib3呢? (5认同)
  • @PirateApp [requests](https://github.com/psf/requests/) 构建在 [urllib3](https://github.com/urllib3/urllib3) 之上。我认为直接使用 urllib3 的代码可以更有效,因为它可以让您重用会话,而请求(至少请求 2,每个人都使用的请求)为每个请求创建一个,但不要引用我的话。两者都不是标准库的一部分([还](https://github.com/psf/requests/issues/2424)) (4认同)

Gat*_*ter 11

我喜欢这个urllib.urlencode功能,它似乎不存在urllib2.

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

  • 只是一个注意事项,小心urlencode,因为它无法直接处理<unicode>对象 - 你必须在将它们发送到urlencode(u'blá'.encode('utf-8')或其他)之前对它们进行编码. (4认同)
  • 正如我上面提到的,应该更新这个问题和各种答案,以澄清 Python 3 中的 `urllib` 是另一种选择,以各种方式清理。但值得庆幸的是,官方文档也在 [21.6. urllib.request — 用于打开 URL 的可扩展库 — Python 3.6.3 文档](https://docs.python.org/3/library/urllib.request.html) (2认同)

Ara*_*ash 11

一个相当大的区别是将Python2移植到Python3.对于python3,urllib2不存在,并且其方法移植到urllib.因此,您正在大量使用它并希望将来迁移到Python3,请考虑使用urllib.但是2to3工具会自动为您完成大部分工作.


Zei*_*ist 9

只是为了添加现有答案,我没有看到有人提到python请求不是本机库.如果您可以添加依赖项,那么请求就可以了.但是,如果您尝试避免添加依赖项,则urllib是一个已经可用的本机python库.

  • 确实,如果您想避免添加任何依赖项,可以使用 urllib。但请注意,即使是 [Python 官方文档](https://docs.python.org/3/library/urllib.request.html#module-urllib.request) 也推荐使用 requests 库:“推荐使用 Requests 包更高级别的 HTTP 客户端接口。” (3认同)
  • @hlongmore 当然,大多数人不想处理低级别的 urllib,而 Requests 库提供了很好的抽象级别。这就像在盒子里使用煎饼混合物与从头开始制作它一样。优点和缺点。 (3认同)

Ran*_*ara 8

我认为所有的答案都很好。但是关于 urllib3 的细节较少。urllib3 是一个非常强大的 Python 的 HTTP 客户端。要安装以下两个命令都可以使用,

urllib3

使用点子,

pip install urllib3
Run Code Online (Sandbox Code Playgroud)

或者您可以从 Github 获取最新代码并使用以下方法安装它们,

$ git clone git://github.com/urllib3/urllib3.git
$ cd urllib3
$ python setup.py install
Run Code Online (Sandbox Code Playgroud)

然后你就可以出发了

只需使用导入 urllib3,

import urllib3
Run Code Online (Sandbox Code Playgroud)

在这里,您不需要直接创建连接,而是需要一个 PoolManager 实例来发出请求。这为您处理连接池和线程安全。还有一个 ProxyManager 对象,用于通过 HTTP/HTTPS 代理路由请求,这里可以参考文档。示例用法:

>>> from urllib3 import PoolManager
>>> manager = PoolManager(10)
>>> r = manager.request('GET', 'http://google.com/')
>>> r.headers['server']
'gws'
>>> r = manager.request('GET', 'http://yahoo.com/')
>>> r.headers['server']
'YTS/1.20.0'
>>> r = manager.request('POST', 'http://google.com/mail')
>>> r = manager.request('HEAD', 'http://google.com/calendar')
>>> len(manager.pools)
2
>>> conn = manager.connection_from_host('google.com')
>>> conn.num_requests
3
Run Code Online (Sandbox Code Playgroud)

urrlib3文档中所述,urllib3带来了 Python 标准库中缺少的许多关键功能。

  • 线程安全。
  • 连接池。
  • 客户端 SSL/TLS 验证。
  • 使用多部分编码上传文件。
  • 重试请求和处理 HTTP 重定向的帮助程序。
  • 支持 gzip 和 deflate 编码。
  • 代理支持 HTTP 和 SOCKS。
  • 100% 的测试覆盖率。

请按照用户指南了解更多详细信息。

requests

requestsurllib3在幕后使用,使制作requests和检索数据变得更加简单。一方面,保持活动是 100% 自动的,与urllib3它不是的情况相比。它还具有事件钩子,当事件被触发时调用回调函数,比如接收响应 In requests,每个请求类型都有自己的函数。因此,您无需创建连接或池,而是直接获取 URL。


requests使用 pip安装只需运行

pip install requests

或者你可以直接从源代码安装,

$ git clone git://github.com/psf/requests.git
$ cd requests
$ python setup.py install
Run Code Online (Sandbox Code Playgroud)

然后, import requests

这里可以参考官方文档,一些高级用法如会话对象、SSL 验证和事件钩子请参考这个url

  • 谢谢你的回答。我来到这里是因为我看到了`urllib3`并且不知道我应该使用它还是`requests`。现在我知道如何继续做出这个决定。接受的答案对“请求”进行了很好的细分,但没有将其与替代方案区分开来。 (3认同)
  • 是的,我也来这里寻找 Requests、urllib、urllib2 和 urllib3 之间的差异,并对接受的答案感到不满意。应添加此说明或至少将其链接到已接受的答案。谢谢。 (2认同)
  • 如果您受到公司代理的困扰,请知道 requests 模块很乐意遵守环境变量 http_proxy、https_proxy、no_proxy。urllib3模块忽略环境变量;要通过代理发送查询,您必须创建 ProxyManager 而不是 PoolManager 的实例。 (2认同)

Chi*_*chi 5

您通常应该使用urllib2,因为这有时会通过接受Request对象使事情变得更容易,并且还会引发协议错误的URLException.但是,使用Google App Engine,您也无法使用它们.您必须使用Google在其沙盒Python环境中提供的URL Fetch API.

  • 你对appengine所说的并不完全正确.您现在可以在App Engine中使用httplib,urllib和urllib2(它们是url fetch的包装器,完成后可以使更多代码与appengine兼容.) (2认同)

alv*_*vas 5

要获取网址的内容:

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.
Run Code Online (Sandbox Code Playgroud)

request为响应编写Python2和Python3以及依赖项代码很困难,因为它们的urlopen()函数和requests.get()函数返回不同的类型:

  • Python2 urllib.request.urlopen()返回一个http.client.HTTPResponse
  • Python3 urllib.urlopen(url)返回一个instance
  • 请求request.get(url)返回arequests.models.Response


par*_*ver 5

我发现上述答案中缺少的一个关键点是 urllib 返回类型的对象,<class http.client.HTTPResponse>requestsreturns <class 'requests.models.Response'>.

因此,read() 方法可以与 一起使用,urllib但不能与 一起使用requests

PS:requests已经有很多方法了,几乎不需要再有一个read();>