urllib、urllib2、urllib3和请求模块有什么区别?

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

436235 次浏览

你通常应该使用urllib2,因为这有时会通过接受Request对象来简化事情,并且还会在协议错误时引发URLException。但是对于Google App Engine,你也不能使用。你必须使用Google在其沙盒Python环境中提供的获取url接口

urllib2提供了一些额外的功能,即urlopen()函数可以允许您指定标头(通常您过去必须使用http,这要冗长得多。)更重要的是,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中,你可以使用http,urllib或urllib2中的任何一个,但它们都只是Google URL Fetch API的包装器。也就是说,你仍然受到相同的限制,例如端口,协议和允许的响应长度。不过,你可以像预期的那样使用库的核心来检索HTTP URL。

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

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

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

如果你使用过python以外的语言,你可能会认为urlliburllib2易于使用,代码不多,功能强大,这就是我过去的想法。但是requests包非常有用和简短,每个人都应该使用它。

首先,它支持完全RESTful 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
  • Kee-Alive&连接池
  • 具有Cookie持久性的会话
  • 浏览器式SSL验证
  • 基本/摘要身份验证
  • 优雅的键/值Cookie
  • 自动减压
  • Unicode响应体
  • 多部分文件上传
  • 连接超时
  • . netrc支持
  • 列表项
  • Python 2.7,3.6-3.9
  • 线程安全。

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

urlliburllib2都是Python模块,它们做URL请求相关的事情,但提供不同的功能。

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

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

要求-请求是一个用Python编写的简单易用的HTTP库。

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

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

3)请求也有更方便的错误处理。如果您的身份验证失败,urllib2将引发urllib2.URLError,而请求将像预期的那样返回一个正常的响应对象。您只需通过布尔response.ok查看请求是否成功

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

要获取url的内容:

try: # Try importing requests first.import requestsexcept ImportError:try: # Try importing Python3 urllibimport urllib.requestexcept AttributeError: # Now importing Python2 urllibimport 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()函数返回不同的类型:

  • Python2urllib.request.urlopen()返回一个http.client.HTTPResponse
  • Python3urllib.urlopen(url)返回一个instance
  • 请求request.get(url)返回requests.models.Response

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

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

附言:requests已经丰富了很多方法,几乎不需要一个方法作为read();>

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

urllib3

使用pip,

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_requests3

正如urrlib3文档中提到的,urllib3带来了Python标准库中缺少的许多关键特性。

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

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

requests

请求在引擎盖下使用urllib3,使创建requests和检索数据变得更加简单。首先,与不是100%自动的urllib3相比,保活是100%自动的。它还具有事件挂钩,当触发事件时调用回调函数,例如接收响应在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

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

  • urllib是最初的Python HTTP客户端,添加到python1.2的标准库中。urllib的早期留档可以在python1.4中找到。

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

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

    urllib2的早期留档可以在python2.1中找到。

Python 3标准库有一个<说明>新增#0,它是旧模块的合并/重构/重写版本。

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

最后,requests在内部使用urllib3,但它的目标是更易于使用的API。