Python利用urllib3库发送请求的完全指南
作者:detayun
urllib3 是 Python 中最流行的 HTTP 客户端库之一,本文全面介绍了PythonHTTP客户端库urllib3的核心用法,对比了其与内置urllib和requests的优势,重点突出连接池和线程安全特性,希望对大家有所帮助
urllib3 是 Python 中最流行的 HTTP 客户端库之一,相比内置的 urllib,它更简洁、更强大、更易用。本文从零开始,覆盖日常开发中 90% 的请求场景。
一、为什么选 urllib3?
| 对比项 | urllib(内置) | requests(第三方) | urllib3 |
|---|---|---|---|
| 上手难度 | 较高 | 极低 | 低 |
| 连接池 | 需手动管理 | 内置 | 内置(核心优势) |
| 线程安全 | 否 | 否 | 是 |
| 性能 | 一般 | 一般 | 更优 |
requests 底层其实就是用 urllib3 实现的。学会 urllib3,等于理解了 requests 的内核。
二、安装
pip install urllib3
三、GET 请求 —— 最基础的用法
import urllib3
http = urllib3.PoolManager() # 创建连接池(推荐)
resp = http.request('GET', 'https://httpbin.org/get')
print(resp.status) # 200
print(resp.data) # b'{"args":{}, ...}'
print(resp.headers) # 响应头
关键点:
PoolManager()内部维护连接池,复用 TCP 连接,性能远好于每次新建连接- 响应数据是
bytes,需要解码:resp.data.decode('utf-8')
四、带参数的 GET 请求
resp = http.request(
'GET',
'https://httpbin.org/get',
fields={'key': 'value', 'page': 1} # 自动拼接 ?key=value&page=1
)
print(resp.data.decode('utf-8'))
等价于手动拼接 URL:
from urllib.parse import urlencode
url = 'https://httpbin.org/get?' + urlencode({'key': 'value'})
但用 fields 更安全,urllib3 会自动处理编码,避免特殊字符导致的问题。
五、POST 请求 —— 三种常见场景
5.1 表单提交(application/x-www-form-urlencoded)
resp = http.request(
'POST',
'https://httpbin.org/post',
fields={'username': 'admin', 'password': '123456'}
)
5.2 JSON 提交(application/json)
import json
resp = http.request(
'POST',
'https://httpbin.org/post',
body=json.dumps({'username': 'admin'}),
headers={'Content-Type': 'application/json'}
)
5.3 上传文件(multipart/form-data)
with open('photo.jpg', 'rb') as f:
resp = http.request(
'POST',
'https://httpbin.org/post',
fields={'file': ('photo.jpg', f, 'image/jpeg')}
)
格式:('文件名', 文件对象, 'MIME类型')
六、自定义请求头
resp = http.request(
'GET',
'https://api.example.com/data',
headers={
'User-Agent': 'my-app/1.0',
'Authorization': 'Bearer xxxxxxx'
}
)
常见坑: User-Agent 必加,否则很多接口会直接拒绝(尤其是反爬场景)。
七、超时设置(生产环境必加)
resp = http.request(
'GET',
'https://httpbin.org/delay/5',
timeout=3.0 # 3秒超时,超时抛出 urllib3.exceptions.TimeoutError
)
也可以分别设置连接超时和读取超时:
resp = http.request(
'GET',
'https://example.com',
timeout=(3.0, 10.0) # (连接超时, 读取超时)
)
八、异常处理 —— 别让程序崩溃
import urllib3
from urllib3.exceptions import HTTPError, TimeoutError, MaxRetryError
http = urllib3.PoolManager(retries=3) # 自动重试3次
try:
resp = http.request('GET', 'https://httpbin.org/status/500')
resp.raise_for_status() # 非200状态码抛出 HTTPError
except TimeoutError:
print('请求超时')
except HTTPError as e:
print(f'HTTP错误: {e.response.status}')
except MaxRetryError:
print('重试次数耗尽')
最常用的三个异常:
| 异常 | 触发场景 |
|---|---|
TimeoutError | 超时未响应 |
HTTPError | 非 2xx 状态码 |
MaxRetryError | 重试耗尽仍失败 |
九、进阶:连接池复用(性能关键)
http = urllib3.PoolManager(
num_pools=10, # 最大连接池数量
maxsize=10, # 每个池最大连接数
retries=3, # 自动重试次数
timeout=5.0
)
# 复用同一个 http 对象发送多个请求
r1 = http.request('GET', 'https://api.example.com/users')
r2 = http.request('GET', 'https://api.example.com/orders')
千万不要每次请求都 urllib3.PoolManager(),那等于每次都新建连接池,失去了 urllib3 最大的性能优势。
十、完整实战示例:调用一个 REST API
import urllib3
import json
http = urllib3.PoolManager(timeout=10.0, retries=3)
def call_api(endpoint, data=None, method='GET'):
url = f'https://api.example.com{endpoint}'
kwargs = {
'method': method,
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer your_token_here'
}
}
if data:
kwargs['body'] = json.dumps(data)
try:
resp = http.request(url, **kwargs)
resp.raise_for_status()
return resp.data.decode('utf-8')
except urllib3.exceptions.HTTPError as e:
print(f'API返回错误: {e.response.status} - {e.response.data}')
return None
except urllib3.exceptions.TimeoutError:
print('请求超时')
return None
# 调用
result = call_api('/users', data={'name': 'zhangsan'}, method='POST')
print(result)
总结:速查表
| 需求 | 核心参数 |
|---|---|
| GET 请求 | http.request('GET', url) |
| 带参数 GET | fields={'k': 'v'} |
| POST 表单 | fields={'k': 'v'} |
| POST JSON | body=json.dumps(data), headers={'Content-Type': 'application/json'} |
| 上传文件 | fields={'file': ('name', fp, 'type')} |
| 自定义头 | headers={'Key': 'Value'} |
| 超时 | timeout=3.0 |
| 自动重试 | PoolManager(retries=3) |
urllib3 不花哨,但足够可靠。掌握以上内容,日常接口调用绰绰有余。
到此这篇关于Python利用urllib3库发送请求的完全指南的文章就介绍到这了,更多相关Python urllib发送请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
