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数据,将两者放在一起进行仔细比较还是能发现共同点的

对于请求头来说,需要的只有namevalue,两者以=号拼接,每一个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

posted @ 2023-07-03 01:10  天才九少  阅读(3378)  评论(6编辑  收藏  举报