在使用 Python 进行网络编程时,经常用到一些网络请求的操作。随着互联网应用的不断增多,从简单的 HTTP 请求到复杂的 RESTful 接口,需要用到的库也越来越多。其中,urllib3 库就是一个非常强大的 Python 第三方库,它能够帮助我们更加方便快捷地进行网络请求操作。

什么是 urllib3?

urllib3 是 Python 的一个第三方库,它是 Python 标准库 urllib 和 httplib 的完美结合,并为它们提供了一些非常有用的功能扩展。

主要特点包括:

  • 连接池管理
  • 请求重试
  • HTTP(S) 代理支持
  • 支持文件上传
  • 支持在线文件压缩
  • 支持单位换算(比如将字节转成 MB)

安装 urllib3

安装 urllib3 可以通过 pip 进行安装,打开命令行并输入以下命令:

1
pip install urllib3

即可安装 urllib3。

常用方法

urlencode

urllib3中,urlencode是一个用于将字典或元组列表编码为URL查询字符串的工具函数。这个函数可以将提供的参数序列化为符合HTTP规范的URL编码格式。

使用urlencode函数,你可以将字典或元组列表编码为查询字符串,然后将其添加到URL中以向服务器发送GET请求或POST请求。

下面是urllib3urlencode函数的使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
from urllib.parse import urlencode
from urllib3 import PoolManager

data = {'username': 'Alice', 'password': '123456'}
encoded_data = urlencode(data)

url = 'https://www.example.com/login?' + encoded_data

http = PoolManager()
response = http.request('GET', url)

print(response.data)

在上面的例子中,我们首先创建了一个名为data的字典,其中包含了用户名和密码的键值对。然后,我们使用urlencode函数将这个字典编码为URL查询字符串,并将其存储在encoded_data变量中。接下来,我们将这个编码后的查询字符串添加到URL中并发送GET请求。最后,我们打印服务器响应的内容。

请注意,urlencode函数在导入时是从urllib.parse模块中引入的,而不是直接从urllib3模块中引入。这是因为urlencode函数实际上是来自Python内置的标准库urllib.parse中的函数。

如何使用 urllib3

发送 HTTP 请求

在使用 urllib3 发送 HTTP 请求时,需要创建一个 PoolManager 的对象,通过这个对象来完成请求。具体的代码实现如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
import urllib3

http = urllib3.PoolManager()

response = http.request("GET", "www.baidu.com")
# 状态码
print("状态码:" + str(response.status))
# 响应头
header = response.info()
print("响应头信息如下")
for key in header.keys():
print(key, ":", header.get(key))

这段代码的作用是发送一个 GET 请求,请求百度的网址。执行后我们可以获得到 response 的信息,比如其状态码、响应头、响应体等等信息。

POST 请求

发送 POST 请求时,需要使用到 request() 函数的 body 参数,该参数的内容为一个字符串,表示 POST 请求的数据。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import urllib3

http = urllib3.PoolManager()

data = {
'username': 'john',
'password': 'pass',
}
encoded_data = urllib3.encode_multipart_formdata(data)

response = http.request(
'POST',
'http://httpbin.org/post',
body=encoded_data[0],
headers={'Content-Type': encoded_data[1]}
)
print(response.status)

HTTPS 支持

urllib3 库通过 Certifi 库提供对 HTTPS 连接的支持。它处理了与 SSL/TLS 握手、证书验证和加密通信等相关的复杂细节,以提供简单易用的 HTTPS 客户端功能。

1
2
3
4
5
6
7
import urllib3
import certifi

http = urllib3.PoolManager(ca_certs=certifi.where())
response = http.request('GET', 'https://baidu.com')
print(response.status)
print(response.data.decode('utf-8'))

连接池

urllib3 使用连接池来管理 HTTP 请求时建立的连接,这样可以提高请求的效率,减少连接的建立和关闭的开销。如果你需要发送多个请求,就可以使用连接池来重用已经建立好的连接,并发出多个请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import urllib3
import threading

http = urllib3.PoolManager(num_pools=10, maxsize=3)


def send_request(_url):
response = http.request('GET', _url)
print(response.status)


threads = []
urls = ['https://www.baidu.com/', 'https://www.cheneyblog.com/']
for url in urls:
t = threading.Thread(target=send_request, args=(url,))
t.start()
threads.append(t)

for t in threads:
t.join()

这里创建了一个有 10 个连接池,每个连接池最多可以建立 3 个连接的 PoolManager 对象,通过多线程同时请求百度和 cheneyblog 的网站。可以看到,每个连接池最多只有 3 个连接,这样就可以有效地节约资源。