← 返回学习中心ARC LAB / LEARNING NOTES

Python 专区

Python Requests

使用本地 HTTP 实验掌握请求、JSON、超时、会话与异常处理。

展开本篇目录

一、为什么学习 Requests?

Requests 用于通过 HTTP 获取或提交数据,常见于 API 调用、文件下载和服务集成。库名是 requests,不是 request;import requests。它不会像浏览器那样自动执行网页 JavaScript。

先修 HTTP、JSON 与 Python 异常处理。路线:发请求 → 看响应 → 校验状态 → 解析内容 → 超时与异常 → 会话与下载。本文实验使用临时本地服务,不依赖公共网站的可用性。

python -m pip install requests

请求包含方法、地址、参数和正文;响应包含状态码、响应头和内容

二、GET 与查询参数

import requests
response = requests.get("http://127.0.0.1:8000/scores",
params={"team":"A"}, timeout=(2,5))
response.raise_for_status()
data = response.json()

这段是接口调用示例,要求 8000 端口已有服务;本篇完整脚本会自动分配空闲端口,无需手动搭服务。params 负责查询参数编码,不要用字符串拼接包含空格、中文或特殊符号的 URL。

timeout=(2,5) 分别设置连接与读取超时,它不是“整个请求绝对最多 7 秒”的总时限;重定向、重试和持续读取都可能影响总时长。

三、先看响应状态,再解析业务数据

属性/方法 含义
status_code HTTP 状态码
headers 响应头
text 解码后的文本
content 字节内容
json() 将响应体解析为 Python 对象
raise_for_status() 对 4xx/5xx 抛 HTTPError
url/history 最终地址与重定向历史

JSON 解析成功不代表 HTTP 成功;HTTP 200 也不保证响应一定是合法 JSON,更不保证满足业务约定。

response.raise_for_status()
data = response.json()
if not isinstance(data, dict) or not isinstance(data.get("scores"), list):
raise ValueError("响应结构不符合约定")

四、POST:JSON、表单与文件

response = requests.post(url, json={"name":"ArcLab"}, timeout=(2,5))
response.raise_for_status()

这里 url 需是你有权调用的服务端点。json= 编码 JSON 并设置相应类型;data={...} 通常发送表单。不要同时传入几种正文参数,再猜服务器究竟收到什么。

上传文件的接口模式:

with open("report.csv","rb") as file:
response = requests.post(url, files={"file":file}, timeout=(2,10))
response.raise_for_status()

字段名 file 必须与接口约定一致,文件应使用上下文管理器关闭。POST 可能产生真实业务副作用,练习时使用自己的测试服务。

五、Session、请求头与身份信息

with requests.Session() as session:
session.headers.update({"User-Agent":"ArcLab-learning/1.0"})
response = session.get(url, timeout=(2,5))
response.raise_for_status()

Session 复用连接并保留 Cookie,适合连续调用同一个服务。认证方式以 API 文档为准;Token 从环境变量读取,不写进源码、日志、URL 查询字符串和截图。

默认 HTTPS 校验应保留。遇到证书异常应检查系统时间、证书链和代理配置,不要把 verify=False 当通用修复。

六、异常分类与可控重试

try:
response = requests.get(url, timeout=(2,5))
response.raise_for_status()
payload = response.json()
except requests.exceptions.Timeout:
print("连接或读取超时")
except requests.exceptions.HTTPError as exc:
print("HTTP 状态失败:", exc.response.status_code)
except requests.exceptions.JSONDecodeError:
print("响应不是合法 JSON")
except requests.exceptions.RequestException as exc:
print("其他请求错误:", type(exc).__name__)

不要 except Exception: pass。对限流 429、暂时性服务错误,可按接口规则使用有限次数、退避与 Retry-After;不要无限循环。自动重试写入请求可能重复创建记录,应先了解幂等性和服务端去重机制。

七、流式下载与资源释放

from pathlib import Path
with requests.get(url, stream=True, timeout=(2,10)) as response:
response.raise_for_status()
with Path("download.bin").open("wb") as file:
for chunk in response.iter_content(chunk_size=65536):
if chunk:
file.write(chunk)

大文件避免一次全部读进内存。真实项目还应限制允许的大小、校验内容类型或摘要,并先写临时文件,成功后再替换目标,防止半截文件被当成有效结果。URL 和文件名应来自可信约定,不直接拿服务端字符串覆盖任意路径。

八、Requests 与 Selenium 怎样选?

需求 优先考虑
已知 JSON API、下载接口 Requests
需要执行页面 JavaScript Selenium 或其他浏览器自动化
需要验证点击、输入和可见状态 Selenium
只需抓 HTML 文本 Requests 加 HTML 解析器,视授权与页面情况

仅把浏览器地址复制给 Requests,并不自动拥有登录状态,也不会触发页面脚本请求。不要用它绕过站点访问限制或高频影响服务。

九、完整本地实验与结果

下载 requests_demo.py:

python requests_demo.py

脚本在 127.0.0.1 随机空闲端口启动临时教学服务,运行结束后自动关闭。只在这个本地实验中关闭系统代理继承,避免本机代理干扰。

本地实验四种实测结果:GET 成功、POST 成功、404 异常、200 非法 JSON 异常

GET: 200 {'team': 'A', 'scores': [80, 90]}
POST: 200 {'received': {'name': 'ArcLab'}}
404: HTTPError caught
200 with invalid JSON: JSONDecodeError caught

服务端使用 Python 标准库实现,只用于教学,不应直接作为公网生产服务器部署。测试同时验证成功响应与两种不同的错误,避免只检查“能连上”。

十、练习与排错

  1. 将 GET 参数改为 B,预测 scores 为 [70,0] 并增加断言。
  2. 请求不存在的路径,检查 HTTPError,而不是继续假设有 scores 字段。
  3. 为返回 JSON 缺少字段的情况补验证,区分网络错误和业务格式错误。
  4. 用 mock 或本地服务测试超时,不依赖某个公网地址恰好响应很慢。
  5. 小项目:调用一个有明确许可的公开数据 API,记录文档、参数、时间、异常策略与输出格式;凭据不提交。

常见问题:连接被拒绝检查服务与端口;乱码检查 encoding/响应头;JSON 失败先看状态和少量脱敏正文;SSL 失败检查证书与代理;代码卡住检查是否设置 timeout。

十一、学习资料

← 继续探索学习路径反馈问题 ↗