人人都会AI编程

17.2 HTTP 请求:urllib、requests 库用法

更新时间:2026-07-12

在 Python 中完成 HTTP 请求,有两大选择:标准库自带的 urllib 和第三方库 requests。它们都能发送 GET、POST 等请求,但易用性和代码量天差地别。实际开发中,requests 的使用频率远高于 urllib

urllib — 内置基础方案

urllib 是 Python 标准库的一部分,无需安装即可使用。它由四个模块组成:

  • urllib.request:发送 HTTP 请求,获取响应。
  • urllib.error:处理请求过程中的异常。
  • urllib.parse:解析 URL,处理查询参数。
  • urllib.robotparser:解析 robots.txt

一个典型的 GET 请求:

from urllib import request, parse

url = "https://httpbin.org/get?name=python"

# 发送请求
with request.urlopen(url) as response:
    html = response.read().decode('utf-8')
    print(html)

带参数的 GET 请求:

params = {"q": "python", "page": 1}
query_string = parse.urlencode(params)
url = f"https://httpbin.org/get?{query_string}"

with request.urlopen(url) as response:
    print(response.status, response.read().decode())

发送 POST 请求:

import json

data = {"username": "admin", "password": "123456"}
data_bytes = json.dumps(data).encode('utf-8')
req = request.Request("https://httpbin.org/post", data=data_bytes, method='POST')
req.add_header('Content-Type', 'application/json')

with request.urlopen(req) as response:
    print(response.read().decode())

urllib 的局限:

  • 代码繁琐:需要自己拼接参数、编码数据、添加头信息、处理 cookie 等。
  • 缺少高级功能:没有自动重定向跟踪、会话保持、连接池等便捷特性。
  • 错误处理不够直观:需要捕获 URLErrorHTTPError 等异常。
  • 通常只推荐在无法安装第三方库的受限环境中使用。

requests — 人性化的 HTTP 客户端

requests 是目前 Python 生态中事实上的 HTTP 请求标准库,它完美诠释了“API 设计应该为用户提供最直观的体验”。安装只需一行:

pip install requests

基础用法一览:

import requests

# GET 请求
response = requests.get('https://httpbin.org/get', params={'q': 'python'})
print(response.status_code)       # 状态码
print(response.text)               # 响应文本
print(response.json())             # 自动解析 JSON

# POST 请求 - 表单
data = {'username': 'admin', 'password': '123'}
r = requests.post('https://httpbin.org/post', data=data)

# POST 请求 - JSON
import json
r = requests.post('https://httpbin.org/post', json=data)
print(r.json())

# 设置请求头
headers = {'User-Agent': 'my-app/1.0', 'Authorization': 'Bearer token123'}
r = requests.get('https://httpbin.org/headers', headers=headers)

# 超时设置
r = requests.get('https://httpbin.org/delay/3', timeout=2)  # 2秒超时,会抛异常

# 文件上传
files = {'file': open('test.txt', 'rb')}
r = requests.post('https://httpbin.org/post', files=files)

高级特性:

  • 会话对象(Session):保持 cookie 和连接池,避免多次请求时的重复握手。
s = requests.Session()
s.headers.update({'User-Agent': 'my-app'})
s.get('https://example.com/login')
r = s.get('https://example.com/dashboard')  # 自动携带 cookie
  • 响应处理response.content 获取原始字节,适合下载图片、视频等二进制文件。
  • 认证:支持基本认证、摘要认证、OAuth 等,简单场景直接用参数:
requests.get('https://api.example.com', auth=('user', 'pass'))
  • 代理与 SSL:通过 proxies 参数设置代理,verify=False 跳过 SSL 验证(仅测试用)。
  • 自动重定向:默认开启,可以通过 allow_redirects=False 关闭。

常见问题与实用提示

  1. 超时一定要设:永远不要使用无超时的 requests.get(),否则遇到故障会无限等待。
  2. 异常处理:捕获 requests.exceptions.RequestException 来统一处理网络错误、超时等。
  3. 大文件下载:用 stream=True 并分块读取,避免一次性加载到内存。
with requests.get(url, stream=True) as r:
    with open('large.zip', 'wb') as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)
  1. 编码问题response.text 会自动根据响应头推断编码,若不准确可指定 r.encoding = 'utf-8'
  2. 避免重复创建 Session:对于需要多次访问同一站点的场景,使用 Session 复用连接,提升性能。

urllib vs requests 选择建议

| 场景 | 推荐库 |
|--------------------------|------------|
| 生产环境核心业务 | requests |
| 受限环境,无第三方库 | urllib |
| 简单测试或一次性脚本 | requests |
| 底层网络控制需求 | urllib |

总结:只要环境允许,直接用 requests。它已经帮你做好了绝大多数 HTTP 编程中容易出错的脏活累活,让你能用最少的代码完成最可靠的请求。