繁体   English   中英

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

[英]What are the differences between the urllib, urllib2, urllib3 and requests module?

在 Python 中, urlliburllib2urllib3requests模块之间有什么区别? 为什么是三个? 他们似乎在做同样的事情......

我知道已经有人说过了,但我强烈推荐requests Python 包。

如果您使用过python以外的语言,您可能会认为urlliburllib2易于使用,代码不多,而且功能强大,这是我以前的想法。 但是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 库。 尽管名称相似,但它们并不相关:它们具有不同的设计和不同的实现。

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

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

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

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

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

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

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

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

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

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

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

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

urllib2.urlopen接受Request类的实例或url,而urllib.urlopen仅接受url。

此处也进行了类似的讨论: http : //www.velocityreviews.com/forums/t326690-urllib-urllib2-what-is-the-difference.html

我喜欢urllib.urlencode函数,它似乎不存在于urllib2

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

要获取 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

我认为所有的答案都很好。 但是关于 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% 的测试覆盖率。

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

requests

requests 在urllib3使用urllib3 ,使发出requests和检索数据变得更加简单。 一方面,保持活动是 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

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

您通常应该使用 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() ;>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM