urllib
在 Python 中,urllib2
、urllib3
和requests
模块之间有什么区别?为什么有三个?他们似乎在做同样的事情......
11 回答
我知道已经说过了,但我强烈推荐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。
这是我对各种“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。
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'
我认为所有的答案都很好。但是关于 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
requestsurllib3
在后台使用,使制作requests
和检索数据变得更加简单。一方面,keep-alive 是 100% 自动的,而urllib3
它不是。它还有事件钩子,当事件被触发时调用回调函数,比如接收响应 In requests
,每个请求类型都有自己的函数。因此,您无需创建连接或池,而是直接获取 URL。
requests
使用 pip安装只需运行
pip install requests
或者你可以从源代码安装,
$ git clone git://github.com/psf/requests.git
$ cd requests
$ python setup.py install
然后,import 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)
返回一个instance
- 请求
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()
;>