911

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

4

11 回答 11

820

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

如果你用过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
  • 线程安全。
于 2013-02-11T00:32:09.150 回答
225

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。

于 2010-01-07T03:43:08.630 回答
132

这是我对各种“urllibs”之间关系的理解:

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

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

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

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

于 2020-08-03T16:34:22.573 回答
63

urlliburllib2都是 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查看请求是否成功

于 2016-09-10T04:14:30.583 回答
29

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

于 2017-10-30T18:42:14.237 回答
14

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

于 2016-04-27T01:07:59.563 回答
11

我喜欢这个urllib.urlencode功能,它似乎不存在于urllib2.

>>> urllib.urlencode({'abc':'d f', 'def': '-!2'})
'abc=d+f&def=-%212'
于 2010-01-07T03:51:08.697 回答
10

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

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

这里可以参考官方文档,会话对象、SSL验证、Event Hooks等高级用法请参考这个网址

于 2020-06-20T19:30:19.523 回答
9

要获取 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()函数返回不同的类型:

  • Python2urllib.request.urlopen()返回一个http.client.HTTPResponse
  • Python3urllib.urlopen(url)返回一个instance
  • 请求request.get(url)返回一个requests.models.Response
于 2017-12-20T02:29:06.593 回答
5

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

于 2010-01-07T03:36:46.977 回答
3

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

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

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

于 2018-12-14T00:04:11.217 回答