在python爬虫中如何处理cookie和session

使用python开发爬虫的过程中,遇到需要登录鉴权的一些页面,必不可少的会接触到cookie和session的使用。本文结合自己最近一次爬虫爬坑的经历,介绍在python爬虫中如何使用Cookie和Session
在这里插入图片描述

Cookie和Session的介绍

Cookie

Cookie 是一种用于跟踪用户会话信息的小型文本文件。它由服务器发送到用户的浏览器,然后由浏览器存储在用户的计算机上。每当用户访问同一站点时,浏览器都会将相关的 Cookie 发送回服务器,以便服务器可以使用它来识别用户并维护用户的状态信息

Session

Session 是一种用于在服务器端存储用户状态信息的机制。与 Cookie 不同,Session 数据存储在服务器上,而不是存储在用户的浏览器中。每个会话都有一个唯一的会话标识符(Session ID),通常存储在用户的 Cookie 中,用于在用户和服务器之间唯一标识会话。

为什么要用到Cookie和Session

假如我们要去访问一些需要登录的页面,爬取需要的信息,我们有以下三中方式:

  1. 人工把浏览器页面的请求header里cookie复制下来,写到python脚本里,这个方法无法保证cookie的时效性
  2. 模拟登录请求,通过代码模拟用户登录的过程,使用requests 库来发送请求,一旦登录成功,保存cookie,后续请求携带上cookie。
  3. 同样模拟登录,但是这里不用保存cookie,使用request.Session发送请求,登录成功,后续都直接使用这个session,服务器会将你视为已登录用户,进行正常的会话。
    第2种方式比较灵活,第3种方式使用起来比较方便,就像使用浏览器登录一样,不需要再考虑cookie的管理和请求添加cookie等,直接使用session发起请求就可以,这里比较推荐第3种方式

使用session保持会话的好处

在requests中,如果直接利用get()或post()等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话,也就是说相当于你用了两个浏览器打开了不同的页面。

设想这样一个场景,第一个请求利用post() 方法登录了某个网站,第二次想获取成功登录后的自己的个人信息, 你又用了一次get()方法去请求个人信息页面。实际上,这相当于打开了两个浏览器,这是两个完全不相关的会话,能成功获取个人信息吗?那当然不能。有小伙伴可能说了,我在两次请求时设置一样的cookies不就行了?可以,但这样做起来显 得很烦琐,我们有更简单的解决方法。

其实解决这个问题的主要方法就是维持同一个会话,也就是相当于打开一个新的浏览器选项 卡而不是新开一个浏览器。但是我又不想每次设置cookies,那该怎么办呢?这时候就有了新的利器一Session对象。利用它,我们可以方便地维护一个会话,而且不用担心 cookies 的问题,它会帮我们自动处理好。requests模块中的Session类能够自动处理发送请求获取响应过程中产生的cookie,进而达到状态保持的目的。接下来我们就来学习它。

在python中如何使用Cookie

如果你已经有了个合法的cookie,可以直接这样使用:

requests.get(url=you_rurl, cookies=your_cookie)

后续每次请求都这样带着cookie就可以,比较繁琐,下面重点介绍如何使用Session

在python中如何使用Session

reqeust.Session()

# 新建一个会话
session = requests.Session()
# 使用这个会话发起一个请求,模拟登录
session.post(url=you_url, data={'你的参数'})
# 如果上一个请求成功,这个请求就可以直接获取到数据,因为session已经把上个请求返回的cookie自动带上了
session.get(url=you_url)

所以requests.session能自动处理 cookie , 下一次发起请求时会自动带上前一次的 cookie,不需要像使用cookie的方式一样每次都手动处理,极大的方便了请求的业务逻辑。

案例:使用session维持github会话

对这个案例进行分析有以下步骤:

  1. 对 github 登陆以及访问登陆后才能访问的页面的整个完成过程进行抓包分析,比如分析登录参数是什么
  2. 确定登陆请求的 url 地址、请求方法和所需的请求参数
  3. 部分请求参数在别的 url 对应的响应内容中,可以使用 re 模块获取
  4. 确定登陆后才能访问的页面的的 url 地址和请求方法
  5. 利用 requests.session 完成代码
