在 Python 中,这两种建立网络连接的方式之间的实际区别是什么?

What is the practical difference between these two ways of making web connections in Python?

我注意到有几种方法可以启动 http 连接以进行网络抓取。我不确定是否有一些是更新的和最新的编码方式,或者它们是否只是具有不同优点和缺点的不同模块。更具体地说,我试图了解以下两种方法之间的区别,您会推荐什么?

1) 使用 urllib3:

http = PoolManager()
r = http.urlopen('GET', url, preload_content=False)
soup = BeautifulSoup(r, "html.parser")

2) 使用请求

html = requests.get(url).content
soup = BeautifulSoup(html, "html5lib")

这两个选项除了需要导入不同模块这一简单事实外,还有什么区别?

在幕后,requests 使用 urllib3 完成大部分 http 繁重工作。如果使用得当,应该大体相同,除非你需要更高级的配置。

除了,在您的特定示例中,它们相同:

在 urllib3 示例中,您重新使用了连接,而在请求示例中,您没有重新使用连接。您可以通过以下方式判断:

>>> import requests
>>> requests.packages.urllib3.add_stderr_logger()
2016-04-29 11:43:42,086 DEBUG Added a stderr logging handler to logger: requests.packages.urllib3
>>> requests.get('https://www.google.com/')
2016-04-29 11:45:59,043 INFO Starting new HTTPS connection (1): www.google.com
2016-04-29 11:45:59,158 DEBUG "GET / HTTP/1.1" 200 None
>>> requests.get('https://www.google.com/')
2016-04-29 11:45:59,815 INFO Starting new HTTPS connection (1): www.google.com
2016-04-29 11:45:59,925 DEBUG "GET / HTTP/1.1" 200 None

要像在 urllib3 PoolManager 中那样开始重新使用连接,您需要发出请求 session

>>> session = requests.session()
>>> session.get('https://www.google.com/')
2016-04-29 11:46:49,649 INFO Starting new HTTPS connection (1): www.google.com
2016-04-29 11:46:49,771 DEBUG "GET / HTTP/1.1" 200 None
>>> session.get('https://www.google.com/')
2016-04-29 11:46:50,548 DEBUG "GET / HTTP/1.1" 200 None

现在 等同于您使用 http = PoolManager() 所做的事情。请注意:urllib3 是一个较低级别的更明确的库,因此您明确地创建了一个池,并且您将明确地需要指定 your SSL certificate location,例如。这是一两行额外的工作,但如果这正是您要找的东西,那么它也有更多的控制权。

说了这么多,对比就变成了:

1) 使用 urllib3:

import urllib3, certifi
http = urllib3.PoolManager(ca_certs=certifi.where())
html = http.request('GET', url).read()
soup = BeautifulSoup(html, "html5lib")

2) 使用请求:

import requests
session = requests.session()
html = session.get(url).content
soup = BeautifulSoup(html, "html5lib")