selenium webdriver如何新增cookie

anywen5590發表於2018-07-03

一. webdriver中常用的cookie方法

webdriver中提供了操作cookie的相關方法:

  • get_cookies()                   獲得cookie資訊

  • add_cookie(cookie_dict)        新增cookie

  • delete_cookie(name)             刪除特定(部分)的cookie

  • delete_all_cookies()              刪除所有的cookie

二. add_cookie()的用法

1. 原始碼中的解釋

原始碼中簡略的向我們展示瞭如何新增cookie,原始碼如下:

    def add_cookie(self, cookie_dict):
        """
        Adds a cookie to your current session.

        :Args:
         - cookie_dict: A dictionary object, with required keys - "name" and "value";
            optional keys - "path", "domain", "secure", "expiry"

        Usage:
            driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
            driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})
            driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure':True})

        """
        self.execute(Command.ADD_COOKIE, {'cookie': cookie_dict})

從中可以看出add_cookie()這個函式有一個引數cookie_dict,它是以字典的形式傳入的,字典中必選的鍵是"name"和"value",可選的鍵是"path", "domin", "secure", "expiry",其實原始碼中還漏了一個:"httponly"

2. cookie中鍵名的含義

這些鍵名都代表什麼意思呢?參考博文《selenium3.7+ python3 新增cookie模擬登陸》,羅列如下

  • name:cookie的名稱

  • value:cookie對應的值,動態生成的

  • domain:伺服器域名

  • expiry:Cookie有效終止日期

  • path:Path屬性定義了Web伺服器上哪些路徑下的頁面可獲取伺服器設定的Cookie

  • httpOnly:防指令碼攻擊

  • secure:在Cookie中標記該變數,表明只有當瀏覽器和Web Server之間的通訊協議為加密認證協議時

三. 例項(以課堂派的登入為例)

第一步:我們先手工做一次登入,開啟chrome的除錯工具(F12),選擇Network—Preserve log—XHR

第二步:點選登入,開啟除錯工具中的login,可以看到右邊Response Headers下面就出現了伺服器返回給瀏覽器的cookie

第三步:python程式碼的實現,最容易出現問題的可能是這一步

1 from selenium import webdriver
2 
3 driver = webdriver.Chrome()
4 cookies = {'value': 'think%3A%7B%22username%210293%31628193MDAwMDAwMLOGpZaIudFqhc6Gl7LQetmZtmfOk2RhbQ%22%2C%22expire%sfdaaswMDAwMDAwMLOGud6Gqb-whbiCmLOmdZ4%22%2C%22token%22%3A%22MDAwMDAwMDAwMMurrpWavLehhs1-3LLfgduEt4OWepuo123456123KZq6HQxtOK0ZCme5p-q6iZu2yrn4uNhJ3KedDYk7ivboS4it6910926YW0%22%7D',
5            'name': 'ketangpai_home_remember'}
6 
7 driver.add_cookie(cookie_dict=cookies)
8 driver.get("https://www.ketangpai.com/Main/index.html")

執行結果後發現報錯了:Message: unable to set cookie

Traceback (most recent call last):
  File "D:/python_workshop/python6/selenium_webdriver/add_cookies的使用(二).py", line 9, in <module>
    driver.add_cookie(cookie_dict=cookies)
  File "D:\Program\python34\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 872, in add_cookie
    self.execute(Command.ADD_COOKIE, {'cookie': cookie_dict})
  File "D:\Program\python34\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
    self.error_handler.check_response(response)
  File "D:\Program\python34\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unable to set cookie
  (Session info: chrome=66.0.3359.139)
  (Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 6.1.7600 x86_64)

第四步:修改程式碼,解決問題

這篇標題很長的文章給我們提供了一個解決方案——Selenium: Trying to log in with cookies and get the errorMessage - “Can only set cookies for current domain” or "Unable to set Cookie"

"技術提示:必須首先載入網站,這樣Selenium 才能知道cookie 屬於哪個網站,即使載入網站的行為對我們沒任何用處"

 只需要給原來的程式碼加上一句(紅色部分),這個url填"https://www.ketangpai.com/User/login.html"或"https://www.ketangpai.com/Main/index.html"都行,只要是同一個domain就行,瀏覽器會自動跳轉到登入頁面