import requests
import re
# 构造请求头字典
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (
KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36',}
# 实例化session对象
session = requests.session()
# 访问登陆页获取登陆请求所需参数
response = session.get(https://github.com/login, headers=headers)
authenticity_token = re.search('name="authenticity_token" value="(.*?)" />',
response.text).group(1) # 使用正则获取登陆请求所需参数
# 构造登陆请求参数字典
data = {
'commit': 'Sign in', # 固定值
'utf8': ' ', # 固定值
'authenticity_token': authenticity_token, # 该参数在登陆页的响应内容中
'login':
input('输入github账号:'),
'password':
input('输入github账号:')}
# 发送登陆请求(无需关注本次请求的响应)
session.post(https://github.com/session, headers=headers, data=data)
# 打印需要登陆后才能访问的页面
response = session.get(https://github.com/settings/profile, headers=headers)
print(response.text)

最佳实践参考

使用session需要每次打开程序都登录,但是有的时候,登录信息并没有过期,如何真正像浏览器一样,及时关闭了浏览器再重新打开,只要cookie不过期,也不需要重新登录。这里就需要把cookie做持久化,然后加载cookie到session中,这样就能通过持久化的cookie构造一个session,避免重复多次登录。

cookie持久化存储和加载

登录成功后,把session中的cookie取出做持久化存储,这里存储到文件中。保存cookie的对象是RequestsCookieJar,我们需要把他转成字典,不能直接使用__dict__方法,需要使用两个特殊函数requests.utils.dict_from_cookiejar将RequestsCookieJar转成字典,然后再使用requests.utils.cookiejar_from_dict(new_cookie_jar),可以将字典转成RequestsCookieJar,参考下面代码:

####### 持久化存储
# 转成字典
cookiejar = requests.utils.dict_from_cookiejar(request_session.cookies)
# 转成json存储到文件中
# 登录成功, session里的cookie是最全的cookiejar = requests.utils.dict_from_cookiejar(request_session.cookies)with open(cookie_path, "w") as f:json.dump(cookiejar, f, indent=True)logging.info('cookies saved to ./data/cookie.txt')####### 取出cookie加载到session
session = reqeust.Session()
with open(cookie_path, "r") as f:load_cookie = json.load(f)whv_logger.info(f"load_cookie from file: {load_cookie}")exist_cookies =  requests.utils.cookiejar_from_dict(load_cookie)session.cookies.update(exist_cookies)

完整的cookie持久化方案参考

在这里顶一个模块专门处理cookie的持久和加载,定义个全局变量request_session用来管理全局的会话。登录完成之后,调用save_cookie方法更新全局session

import json
import tracebackimport requests.utilscookie_path = './data/cookie.txt'
request_session: requests.Session = Nonedef __load_cookie():'''加载本地cookie,如果存在加载,如果不存在就返回空:param session::return:'''try:with open(cookie_path, "r") as f:load_cookie = json.load(f)logging.info(f"load_cookie from file: {load_cookie}")return requests.utils.cookiejar_from_dict(load_cookie)except Exception as e:traceback.print_exc()logging.error("failed load cookie, error:%s", e)return Nonedef get_session():global request_sessionif request_session is not None:return request_sessionelse:request_session = requests.Session()exist_cookies = __load_cookie()if exist_cookies is not None:request_session.cookies.update(exist_cookies)return request_sessiondef 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)logging.info('cookies saved to ./data/cookie.txt')def update_cookie():'''这个方法需要具体场景具体分析,并不一定都用到。为什么需要一个新的session# 走到这一步,说明session已经过期,重新获取session,需要重新处理下session:return:'''error_cookie_jar = requests.utils.dict_from_cookiejar(request_session.cookies)# 替换自己需要处理的cookie中的参数new_cookie_jar = {'__RequestVerificationToken': error_cookie_jar['__RequestVerificationToken']}new_cookie = requests.utils.cookiejar_from_dict(new_cookie_jar)# 清空旧的cookierequest_session.cookies.clear_session_cookies()# 填充新的cookierequest_session.cookies.update(new_cookie)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/599547.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云流量怎么计算的?轻量服务器流量价格表

腾讯云轻量应用服务器套餐带流量包,就是有月流量限制的意思,超出轻量套餐的流量需要另外支付流量费,轻量服务器地域不同超额流量费用也不同,北京上海广州等中国内地地域流量价格是0.8元每GB,中国香港地域流量价格是1元…

【功能更新】强化知识库管理与AI问答机器人性能

三月HelpLook带来了3大类功能焕新,主要聚焦于:知识库的管理功能升级和AI问答机器人的优化,让我们看看更新了哪些新功能! 那么,接下来就让我们来详细了解一下本次升级都带来了哪些新功能吧! 知识库使用与管理…

Stm32 HAL库 访问内部flash空间

Stm32 HAL库 访问内部flash空间 代码的部分串口配置申明文件main函数 在一些时候,需要存储一些数据,但是又不想接外部的flash,那我们可以知道,其实还有内部的flash可以使用, 需要注意的是内部flash,读写次数…

创建型模式--1.单例模式【巴基速递】

1. 巴基的订单 在海贼世界中,巴基速递是巴基依靠手下强大的越狱犯兵力,组建的集团海贼派遣公司,它的主要业务是向世界有需要的地方输送雇佣兵(其实是不干好事儿)。 自从从特拉法尔加罗和路飞同盟击败了堂吉诃德家族 &…

LeetCode-74. 搜索二维矩阵【数组 二分查找 矩阵】

LeetCode-74. 搜索二维矩阵【数组 二分查找 矩阵】 题目描述:解题思路一:先二分查找行,再二分查找列。解题思路二:暴力遍历,也能过。解题思路三:用python的in。 题目描述: 给你一个满足下述两条…

【绩效管理】帮助零售企业建立分层分类绩效考核体系项目纪实

购物中心张经理评价:“员工的绩效管理一直是困扰我公司的难题,我们只懂得怎么经营,至于怎么做人力资源管理,真是一点都不懂。这次华恒智信为我们提供的服务对我们的帮助很大。基于企业实际调研情况,华恒智信专家明确指…

nginx配置实例-负载均衡

目录 一、目的:实现效果 二、准备工作 三、实验部署 3.1修改第二台Tomcat服务器的监听端口为8081 3.2修改完成后,重新启动tomcat8081这台服务器。 3.3在浏览器测试 3.4在两台tomcat里面webapps目录中,创建名称是edu的文件夹&#xff0c…

绝地求生:29.1版本爆料杜卡迪联名、新通行证、成长型AUG和异色、战队皮

这回的更新爆料是真的多,虽然不会同时上线,本期杜卡迪因为没有轮毂和轮胎,所以车漆的颜色可能会贵一点,但是似乎会有进阶优惠礼包可以购买 合作者战队 本期合作者战队皮肤感觉比较一般,武器不是热门武器,而…

SpringBoot学习之Kibana下载安装和启动(Mac版)(三十二)

一、简介 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。 …

kubernetes集群添加到jumpserver堡垒机里管理

第一步、在kubernetes集群中获取一个永久的token。 jumpserver堡垒机用api的来管理kubernetes,所以需要kubernetes的token,这个token还需要是一个永久的token,版本变更:Kubernetes 1.24基于安全方面的考虑(特性门控Le…

Springboot引入swagger

讲在前面&#xff1a;在spring引入swagger时&#xff0c;由于使用的JDK、Spring、swagger 的版本不匹配&#xff0c;导致启动报错&#xff0c;一直存在版本依赖问题。所以在此声明清楚使用版本。JDK 1.8、Spring boot 2.6.13、 Swagger 2.9.2。 引入maven依赖 <dependency&…

2024单品正价起号,直播素材投流选品,【选品课】+【投流课】+【素材课】+【卡首屏】

课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/89064168 更多资源下载&#xff1a;关注我。 课程内容: 01 01 1.如何养账号过风控,mp4 01 1.如何搭建一条计划(1)..mp4 02 1.如何搭建一条计划(2)..mp4 02 02 2.单品起号方案如何选择,mp4 03 2.-比…