在 Python 中,urllib
、urllib2
、urllib3
和 requests
模块有什么区别?为什么有三个?他们似乎在做同样的事情......
urllib
是另一种选择,以各种方式进行清理。但值得庆幸的是,官方文档还指出“建议将 Requests 包用于更高级别的 HTTP 客户端接口。”位于 21.6. urllib.request — Extensible library for opening URLs — Python 3.6.3 documentation
urllib3
是什么以及 urllib3
与官方 urllib
模块有何不同。
我知道已经说过了,但我强烈推荐 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 响应体
多部分文件上传
连接超时
.netrc 支持
项目清单
Python 2.7、3.6—3.9
线程安全。
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 中。
在 urllib2 中还有用于实现更高级 URL 支持的处理程序。简短的回答是,除非您使用遗留代码,否则您可能希望使用 urllib2 中的 URL 打开器,但您仍然需要将某些实用程序功能导入 urllib。
奖励答案 使用 Google App Engine,您可以使用 httplib、urllib 或 urllib2 中的任何一个,但它们都只是 Google 的 URL Fetch API 的包装器。也就是说,您仍然受到相同的限制,例如端口、协议和允许的响应长度。不过,您可以使用库的核心来检索 HTTP URL。
urlopen()
和 Request
,并且使用 urllib 中的 urlencode()
。只要确保使用正确的 urlopen,使用这两个库并没有真正的危害。 [urllib docs][1] 清楚地表明使用它是公认的用法。 [1]:docs.python.org/library/urllib2.html#urllib2.urlopen
urllib2.urlopen
;也包含其他变体。
requests
还允许自定义标题:docs.python-requests.org/en/master/user/quickstart/…
这是我对各种“urllibs”之间关系的理解:
在 Python 2 标准库中并排存在两个 HTTP 库。尽管名称相似,但它们并不相关:它们具有不同的设计和不同的实现。
urllib 是最初的 Python HTTP 客户端,在 Python 1.2 中添加到标准库中。可以在 Python 1.4 中找到 urllib 的早期文档。
urllib2 是一个功能更强大的 HTTP 客户端,在 Python 1.6 中添加,旨在替代 urllib: urllib2 - 新的和改进但不兼容的 urllib 版本(仍处于试验阶段)。可以在 Python 2.1 中找到 urllib2 的早期文档。
Python 3 标准库有一个 new urllib
,它是旧模块的合并/重构/重写版本。
urllib3
是第三方包(即,不在 CPython 的标准库中)。尽管有这个名字,但它与标准库包无关,将来也不打算将它包含在标准库中。
最后,requests
在内部使用 urllib3
,但它旨在提供更易于使用的 API。
urllib 和 urllib2 都是 Python 模块,它们执行 URL 请求相关的东西,但提供不同的功能。
1)urllib2可以接受一个Request对象来设置一个URL请求的头部,urllib只接受一个URL。
2) urllib 提供了用于生成 GET 查询字符串的 urlencode 方法,而 urllib2 没有这样的功能。这也是为什么 urllib 经常与 urllib2 一起使用的原因之一。
Requests - Requests 是一个用 Python 编写的简单易用的 HTTP 库。
1) Python Requests 自动对参数进行编码,因此您只需将它们作为简单参数传递,这与 urllib 的情况不同,您需要在传递参数之前使用方法 urllib.encode() 对参数进行编码。
2) 它自动将响应解码为 Unicode。
3) Requests 也有更方便的错误处理。如果您的身份验证失败,urllib2 将引发 urllib2.URLError,而 Requests 将返回一个正常的响应对象,如预期的那样。您只需通过 boolean response.ok 查看请求是否成功
只是为了添加现有答案,我没有看到有人提到 python requests 不是本机库。如果您可以添加依赖项,那么 requests 就可以了。但是,如果您试图避免添加依赖项,则 urllib 是一个本机 Python 库,您已经可以使用它。
一个相当大的区别是将 Python2 移植到 Python3。 python3 不存在 urllib2 及其方法移植到 urllib。因此,您正在大量使用它并希望将来迁移到 Python3,请考虑使用 urllib。但是 2to3 工具会自动为您完成大部分工作。
我喜欢 urllib.urlencode
函数,它似乎在 urllib2
中不存在。
>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
urllib
是另一个选项,以各种方式清理。但值得庆幸的是,官方文档还指出“建议将 Requests 包用于更高级别的 HTTP 客户端接口。”位于 21.6. urllib.request — Extensible library for opening URLs — Python 3.6.3 documentation
我认为所有的答案都很好。但是关于 urllib3 的细节较少。urllib3 是一个非常强大的 Python 的 HTTP 客户端。对于安装以下两个命令都可以,
urllib3
使用点子,
pip install urllib3
或者您可以从 Github 获取最新代码并使用以下方式安装它们,
$ git clone git://github.com/urllib3/urllib3.git
$ cd urllib3
$ python setup.py install
然后你准备好了,
只需使用导入 urllib3,
import urllib3
在这里,您需要一个 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
如 urrlib3
文档中所述,urllib3
带来了 Python 标准库中缺少的许多关键功能。
线程安全。
连接池。
客户端 SSL/TLS 验证。
使用多部分编码的文件上传。
重试请求和处理 HTTP 重定向的助手。
支持 gzip 和 deflate 编码。
对 HTTP 和 SOCKS 的代理支持。
100% 的测试覆盖率。
请按照用户指南了解更多详细信息。
响应内容(HTTPResponse 对象提供状态、数据和标头属性)
使用带有响应内容的 io Wrappers
创建查询参数
urllib3的高级使用
要求
requests 在后台使用 urllib3
并使得创建 requests
和检索数据变得更加简单。一方面,keep-alive 是 100% 自动的,而 urllib3
不是。它也有事件钩子,当一个事件被触发时,它会调用一个回调函数,比如接收一个响应。在 requests
中,每个请求类型都有自己的函数。因此,您无需创建连接或池,而是直接获取 URL。
使用 pip 安装 requests
只需运行
pip install requests
或者你可以从源代码安装,
$ git clone git://github.com/psf/requests.git
$ cd requests
$ python setup.py install
然后,import requests
这里可以参考官方的documentation,会话对象、SSL验证、Event Hooks等高级用法请参考这个url。
urllib3
,但不知道我应该使用它还是 requests
。现在,我对如何做出该决定感到了解。接受的答案对 requests
进行了很好的细分,但没有将其与替代方案区分开来。
要获取 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) 返回一个实例
请求 request.get(url) 返回一个 requests.models.Response
您通常应该使用 urllib2,因为这有时会通过接受 Request 对象使事情变得更容易一些,并且还会在协议错误时引发 URLException。但是,对于 Google App Engine,您也不能使用。您必须使用 Google 在其沙盒 Python 环境中提供的 URL Fetch API。
我发现上述答案中缺少的一个关键点是 urllib 返回类型为 <class http.client.HTTPResponse>
的对象,而 requests
返回 <class 'requests.models.Response'>
。
因此,read() 方法可以与 urllib
一起使用,但不能与 requests
一起使用。
PS : requests
已经拥有如此多的方法,几乎不需要像 read()
那样的方法了;>
不定期副业成功案例分享
urllib
,并且它的文档还正式指出“Requests 包推荐用于更高级别的 HTTP 客户端接口。”在21.6. urllib.request — Extensible library for opening URLs — Python 3.6.3 documentation,而urllib3
是requests
使用的一个很棒的库。urllib.parse()
有印象 request has no replacement