1. 程式人生 > 實用技巧 >selenium+requests進行cookies儲存讀取操作

selenium+requests進行cookies儲存讀取操作

selenium+requests進行cookies儲存讀取操作

版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。 本文連結:https://blog.csdn.net/wuqing942274053/article/details/80427259 版權

看這篇文章之前大家可以先看下我的上一篇文章: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池維護的文章,釋出在我的微信公眾號上,盡請關注哦。