pin_drop当前位置:知识文库 ❯ 图文

requests Session会话详解 - Cookie管理与连接池优化

一、概述

requests.Session对象用于在多个请求之间保持状态,最核心的功能是自动管理Cookie。Session对象会在同一会话的所有请求间共享Cookie、请求头、代理等配置,避免了每次请求都重复设置。

此外,Session底层使用urllib3的连接池,可以复用TCP连接,显著提升多次请求的性能。当需要向同一服务器发送多个请求时,使用Session可以省去重复建立和关闭TCP连接的开销,大幅提高请求效率。


二、Session属性与方法

Session属性/方法 类型 说明
headers dict 会话级别的默认请求头,所有请求自动携带
cookies RequestsCookieJar 会话级别的Cookie,自动管理跨请求的Cookie
auth AuthBase 会话级别的认证信息
proxies dict 会话级别的代理设置
verify bool/str 会话级别的SSL验证设置
get() method 发送GET请求,返回Response对象
post() method 发送POST请求,返回Response对象
put() method 发送PUT请求,返回Response对象
delete() method 发送DELETE请求,返回Response对象
close() method 关闭会话,释放连接池资源

三、代码示例

示例1:Session自动管理Cookie

代码示例

import requests

# 创建Session对象
session = requests.Session()

# 第一次请求:服务器设置Cookie
response1 = session.get('https://httpbin.org/cookies/set?session_id=abc123&user=zhangsan')
print(f"设置Cookie后: {dict(session.cookies)}")

# 第二次请求:自动携带之前设置的Cookie
response2 = session.get('https://httpbin.org/cookies')
print(f"服务器收到Cookie: {response2.json()['cookies']}")

# 使用完毕,关闭Session释放资源
session.close()

输出:

代码示例

设置Cookie后: {'session_id': 'abc123', 'user': 'zhangsan'}
服务器收到Cookie: {'session_id': 'abc123', 'user': 'zhangsan'}

示例2:Session设置全局请求头

代码示例

import requests

session = requests.Session()

# 设置全局请求头,所有请求自动携带
session.headers.update({
    'User-Agent': 'MyApp/2.0',
    'Authorization': 'Bearer my_token_123',
    'Accept': 'application/json'
})

# 所有请求自动携带全局请求头
response = session.get('https://httpbin.org/headers')
result = response.json()

print(f"User-Agent: {result['headers'].get('User-Agent')}")
print(f"Authorization: {result['headers'].get('Authorization')}")
print(f"Accept: {result['headers'].get('Accept')}")

session.close()

输出:

代码示例

User-Agent: MyApp/2.0
Authorization: Bearer my_token_123
Accept: application/json

示例3:使用上下文管理器管理Session

代码示例

import requests

# 使用with语句自动管理Session生命周期(推荐)
with requests.Session() as session:
    # 设置全局配置
    session.headers.update({'X-App-Version': '1.0.0'})

    # 模拟登录请求
    login_data = {'username': 'admin', 'password': '123456'}
    login_resp = session.post('https://httpbin.org/post', json=login_data)
    print(f"登录状态码: {login_resp.status_code}")

    # 后续请求自动携带Cookie和全局请求头
    profile_resp = session.get('https://httpbin.org/headers')
    result = profile_resp.json()
    print(f"后续请求携带版本头: {result['headers'].get('X-App-Version')}")

# Session已自动关闭,无需手动close()

输出:

代码示例

登录状态码: 200
后续请求携带版本头: 1.0.0

四、实际应用场景

  • 场景1:模拟登录后的系列操作:先POST登录获取Cookie,后续的GET/POST请求自动携带登录态Cookie,完成个人信息查询、数据提交等操作。这是爬虫开发中最常见的使用模式。

  • 场景2:批量API调用优化:当需要向同一API服务器发送大量请求时,Session复用TCP连接池,避免每次请求都经历TCP三次握手和TLS协商,显著提升请求性能。

  • 场景3:微服务间调用:在微服务架构中,使用Session统一管理认证令牌、请求头配置和超时设置,简化服务间通信的代码复杂度。


五、注意事项

注意1:使用完Session后应调用close()释放连接池资源,推荐使用with语句自动管理,确保在异常情况下也能正确关闭。

注意2:Session的Cookie是累积的,即后续请求会携带之前所有请求收到的Cookie。如需清除,可使用session.cookies.clear()或session.cookies.delete(name)。

注意3:Session不是线程安全的,多线程环境下每个线程应使用独立的Session实例。如果在多线程中共享同一个Session,可能会导致Cookie混乱和连接池竞争问题。


六、Session与直接请求对比

选择使用Session还是直接使用requests.get/post等方法,取决于具体的使用场景:

特性 requests.get() Session.get()
Cookie管理 每次请求独立 自动跨请求保持
连接复用 每次新建连接 复用连接池
全局配置 每次请求单独设置 一次设置全局生效
性能 多次请求较慢 多次请求更快
资源管理 无需关闭 需要close()或with语句
线程安全 安全 非线程安全

小贴士

如果只是发送一两个请求,直接使用requests.get()即可,无需创建Session。但如果是爬虫或API客户端等需要频繁请求同一服务器的场景,强烈推荐使用Session,不仅可以复用连接提升性能,还能自动管理Cookie,大大简化代码。


七、小结

  • Session对象在多个请求间保持Cookie、请求头等状态,避免重复配置。

  • Session底层使用连接池复用TCP连接,显著提升多次请求的性能。

  • 推荐使用with requests.Session()语句管理Session生命周期,确保资源正确释放。

  • Session非线程安全,多线程环境需为每个线程创建独立实例。


八、练习题

练习1

使用Session模拟登录流程:先POST登录(设置Cookie),再GET获取个人信息,验证Cookie在请求间自动传递。

练习2

创建Session并设置全局User-Agent和Authorization请求头,发送两次请求验证全局配置对所有请求生效。

练习3

编写一个API客户端类,使用Session管理连接,提供login()、get_profile()、logout()等方法,模拟完整的用户操作流程。


常见问题

1. Session会自动处理重定向吗?

是的,Session和requests模块级方法一样,默认会自动跟随3xx重定向。重定向过程中Cookie也会被正确传递。可以通过allow_redirects=False参数禁用自动重定向。

2. Session的headers和请求时的headers如何合并?

请求时指定的headers会覆盖Session的headers中相同的键。例如session.headers设置了User-Agent为'App/1.0',但session.get(url, headers={'User-Agent': 'Custom'})会使用'Custom'。不冲突的键会合并保留。

3. Session的连接池大小是多少?

Session默认使用urllib3的HTTPAdapter,连接池大小为10(pool_maxsize=10)。如果需要增加并发连接数,可以自定义Adapter:session.mount('https://', requests.adapters.HTTPAdapter(pool_maxsize=20))。

4. 如何清除Session中的Cookie?

可以清除单个Cookie:session.cookies.delete('cookie_name');也可以清除所有Cookie:session.cookies.clear()。清除后,后续请求将不再携带已清除的Cookie。

标签: requests Session Cookie管理 连接池 Python教程 HTTP会话

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: requests Response对象详解 - 状态码解析与数据提取技巧 下一篇: requests超时设置详解 - 连接超时、读取超时与重试机制

poll相关推荐