1 from selenium import webdriver
2 
3 driver = webdriver.Chrome()
4 cookies = {'value': 'think%3A%7B%22username%210293%31628193MDAwMDAwMLOGpZaIudFqhc6Gl7LQetmZtmfOk2RhbQ%22%2C%22expire%sfdaaswMDAwMDAwMLOGud6Gqb-whbiCmLOmdZ4%22%2C%22token%22%3A%22MDAwMDAwMDAwMMurrpWavLehhs1-3LLfgduEt4OWepuo123456123KZq6HQxtOK0ZCme5p-q6iZu2yrn4uNhJ3KedDYk7ivboS4it6910926YW0%22%7D',
5            'name': 'ketangpai_home_remember'}
6
7 driver.get("https://www.ketangpai.com/User/login.html")
8 driver.add_cookie(cookie_dict=cookies)
9 driver.get("https://www.ketangpai.com/Main/index.html")

再次執行,發現已經成功了

四. 獲取cookie的方法不止一種

cookie的可以通過瀏覽器除錯來獲取,當然也可以通過抓包工具獲取,那麼能不能用程式碼來獲取呢?答案是肯定的

參照上面那篇博文,我們完成以下程式碼,第一次通過driver1傳送使用者名稱和密碼登入,獲取cookie並儲存,第二次driver2新增driver1儲存的cookie,達到繞過登入的目錄

 1 from selenium import webdriver
 2 import time
 3 
 4 #driver1登入網站,獲得cookie並儲存
 5 driver1 = webdriver.Chrome()
 6 driver1.get("https://www.ketangpai.com/User/login.html")
 7 driver1.maximize_window()
 8 time.sleep(2)
 9 
10 #第一次通過send_keys向輸入框傳送使用者名稱密碼登入
11 driver1.find_element_by_xpath("//input[@name='account']").send_keys("your username")
12 driver1.find_element_by_xpath("//input[@name='pass']").send_keys("your password")
13 time.sleep(2)
14 driver1.find_element_by_xpath("//div[@class='padding-cont pt-login']//a[@class='auto-login fl']").click()
15 time.sleep(3)
16 driver1.find_element_by_xpath("//div[@class='padding-cont pt-login']//a[@class='btn-btn']").click()
17 time.sleep(6)
18 #用get_cookies的方法得到登入後的cookie,這個cookie是個列表,列表中兩個元素都是字典,第一個是登入前的cookie,第二個是登入後的cookie
19 #將cookie儲存在變數savedCookies中
20 savedCookies = driver1.get_cookies()
21 print(savedCookies)
22 
23 #driver2得到driver1的cookie,先刪除自己的所有cookie,再將driver1的cookie新增進來
24 driver2 = webdriver.Chrome()
25 #必須首先載入網站,這樣selenium才知道cookie是屬於哪個網站的
26 driver2.get("https://www.ketangpai.com/User/login.html")
27 #一旦載入網站,即使沒登入,也會產生一個cookie,所以這個cookie被刪除了
28 driver2.delete_all_cookies()
29 #遍歷savedCookies中的兩個元素
30 for cookie in savedCookies:
31     #k代表著add_cookie的引數cookie_dict中的鍵名,這次我們要傳入這5個鍵
32     for k in {'name', 'value', 'domain', 'path', 'expiry'}:
33         #cookie.keys()屬於'dict_keys'類,通過list將它轉化為列表
34         if k not in list(cookie.keys()):
35             #saveCookies中的第一個元素,由於記錄的是登入前的狀態,所以它沒有'expiry'的鍵名,我們給它增加
36             if k == 'expiry':
37                 t = time.time()
38                 cookie[k] = int(t)    #時間戳s
39     #將每一次遍歷的cookie中的這五個鍵名和鍵值新增到cookie
40     driver2.add_cookie({k: cookie[k] for k in {'name', 'value', 'domain', 'path', 'expiry'}})
41 
42 #載入我們想要看到的頁面的url
43 driver2.get("https://www.ketangpai.com/Main/index.html")
44 #再次列印driver2的cookie
45 print(driver2.get_cookies())

注意:cookie有兩種,一種是會話級別的,一種是有有效期的,會話級別的cookie就不能用add_cookie的方法了,因為一次會話過程(從開啟瀏覽器到關閉瀏覽器,斷開連線)結束後它就失效了

 

 

 

 

參考文章

https://www.cnblogs.com/CoolJayson/p/7421013.html

https://www.cnblogs.com/huangguifeng/p/7858619.html

https://stackoverflow.com/questions/48562253/webdrivererror-unable-to-set-cookie-javascript

 

轉載於:https://www.cnblogs.com/my_captain/p/9260373.html

相關文章