Python requests库教程:从GET请求到Session会话管理完整指南
前言:为什么你需要学习requests库
在Python生态中,requests库是最受欢迎的HTTP客户端库,没有之一。无论是调用REST API、爬取网页数据、与云服务交互,还是搭建自动化脚本,requests都是必选项。Python官方文档甚至称其为”HTTP for Humans”——专为人类设计的HTTP库。
但很多初学者只会用 requests.get() 获取页面内容,遇到需要登录、设置请求头、处理Session会话时就卡住了。本文将带你从零开始,系统掌握requests库的核心用法:从最基础的GET/POST请求,到Cookie自动管理、Session会话保持、请求头自定义、超时重试、以及错误处理。读完本文,你就能用requests搞定日常开发中99%的HTTP请求场景。
环境准备
- Python版本: 3.7+(推荐Python 3.10及以上)
- requests库版本: 2.31+(2026年最新稳定版)
- 系统: Windows / macOS / Linux 均可
安装requests库
pip install requests
验证安装:
$ python -c "import requests; print(requests.__version__)"
2.32.3
步骤一:发送GET请求获取数据
GET请求是最常见的HTTP请求方式,用于从服务器获取资源。以下是一个最简单的例子——获取一个JSON格式的公开API数据:
import requests
# 请求一个公开的JSON API
url = "https://api.github.com/repos/psf/requests"
response = requests.get(url)
# 检查响应状态码
print(f"状态码: {response.status_code}")
# 将响应解析为JSON
data = response.json()
print(f"仓库名: {data['full_name']}")
print(f"Star数: {data['stargazers_count']}")
print(f"描述: {data['description']}")
输出示例:
状态码: 200
仓库名: psf/requests
Star数: 53000+
描述: A simple, yet elegant, HTTP library.
GET请求带参数
很多API需要在URL后附加查询参数。requests的 params 参数能帮你优雅地构建URL:
import requests
# 不用手动拼接 URL,用 params 字典
params = {
"q": "requests",
"sort": "stars",
"order": "desc",
"per_page": 5
}
url = "https://api.github.com/search/repositories"
response = requests.get(url, params=params)
# requests 自动将 params 编码到 URL
print(f"请求的完整URL: {response.url}")
# 输出: https://api.github.com/search/repositories?q=requests&sort=stars&order=desc&per_page=5
data = response.json()
for repo in data["items"]:
print(f"⭐ {repo['full_name']} — {repo['stargazers_count']} stars")
使用 params 的好处:requests会自动处理URL编码(比如中文、特殊符号),避免手动拼接时出错。
步骤二:设置请求头(Headers)
很多API要求客户端在请求头中传递认证信息、指定内容类型或模拟浏览器行为。通过 headers 参数可以轻松设置:
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "application/json",
"Authorization": "Bearer your_token_here" # 如果API需要token
}
url = "https://api.github.com/user"
response = requests.get(url, headers=headers)
if response.status_code == 200:
print("认证成功!")
print(f"用户: {response.json()['login']}")
elif response.status_code == 401:
print("认证失败,请检查Token")
常见请求头说明:
| 请求头 | 作用 |
|---|---|
| User-Agent | 标识客户端类型,很多网站会拦截默认的 “python-requests” |
| Authorization | 携带认证令牌(Bearer Token / Basic Auth) |
| Content-Type | 指定请求体格式(如 application/json) |
| Accept | 告诉服务器客户端期望的响应格式 |
| Cookie | 携带会话Cookie(通常用Session对象自动管理) |
步骤三:发送POST请求提交数据
POST请求用于向服务器提交数据,比如用户登录、创建资源、提交表单等。requests根据提交的数据类型,提供了不同的参数:
3.1 提交JSON数据
使用 json 参数,requests会自动设置 Content-Type: application/json:
import requests
url = "https://jsonplaceholder.typicode.com/posts"
new_post = {
"title": "Python requests 教程",
"body": "这是一篇关于requests库的教程",
"userId": 1
}
response = requests.post(url, json=new_post)
print(f"状态码: {response.status_code}") # 201 Created
print(f"创建的资源ID: {response.json()['id']}")
3.2 提交表单数据
使用 data 参数模拟HTML表单提交:
import requests
url = "https://httpbin.org/post"
form_data = {
"username": "test_user",
"password": "test_pass123"
}
response = requests.post(url, data=form_data)
print(response.json()["form"])
# 输出: {'username': 'test_user', 'password': 'test_pass123'}
3.3 上传文件
import requests
url = "https://httpbin.org/post"
files = {
"file": ("report.txt", "这是文件内容", "text/plain")
}
response = requests.post(url, files=files)
print(response.json()["files"])
# 输出: {'file': '这是文件内容'}
步骤四:管理Session和Cookie
这是日常开发中最重要的技能之一。Session对象可以在多个请求之间自动保持Cookie,让你像浏览器一样维持登录状态。
4.1 为什么需要Session?
每次调用 requests.get() 或 requests.post() 都是独立的请求,不会自动携带之前请求返回的Cookie。如果连续调用一个需要登录的API,每次都要手动传递Cookie,非常麻烦。
requests.Session() 帮你自动搞定这一切:
4.2 Session基础用法
import requests
# 创建Session对象
session = requests.Session()
# 设置全局请求头(所有会话中的请求都会自动带上)
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
# 第一次请求——模拟登录(服务器返回Cookie)
login_url = "https://httpbin.org/cookies/set/sessionid/abc123"
response = session.get(login_url)
print(f"登录响应: {response.json()}")
# 第二次请求——Session自动携带了Cookie
check_url = "https://httpbin.org/cookies"
response = session.get(check_url)
print(f"当前Cookie: {response.json()}")
# 输出: {'cookies': {'sessionid': 'abc123'}}
# 使用同一个Session,Cookie自动保持
4.3 真实场景:登录网站后保持会话
import requests
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
# 步骤1:先访问登录页面获取CSRF Token(实际开发中常见)
login_page_url = "https://example.com/login"
page_resp = session.get(login_page_url)
# 从HTML中解析CSRF Token(省略正则/BeautifulSoup代码)
# 步骤2:提交登录表单
login_data = {
"username": "your_username",
"password": "your_password",
"csrf_token": "extracted_token"
}
login_resp = session.post(login_page_url, data=login_data)
if login_resp.ok:
print("登录成功!")
# 步骤3:访问需要登录的页面——Session自动携带认证Cookie
dashboard_url = "https://example.com/dashboard"
dashboard_resp = session.get(dashboard_url)
print(f"已登录用户页面状态码: {dashboard_resp.status_code}")
4.4 手动添加Cookie
如果你已经有了Cookie字符串,可以直接注入到Session中:
import requests
session = requests.Session()
# 方式一:更新Cookie字典
session.cookies.update({
"sessionid": "abc123",
"token": "xyz789"
})
# 方式二:从响应中提取并设置
response = requests.get("https://httpbin.org/cookies/set/foo/bar")
for cookie in response.cookies:
session.cookies.set(cookie.name, cookie.value)
# 验证
resp = session.get("https://httpbin.org/cookies")
print(resp.json())
步骤五:超时、重试与错误处理
网络请求必须考虑异常情况,否则你的程序会在网络波动时直接崩溃。
5.1 设置超时
永远不要不设置超时!不设超时的请求可能无限等待:
import requests
from requests.exceptions import Timeout
try:
# timeout = (connect_timeout, read_timeout)
response = requests.get("https://httpbin.org/delay/10", timeout=(3, 5))
print(response.text)
except Timeout:
print("请求超时!")
5.2 连接错误处理
import requests
from requests.exceptions import ConnectionError, Timeout, RequestException
url = "https://api.example.com/data"
try:
response = requests.get(url, timeout=10)
response.raise_for_status() # 非200状态码会抛出HTTPError
data = response.json()
print("请求成功:", data)
except ConnectionError:
print(f"无法连接到 {url},请检查网络或域名")
except Timeout:
print(f"请求 {url} 超时")
except requests.exceptions.HTTPError as e:
print(f"HTTP错误: {e.response.status_code}")
except RequestException as e:
print(f"请求异常: {e}")
5.3 自动重试机制
使用 requests.adapters.HTTPAdapter 结合Session实现自动重试:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# 创建Session
session = requests.Session()
# 配置重试策略
retry_strategy = Retry(
total=3, # 最多重试3次
backoff_factor=1, # 退避因子:重试间隔 = {backoff_factor} * (2^({retry_number} - 1))
status_forcelist=[500, 502, 503, 504], # 这些状态码触发重试
allowed_methods=["GET", "POST"] # 哪些方法可以重试
)
# 将重试策略挂载到HTTP适配器
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
# 现在这个Session会自动重试失败的请求
response = session.get("https://httpbin.org/status/500", timeout=10)
print(f"最终状态码: {response.status_code}")
完整实战:用requests抓取GitHub Trending仓库
下面是一个综合示例,综合运用了本文提到的所有知识点:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from requests.exceptions import RequestException
from datetime import datetime
def create_robust_session():
"""创建一个带重试机制的Session"""
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "application/vnd.github.v3+json"
})
retry_strategy = Retry(
total=3,
backoff_factor=0.5,
status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
return session
def get_trending_repositories():
"""获取GitHub每日热门仓库"""
session = create_robust_session()
params = {
"q": "created:>2026-05-01",
"sort": "stars",
"order": "desc",
"per_page": 10
}
try:
response = session.get(
"https://api.github.com/search/repositories",
params=params,
timeout=15
)
response.raise_for_status()
data = response.json()
print(f"🔥 GitHub热门仓库 ({datetime.now().strftime('%Y-%m-%d')}):\n")
for i, repo in enumerate(data["items"], 1):
print(f"{i}. {repo['full_name']}")
print(f" ⭐ Stars: {repo['stargazers_count']}")
print(f" 📝 描述: {repo['description'] or '无描述'}")
print(f" 🔗 {repo['html_url']}\n")
except RequestException as e:
print(f"获取数据失败: {e}")
if __name__ == "__main__":
get_trending_repositories()
常见问题(FAQ)
Q1: requests.get() 返回的状态码不是200怎么办?
首先用 response.status_code 查看具体状态码。常见情况:401 Unauthorized — 需要添加认证信息(Token/Auth);403 Forbidden — IP被限制或需要添加合适的 User-Agent;404 Not Found — URL路径或参数有误;429 Too Many Requests — 请求频率过高,需要添加延时或使用重试机制;5xx — 服务端问题,可以重试。建议始终调用 response.raise_for_status() 来主动抛出异常。
Q2: requests.Session() 和直接调用 requests.get() 有什么区别?
核心区别在于连接复用和Cookie自动管理。直接调用 requests.get() 每次都会创建新的连接,不会自动携带之前请求返回的Cookie。而 requests.Session() 会复用TCP连接(减少连接建立开销),并在同一Session内的所有请求中自动保持Cookie。如果需要连续调用同一个站点的多个API、或者需要登录后保持会话,务必使用Session。
Q3: requests 和 urllib 应该用哪个?
无脑选requests。Python内置的 urllib 虽然功能齐全,但API设计繁琐:需要用 urlopen、手动处理编码、手动管理Cookie、手动处理异常。而requests API简洁直观,一个 get() / post() 就能搞定大部分场景,代码量减少50%以上。requests底层其实也使用了urllib3,但上层API做了大量人性化封装。只有在完全不能安装第三方库的受限环境中才考虑使用urllib。
Q4: 如何解决 ‘SSL: CERTIFICATE_VERIFY_FAILED’ 证书验证错误?
首先检查系统时间是否正确(证书过期检测依赖正确时间)。如果是自签名证书或测试环境,可以设置 verify=False 跳过验证(同时要用 urllib3.disable_warnings() 关闭警告):requests.get(url, verify=False)。生产环境建议正确配置CA证书,或指定证书路径:requests.get(url, verify='/path/to/cert.pem')。
如果你正在寻找更专业的 API 调试工具,不妨看看我们的 2026年最好用的5个免费API测试工具评测,找到最适合你的 Postman 替代品。
总结
本文从零开始,系统学习了Python requests库的核心用法:
- GET请求:基础获取数据 + params参数传递
- 请求头设置:User-Agent、Authorization等关键头部配置
- POST请求:提交JSON数据、表单数据、文件上传
- Session会话管理:Cookie自动保持、登录状态维持
- 错误处理:超时设置、连接错误捕获、自动重试机制
requests库是Python开发者工具箱中最重要的武器之一,建议将本文的代码保存为参考模板,在实际项目中直接复用。
📖 推荐阅读:
- Python实战:用FastAPI和Pandas搭建实时A股行情看板 — 本文中的requests技能可以直接用于从行情API获取数据
- Python实战:20行代码搭建股票价格提醒机器人 — 使用requests调用行情API实现价格监控
- Python实战:用SQLAlchemy 2.0实现异步数据库操作 — 结合requests获取外部数据后存入数据库的完整工作流