selenium中操作Cookie
Cookie介绍:
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),一般存放在客户端上
以百度首页为例,打开调试工具(F12),点击Application(应用程序),选择 Storage 下的 Cookies 选项,找到当前网页即可看到所有的 Cookie,可以发现的是,Cookie在浏览器中是一条一条存在的,每条Cookie都是一个键值对的结构
正文:
- Selenium对Cookie的操作
- 利用Selenium进行模拟登录并使用Cookies
- 获取的Cookie配合requests使用
Selenium对Cookie的操作
Selenium 能够实现操作浏览器的Cookie,因为本身就是其调用浏览器运行,能操作的内容有对Cookie的读取、新增和删除
- 读取Cookie
- 新增Cookie
- 删除Cookie
读取Cookie
两种方法:
driver.get_cookies() # 获取所有的Cookie对象 driver.get_cookie(name) # 获取指定的单条Cookie
driver.get_cookies() 能够获取所有的Cookie,并以 列表 形式返回所有Cookie
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/") print(driver.get_cookies())
[{'domain': '.baidu.com', 'expiry': 1629821019, 'httpOnly': False, 'name': 'BA_HECTOR', 'path': '/', 'secure': False, 'value': '8s818la521202160bp1gia2ic0r'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '34437_34441_31254_33848_34072_34092_34106_26350_34416_34390'}, {'domain': '.baidu.com', 'expiry': 1661353419, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'EDB65890D2F1E97267AD56A70D8F24E8:FG=1'}, {'domain': '.baidu.com', 'expiry': 3777301066, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'EDB65890D2F1E972DC3D6A6A8114E431'}, {'domain': '.baidu.com', 'expiry': 3777301066, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1629817419'}, {'domain': 'www.baidu.com', 'expiry': 1630681419, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]
driver.get_cookie(name) 根据名称获取单个Cookie
源码解读:
对于.get_cookie(name)方法获取单个Cookie,是先用.get_cookies()方法获取所有的Cookie,再通过循环判断提取目标Cookie
获取百度首页名为BD_HOME
的Cookie内容,并将其输出
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/") print(driver.get_cookie("BD_HOME"))
新增Cookie
新增Cookie方法:driver.add_cookie(cookie_dict)
Cookie是一个键值对数据,传入的Cookie对象中必须包含name和value两个属性,缺少其中任何一个都会添加失败。除此之外还有四个可选属性:path,domain,secure,expiry 。源码描述如下:
示例代码:
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.add_cookie({"name":"MyCookie", "value":"this is my cookie!"})
在打开的浏览器窗口,打开调试工具就能看到添加的Cookie
删除Cookie
两种方法:
driver.delete_all_cookies() # 全部删除 driver.delete_cookie(name) # 删除其中一个
driver.delete_all_cookies() 删除全部Cookie
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.delete_all_cookies()
可以看到的是,百度首页在浏览器中的Cookie已经全部被清空了
driver.delete_cookie(name) 删除指定名称的Cookie
删除百度首页名为 BD_HOME 的Cookie内容
from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.delete_cookie("BD_HOME")
可以看到名为BD_HOME
的Cookie已经在浏览器中找不到了
利用Selenium进行模拟登录并使用Cookies
在 爬虫领域 或 自动化测试中,总有一些网站只有登录后才能访问,或则某些数据只有在登录后才会出现。由于用户登陆后的身份信息通常会存放在Cookie中,因此可以将登录后的Cookie保存,再将此Cookie添加到网页中来模拟已登录状态。能有效避免在登录页面中进行多次操作,即一次登录后即可保留登录状态
实现步骤:
1,只需要将当前页面中的Cookie全部清空
2,然后直接添加 已经在登录状态下 或 拥有身份信息 的Cookie在网页中
3,最后别忘记刷新一下网页driver.refresh
,就可以实现页面保留登录状态的效果
# 删除所有的Cookies driver.delete_all_cookies() # 逐个添加Cookie,可以使用循环 driver.add_cookie(cookie_dict) driver.add_cookie(cookie_dict) ... driver.refresh()
以百度为例:
- 先使用 Selenium.WebDriverWait 动作行为模拟网站登录
- 将登录后的Cookies获取并保存到本地(以Json格式)
- 下次打开网页使用Cookie进行网页登录
(1)模拟登录
由于存在百度首页登录时会出现验证的情况,代码并未对此进行自动验证处理,这时候就需要手动验证了
def handle_login(username, pwd, isverify=False): """ 百度首页登录处理方法 :param username: 用户名 :param pwd: 用户密码 :param isverify: 是否存在网页验证 """ # 点击右上角登录按钮 self.find_by_xpath(r"//a[@id='s-top-loginbtn']").click() time.sleep(1) # 点击用户名登录按钮 self.find_by_xpath(r"//p[@id='TANGRAM__PSP_11__footerULoginBtn']").click() # 向输入框输入账户名 self.find_by_xpath(r"//input[@id='TANGRAM__PSP_11__userName']").send_keys(username) # 向输入框输入密码 self.find_by_xpath(r"//input[@id='TANGRAM__PSP_11__password']").send_keys(pwd) # 点击登录按钮 self.find_by_xpath(r"//input[@id='TANGRAM__PSP_11__submit']").click() # 手动图形验证等待 input("请手动进行图形验证,完毕后输入任意内容继续运行") if isverify: # 点击发送验证码按钮 self.find_by_xpath(r"//input[@id='TANGRAM__29__button_send_mobile']").click() # 等待用户输入手动验证码 vcode = input("请输入六位数验证码:") self.find_by_xpath(r"//input[@id='TANGRAM__29__input_vcode']").send_keys(vcode) # 点击确定按钮 self.find_by_xpath(r"//input[@id='TANGRAM__29__button_submit']").click()
(2)Cookie处理
需要可持久化存储Cookie,以及对Cookie进行读取并判断是否存在
def save_cookies(data, encoding="utf-8"): """ 百度首页Cookies保存方法 :param data: 所保存数据 :param encoding: 文件编码,默认utf-8 """ with open(self.f_path, "w", encoding=encoding) as f_w: json.dump(data, f_w) def load_cookies(encoding="utf-8"): """ 百度首页Cookies读取方法 :param encoding: 文件编码,默认utf-8 """ if os.path.isfile(self.f_path): with open(self.f_path, "r", encoding=encoding) as f_r: user_status = json.load(f_r) return user_status
(3)使用Cookie进行网页登录
根据刚开始的步骤示例,修改网页中的Cookies是很简单的
先将网页中原有的Cookies全部删除,然后通过循环一个个将保存的登录Cookie全部添加进网页
def cookies_login(cookies: list): """ 百度首页Cookies登录方法 :param cookies: 网页所需要添加的Cookie """ self.browser.delete_all_cookies() for c in cookies: self.browser.add_cookie(c) self.browser.refresh()
(4)总结上述流程
import os import json import time from selenium import webdriver class BaiduLogin: def __init__(self, url, executable_path, f_path): """ 对象初始化 :param url: 百度首页地址 :param executable_path: 浏览器驱动路径 :param f_path: Cookies文件保存路径 """ self.url = url self.browser = self.start_browser(executable_path) self.f_path = f_path @staticmethod def start_browser(executable_path): return webdriver.Edge(executable_path=executable_path) def start_url(self): self.browser.get(self.url) def find_by_xpath(self, xpath): return self.browser.find_element_by_xpath(xpath) def baidu_login(self, *args): self.start_url() if cookies := self.load_cookies(): self.__cookies_login(cookies) else: self.__handle_login(*args, **kwargs) def __handle_login(self, username, pwd, isverify=False): """ 百度首页登录处理方法 :param username: 用户名 :param pwd: 用户密码 :param isverify: 是否存在网页验证 """ # 点击右上角登录按钮 self.find_by_xpath(r"//a[@id='s-top-loginbtn']").click() time.sleep(1) # 点击用户名登录按钮 self.find_by_xpath(r"//p[@id='TANGRAM__PSP_11__footerULoginBtn']").click() # 向输入框输入账户名 self.find_by_xpath(r"//input[@id='TANGRAM__PSP_11__userName']").send_keys(username) # 向输入框输入密码 self.find_by_xpath(r"//input[@id='TANGRAM__PSP_11__password']").send_keys(pwd) # 点击登录按钮 self.find_by_xpath(r"//input[@id='TANGRAM__PSP_11__submit']").click() # 手动图形验证等待 input("请手动进行图形验证,完毕后输入任意内容继续运行") if isverify: time.sleep(1) # 点击发送验证码按钮 self.find_by_xpath(r"//input[@id='TANGRAM__29__button_send_mobile']").click() # 等待用户输入手动验证码 vcode = input("请输入六位数验证码:") self.find_by_xpath(r"//input[@id='TANGRAM__29__input_vcode']").send_keys(vcode) # 点击确定按钮 self.find_by_xpath(r"//input[@id='TANGRAM__29__button_submit']").click() self.save_cookies(self.browser.get_cookies()) # 登录后保存Cookie def __cookies_login(self, cookies: list): """ 百度首页Cookies登录方法 :param cookies: 网页所需要添加的Cookie """ self.browser.delete_all_cookies() for c in cookies: self.browser.add_cookie(c) self.browser.refresh() def save_cookies(self, data, encoding="utf-8"): """ 百度首页Cookies保存方法 :param data: 所保存数据 :param encoding: 文件编码,默认utf-8 """ with open(self.f_path, "w", encoding=encoding) as f_w: json.dump(data, f_w) def load_cookies(self, encoding="utf-8"): """ 百度首页Cookies读取方法 :param encoding: 文件编码,默认utf-8 """ if os.path.isfile(self.f_path): with open(self.f_path, "r", encoding=encoding) as f_r: user_status = json.load(f_r) return user_status def quit(self): # 关闭浏览器 self.browser.quit()
调用方式:
target_driver = "msedgedriver.exe" url, cookie_fname = r"https://www.baidu.com/", "百度登录Cookies.json" login = BaiduLogin(url, target_driver, cookie_fname) login.baidu_login("用户名", "用户密码")
获取的Cookies配合requests使用
以百度首页为例,打开调试工具(F12),点击Network(网络\抓包工具),如果空白的话就按Ctrl + R
快捷键刷新网页读取,找到位于第一个的请求www.baidu.com
,选择Headers(标头)后在下方就能看到咱们对于https://www.baidu.com/
这个链接的Request Headers(请求头),在里面就能找到Cookie属性
我们会发现在这里的cookie格式与我们在Application(应用程序),选择 Storage 下的 Cookies 选项看到的完全不一样,但其实都是同一些cookies数据,将两者放在一起进行仔细比较还是能发现共同点的
对于请求头来说,需要的只有name
和value
,两者以=
号拼接,每一个cookie以;
进行分割
requests使用Cookie的两种方式:
- 通过请求头方式直接将Cookies给传入
- 在requests.get 和 requests.post 方法中传入cookie参数
略。。。
学习自:https://blog.csdn.net/XianZhe_/article/details/119860391
https://www.cnblogs.com/qican/p/13675158.html