Requests

技术栈
工具链
pythonrequestsHTTP网络请求RESTAPI

概览

Requests

Requests 是 Python 最受欢迎的 HTTP 库,由 Kenneth Reitz 于 2011 年创建。它以「HTTP for Humans」为理念,将复杂的 HTTP 请求简化到极致。

解决什么问题

  • 用最少的代码发送 GET / POST / PUT / DELETE 等 HTTP 请求
  • 自动处理 Cookie、Session、SSL 验证、重定向等繁琐细节
  • 替代标准库 urllib 的复杂接口

关键特性

  • 简洁直观的 API:requests.get(url) 一个函数搞定
  • 自动解压 gzip/deflate 响应
  • Session 对象持久化 Cookie 和连接池
  • 内置 JSON 解析:resp.json()
  • 支持文件上传、流式下载、超时控制

安装

环境准备

  • 操作系统: Windows / macOS / Linux 均可
  • Python 版本: 2.7 或 3.5 及以上(强烈推荐 3.8+)
  • 前置依赖: urllib3certificharset-normalizeridna(pip 会自动安装)

安装命令

# 基础安装
pip install requests

# 使用清华镜像加速
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple

验证安装:

import requests
print(requests.__version__)

常见安装问题

Q: pip 安装后 import 报 ModuleNotFoundError
确认当前 Python 环境与 pip 对应:

which python
which pip
# 或使用 python -m pip 确保一致性
python -m pip install requests

Q: SSL 证书验证失败

  • 更新 certifi 包:pip install --upgrade certifi
  • 临时绕过(不推荐生产使用):requests.get(url, verify=False)

Q: 使用虚拟环境时安装到了全局
确保先激活虚拟环境:

python -m venv venv
source venv/bin/activate  # Linux/macOS
# venv\Scripts\activate   # Windows
pip install requests

示例

Requests Hello World:GET 请求与 JSON 解析

目标

发送一个 GET 请求到公开 API,解析 JSON 响应,并处理常见 HTTP 状态码。

完整代码

import requests

# 1. 基础 GET 请求
url = "https://api.github.com/repos/psf/requests"
response = requests.get(url)

# 2. 检查状态码
print(f"状态码: {response.status_code}")
print(f"Content-Type: {response.headers['Content-Type']}")

# 3. 解析 JSON
if response.status_code == 200:
    data = response.json()
    print(f"仓库名: {data['full_name']}")
    print(f"Stars: {data['stargazers_count']}")
    print(f"描述: {data['description']}")
else:
    print(f"请求失败: {response.text[:200]}")

# 4. 带 Query 参数的请求
params = {"q": "python requests", "sort": "stars"}
resp = requests.get("https://api.github.com/search/repositories", params=params)
if resp.ok:
    results = resp.json()
    print(f"\n搜索到 {results['total_count']} 个仓库")
    for repo in results["items"][:3]:
        print(f"  - {repo['full_name']} ⭐{repo['stargazers_count']}")

运行步骤

pip install requests
python hello_requests.py

预期输出

状态码: 200
Content-Type: application/json; charset=utf-8
仓库名: psf/requests
Stars: 52300+
描述: A simple, yet elegant, HTTP library.

搜索到 150000+ 个仓库
  - psf/requests ⭐52300+
  - httpie/cli ⭐35000+
  - encode/httpx ⭐14000+

教程

Requests 从入门到精通

背景

HTTP 是互联网应用层最核心的协议。Requests 将这个协议中每次都需要处理的 headers、cookies、认证、超时等细节封装得极其优雅,让开发者专注于业务逻辑。


第 1 章:HTTP 方法速览

import requests

# GET — 获取资源
r = requests.get("https://httpbin.org/get")

# POST — 创建资源
r = requests.post("https://httpbin.org/post", json={"name": "Alice"})
r = requests.post("https://httpbin.org/post", data={"name": "Alice"})  # form 编码

# PUT — 更新资源
r = requests.put("https://httpbin.org/put", data={"key": "value"})

# DELETE — 删除资源
r = requests.delete("https://httpbin.org/delete")

# HEAD — 只获取响应头
r = requests.head("https://httpbin.org/get")

# PATCH — 部分更新
r = requests.patch("https://httpbin.org/patch", data={"key": "value"})

第 2 章:Session 与持久化连接

# Session 保持连接和 Cookie
s = requests.Session()
s.headers.update({"User-Agent": "MyApp/1.0"})
s.auth = ("username", "password")

# 共享连接池,自动管理 Cookie
login_resp = s.post("https://example.com/login", json={"user": "a", "pass": "b"})
dashboard = s.get("https://example.com/dashboard")

# Session 级别重试策略
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503])
s.mount("https://", HTTPAdapter(max_retries=retry))

第 3 章:文件上传与流式下载

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

# 流式下载大文件
with requests.get("https://example.com/large_file.zip", stream=True) as r:
    r.raise_for_status()
    with open("large_file.zip", "wb") as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)

第 4 章:认证方式

# Basic Auth
requests.get("https://api.example.com", auth=("user", "pass"))

# Bearer Token
headers = {"Authorization": "Bearer eyJhbGciOi..."}
requests.get("https://api.example.com", headers=headers)

# OAuth2 客户端凭证
from requests.auth import HTTPBasicAuth
auth = HTTPBasicAuth("client_id", "client_secret")
data = {"grant_type": "client_credentials"}
r = requests.post("https://auth.example.com/token", auth=auth, data=data)
token = r.json()["access_token"]

第 5 章:异常处理与超时

try:
    r = requests.get("https://api.example.com", timeout=(3.0, 10.0))
    # timeout=(连接超时, 读取超时)
    r.raise_for_status()  # 非 2xx 抛出 HTTPError
except requests.exceptions.Timeout:
    print("请求超时")
except requests.exceptions.ConnectionError:
    print("连接失败,检查网络或 URL")
except requests.exceptions.HTTPError as e:
    print(f"HTTP 错误: {e}")
except requests.exceptions.RequestException as e:
    print(f"请求异常: {e}")

思考题

  1. Session 和直接调用 requests.get() 有什么区别?什么场景下必须使用 Session?
  2. stream=True 下载时,iter_contentiter_lines 分别适合什么场景?
  3. 如何为 Requests 添加自定义的 DNS 解析(如使用 DoH)?