• selenium+requests进行cookies保存读取操作


    看这篇文章之前大家可以先看下我的上一篇文章:cookies详解

    本篇我们就针对上一篇来说一下cookies的基本应用

    使用selenium模拟登陆百度

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from PIL import Image
    
    chrome_option = webdriver.ChromeOptions()
    chrome_path = "/usr1/webdrivers/chromedriver"
    
    def login_baidu():
        driver = None
        try:
            driver = webdriver.Chrome(executable_path=chrome_path)
            driver.get("https://www.baidu.com")
            print(driver.title)
            WebDriverWait(driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="u1"]/*[@class="lb"]')))
            element = driver.find_element_by_xpath('//*[@id="u1"]/a[7]')
            element.click()
    
            WebDriverWait(driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__footerULoginBtn"]')))
            element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__footerULoginBtn"]')
            element.click()
    
            WebDriverWait(driver, 10, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__userName"]')))
            element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__userName"]')
            element.send_keys("账号")
    
            WebDriverWait(driver, 10, 0.5).until(
                EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__password"]')))
            element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__password"]')
            element.send_keys("密码")
    
            WebDriverWait(driver, 10, 0.5).until(
                        EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__verifyCodeImg"]')))
            element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__verifyCodeImg"]')
    
            driver.get_screenshot_as_file("qrcode.png")
            image = Image.open("qrcode.png")
            left = element.location.get("x")
            top = element.location.get("y")
            right = left + element.size.get("width")
            bottom = top + element.size.get("height")
            cropImg = image.crop((left, top, right, bottom))
            cropImg.save("code.png")
    
            yanzheng = input(">>>")
            WebDriverWait(driver, 10, 0.5).until(
                EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__verifyCode"]')))
            element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__verifyCode"]')
            element.send_keys(yanzheng)
    
            WebDriverWait(driver, 10, 0.5).until(
                EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__PSP_10__submit"]')))
            element = driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__submit"]')
            element.click()
    
            # 如果需要手机验证码
            try:
                WebDriverWait(driver, 10, 0.5).until(
                    EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__36__button_send_mobile"]')))
                element = driver.find_element_by_xpath('//*[@id="TANGRAM__36__button_send_mobile"]')
                element.click()
    
                WebDriverWait(driver, 10, 0.5).until(
                    EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__36__input_vcode"]')))
                element = driver.find_element_by_xpath('//*[@id="TANGRAM__36__input_vcode"]')
                duanxin = input(">>>")
                element.send_keys(duanxin)
    
                WebDriverWait(driver, 10, 0.5).until(
                    EC.element_to_be_clickable((By.XPATH, '//*[@id="TANGRAM__36__button_submit"]')))
                element = driver.find_element_by_xpath('//*[@id="TANGRAM__36__button_submit"]')
                element.click()
            except Exception as e:
                print(e)
    
            driver.get_screenshot_as_file("screen.png")
        finally:
            print("关闭")
            if driver:
                driver.quit()
    

    selenium操作很简单,这里不做详解讲解,以后我们开爬虫基础系列文章的时候会讲到。

    selenium保存cookies

    cookies = driver.get_cookies()
    with open("cookies.txt", "w") as fp:
        json.dump(cookies, fp)
    

    这里切记,如果我们要使用json.load读取数据,那么一定要使用json.dump来写入数据,不能使用str(cookies)直接转为字符串进行保存,因为其存储格式不同。这样我们就将cookies保存在文件中了。

    selenium读取cookies

    def read_cookies():
        # 设置cookies前必须访问一次百度的页面
        driver.get("http://www.baidu.com")
        with open("cookies.txt", "r") as fp:
            cookies = json.load(fp)
            for cookie in cookies:
                # cookie.pop('domain')  # 如果报domain无效的错误
                driver.add_cookie(cookie)
    
        driver.get("http://www.baidu.com")
    

    这里不用登录就会直接显示我的用户名。而且要注意不同的浏览器可能处理方式不同,比如在火狐浏览器中就会报错:selenium.common.exceptions.InvalidCookieDomainException: Message: .baidu.com,如果碰到这种错误(不一定,也可能跟系统、浏览器都有关系),在add_cookie的时候我们可以把domain去掉就行了。

    requests读取cookies

    import requests
    from requests.cookies import RequestsCookieJar
    s = requests.session()
    s.verify = False
        s.headers = {
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
        }
    s.get("http://www.baidu.com")
    
    #这里我们使用cookie对象进行处理
    jar = RequestsCookieJar()
    with open("cookies.txt", "r") as fp:
        cookies = json.load(fp)
        for cookie in cookies:
            jar.set(cookie['name'], cookie['value'])
    
    #百度个人中心
    r = s.get("https://www.baidu.com/p/setting/profile/basic", cookies=jar)
    
    # 也可以使用字典设置
    cookies_dict = dict()
    with open("cookies.txt", "r") as fp:
        cookies = json.load(fp)
        for cookie in cookies:
            cookies_dict[cookie['name']] = cookie['value']
    r = s.get("https://www.baidu.com/p/setting/profile/basic", cookies=cookies_dict)
    
    r.encoding = "utf-8"
    print(r.text)
    

    requests库可以使用cookies对象和dict对象来指定cookies,这个可以看一下源码

    通过requests读取cookies的使用,我们知道在cookies中我们一般只使用name和value,像domain、path等值都是不需要使用的,而且上面传入cookies字典的例子我们知道,只要保存了cookies中的name和value,无论你以什么样的方式保存,文件、或者数据库等,最后读取出来只要生成对应的字典格式就行了。

    requests保存cookies

    import requests
    s = requests.session()
    s.verify = False
    s.headers = {
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
        }
    
    # 这里可以是模拟登陆的步骤
    s.get("http://www.baidu.com")
    
    cookies = requests.utils.dict_from_cookiejar(s.cookies)
    with open("cook.txt", "w") as fp:
        json.dump(cookies, fp)
    print(cookies)
    

    首先我们看一下requests.session里面的cookies,它是一个RequestsCookieJar对象,这就是我们在上面使用的时候用RequestsCookieJar对象读取cookies的原因了

    下面我们看到requests.utils.dict_from_cookiejar方法,这是requests库提供的一个方法,把上面的RequestsCookieJar对象转换为一个字典(字典里只有name和value),这就是我上面说的,requests库只使用name和value值,而我们selenium中保存的cookies中包含domain、path等信息。

    另外还有一个方法requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True)这个方法,根据字典生成一个RequestsCookieJar对象,为什么需要这样一个方法呢,可能在上面的应用中有些人会有疑问,我们的cookies是通过get/post方法的参数传进去的,那么在访问其他网页的时候都要去传递这样一个参数吗?这样很不方便而且容易遗忘。看上图的s.cookies变量,它是requests.session对象中的变量,而且是一个RequestsCookieJar类型的对象,那么我们就可以使用这个函数把读取的字典信息转换为RequestsCookieJar对象,然后把值直接设置给s.cookies,就像上面代码里的headers一样,这样就方便很多了吧。

    上面我都是将cookies值保存在文件中,在大多数情况下我们一般使用都是将其保存在数据库中,启动一个服务器专门进行登录验证并保存cookies值。后面我会写一篇Flask+Redis进行cookies池维护的文章,发布在我的微信公众号上,尽请关注哦。


    如果你觉得我的文章还可以,可以关注我的微信公众号,查看更多实战文章:Python爬虫实战之路
    也可以扫描下面二维码,添加我的微信公众号

    公众号

    赞赏码

  • 相关阅读:
    算法学习-顺序查找
    EF框架中Attach与Entry
    EntityFramework更新实体绑定实体字段简便方法
    C# 快速写入本地文件
    Vue 3.0初探
    二维管线生成三维管线,转换3DTiles 思路
    Civil3d中 如何用管轴线的变坡点桩号控制其他纵断面数据的显示?
    jupyter
    jenkins
    ambari
  • 原文地址:https://www.cnblogs.com/small-bud/p/9064674.html
Copyright © 2020-2023  润新知