urllib,urllib2,urllib3和请求模块之间有什么区别?


750

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


77
要求是最好的。
Yarin


75
请求使用urllib3。3是一个更大的数字
兄弟

2
摘要:requests大部分时间使用。有时urllib2可以工作,但是需要更多代码,并且不够优雅。不要用urllib
Trevor Boyd Smith,

10
应该更新此问题,以澄清urllibPython 3中的另一个选择,已通过各种方式进行了清理。但值得庆幸的是,官方文档还指出“ 建议将请求包用于更高级别的HTTP客户端接口。 ”在21.6。urllib.request —用于打开URL的可扩展库— Python 3.6.3文档
nealmcb

Answers:


714

我知道已经有人说过了,但我强烈建议您使用requestsPython软件包。

如果您使用的是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.6—3.4
  • 线程安全的。

32
我选择此作为答案,因为原始答案已过时。因此,如果您想知道为什么这个答案比76个投票高出一个答案,那是因为Requests是处理事务的新方法。
Paul Biggar

132
@PaulBiggar,您说这是最好的答案。但这并不能真正回答问题。我来这里是为了了解urllib和urllib2之间的区别。特别是关于url编码功能。答案:使用请求!;)只是说您可能想澄清这个问题。就目前而言,Crast的答案实际上确实完美地回答了这个问题。
2013年

2
这将有助于注意到Python 3文档还有另一个独特的库urllib,并且其文档还正式指出“ 建议将Requests软件包用于更高级别的HTTP客户端接口。 ”在21.6。urllib.request —用于打开URL的可扩展库— Python 3.6.3文档,这urllib3requests
nealmcb

好除了我的印象中要求有没有替代urllib.parse()
鲍勃·斯坦因

同意。使用@PaulBiggar-请求似乎确实是事实。实际上,我到达这里是基于urllib(和其他版本)不起作用或与请求相比不是最优的。
DL

205

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。


1
有人如何使用urllib2创建带有编码查询字符串的url?这是我使用urllib的唯一原因,并且我想确保以最新/最好的方式进行操作。
Gattster 2010年

2
就像我上面的例子中,使用urlopen()Requesturllib2的,并使用urlencode()urllib的。只要确保使用正确的urlopen,使用这两个库都不会造成真正的危害。[urllib docs] [1]清楚地表明使用此方法是公认的用法。[1]:docs.python.org/library/urllib2.html#urllib2.urlopen
Crast 2010年

我用这个要点是为了urllib2.urlopen; 也包含其他变体。
Andrei-Niculae Petre 2014年

urllib2不支持放置或删除,这很
麻烦


46

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

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

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

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

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

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

3)Requests还具有更方便的错误处理方式。如果您的身份验证失败,则urllib2将引发urllib2.URLError,而Requests将返回正常的响应对象。您需要通过boolean response.ok查看所有请求是否成功


10
urllib3呢?
PirateApp '18 -4-6

1
@PirateApp 请求建立在urllib3之上。我认为直接使用urllib3的代码可以提高效率,因为它可以让您重用会话,而请求(至少是请求2,每个人都使用一个)会为每个请求创建一个,但不要在此引用我。两者都不是标准库的一部分(至今
Boris,

12

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


12

仅添加到现有答案中,我看不到有人提到python请求不是本机库。如果可以添加依赖项,那么请求就可以了。但是,如果您试图避免添加依赖项,则urllib是一个本机python库,已经可供您使用。


11

我喜欢此urllib.urlencode功能,并且似乎不存在urllib2

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

4
请注意,由于urlencode不能直接处理<unicode>对象,因此请小心-您必须先对它们进行编码,然后再将它们发送到urlencode(u'blá'.encode('utf-8')或其他格式)。

@ user18015:我认为这不适用于Python 3,您能澄清一下吗?
Janus Troelsen

正如我在上面提到的,这个问题和各种答案都应该更新,以阐明urllibPython 3中的另一个选择是以各种方式进行清理。但值得庆幸的是,官方文档还指出“ 建议将请求包用于更高级别的HTTP客户端接口。 ”在21.6。urllib.request-用于打开URL的可扩展库
-Python

urllib2在Python 3中根本不存在
Boris

7

要获取网址的内容:

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.

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

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

5

通常应该使用urllib2,因为通过接受Request对象有时会使事情变得容易一些,并且还会在协议错误时引发URLException。但是,借助Google App Engine,您将无法使用任何一种。您必须使用Google在其沙盒Python环境中提供的URL Fetch API


2
您关于appengine的说法并不完全正确。您现在可以立即在App Engine中使用httplib,urllib和urllib2(它们是url提取的包装器,这样做是为了使更多代码与appengine兼容。)
Crast 2010年

啊,一定是新手。我的代码最后一次尝试失败,必须重新
编写


urllib2在Python 3中根本不存在
Boris

@Boris迁移到urllib.requesturllib.error
艾伦

1

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.