为什么要使用session
前面介绍了如何使用reqesuts发起请求,今天介绍如何使用session发起请求。session简单理解就是一种会话机制,在浏览器中我们登录完之后,后面再请求服务数据都不需要再登录了,以为Cookie里已经保存了你的会话状态,每次请求会自动携带cookie参数,如果使用reqeusts.request就必须每次手动携带cookie参数。而reqeuest.Session()会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 就不需要再手动每次处理cookie状态了。
参考文档:
官方文档
如何使用
session使用方式其实和reqeust方法差不都,也支持session.get(), session.post(), session.request()等方法。
s = requests.Session()
s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get('https://httpbin.org/cookies')
print(r.text)
# '{"cookies": {"sessioncookie": "123456789"}}'
最佳实践 cookie复用
处理一些网站时需要的登录校验权限,可以通过session的方式请求,可以把登录后获取到的cookie保存起来,这样后面每次需要登录的时候,可以直接使用已经保存好的cookie,使用这个cookie去构造一个session,然后再发起请求,这样可以避免重复登录。适用于多机器并发式爬取数据。
cookie复用实践:
import json
import traceback
import requests.utils
from executor.page_executor import PageExecutor
from file_path import get_absolute_path
cookie_path = get_absolute_path('data/cookie.txt')
request_session: requests.Session = None
def __load_cookie():
'''
加载本地cookie,如果存在加载,如果不存在就返回空
:param session:
:return:
'''
try:
with open(cookie_path, "r") as f:
load_cookie = json.load(f)
return requests.utils.cookiejar_from_dict(load_cookie)
except Exception as e:
traceback.print_exc()
return None
def get_session():
global request_session
if request_session is not None:
return request_session
else:
request_session = requests.Session()
exist_cookies = __load_cookie()
if exist_cookies is not None:
request_session.cookies.update(exist_cookies)
return request_session
def save_cookie():
# 登录成功, session里的cookie是最全的,response返回的cookie不全
cookiejar = requests.utils.dict_from_cookiejar(request_session.cookies)
with open(cookie_path, "w") as f:
json.dump(cookiejar, f, indent=True)
whv_logger.info('cookies saved to ./data/cookie.txt')
def update_cookie():
'''
为什么需要一个新的session
# 走到这一步,说明session已经过期,重新获取session,需要重新处理下session
# 1. 但是因为携带有旧的session,导致携带旧的__RequestVerificationToken和新的__RequestVerificationToken一起请求,登录失败
# 2. 所以需要重新处理下session,主要是处理__RequestVerificationToken
:return:
'''
error_cookie_jar = requests.utils.dict_from_cookiejar(request_session.cookies)
new_cookie_jar = {'__RequestVerificationToken': error_cookie_jar['__RequestVerificationToken']}
new_cookie = requests.utils.cookiejar_from_dict(new_cookie_jar)
# 清空旧的cookie
request_session.cookies.clear_session_cookies()
# 填充新的cookie
request_session.cookies.update(new_cookie)