天天看點

selenium登入163郵箱,得到cookie,requests後續請求

1.場景

很多時候登入操作是比較複雜的,因為存在各種反爆破操作,以及為了安全性送出資料都會存在加密。如果要完全模拟代碼去實作登入操作是比較複雜,并且該網站後續更新了登入安全相關功能,那麼登入的模拟操作又得修改。但是通過selenium模拟人為登入得操作是永遠不會過時。是以一個好得方案就是通過selenium模拟登入,然後拿到可用得Cookie通過requests進行後續得模拟請求。

2.實作代碼

import time, requests
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

driver = webdriver.Chrome()
driver.get('https://mail.163.com/')
WebDriverWait(driver, 15).until(  # 顯示等待,直到頁面出現某個元素
    EC.presence_of_element_located((By.ID, "normalLoginTab"))
)
# 因為登入位置處于iframe中,是以要切換進去
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@id,'x-URS-iframe')]"))

email = driver.find_element_by_name('email')
password = driver.find_element_by_name('password')
login = driver.find_element_by_id('dologin')

email.clear()
password.clear()
email.send_keys('admin')
password.send_keys('admin')
login.click()
driver.switch_to.default_content()  # 切回預設

WebDriverWait(driver, 15).until(  # 顯示等待,直到頁面出現某個元素
    EC.presence_of_element_located((By.ID, "_mail_tabitem_0_116text"))
)

driver.find_element_by_xpath('//*[@class="nui-tree-item-text" and @title="收件箱"]').click()
time.sleep(1)  # 等一下,看看點選收件箱效果

# 通過執行js文法得到cookie值,為啥不用:driver.get_cookies(),是因為得到的結果不全
# 這裡花了些功夫才想到可以通過js擷取cookie,還是太相信driver.get_cookies()這個API了
# 經驗就是一條路不通,就要換條路了
cookies = driver.execute_script('return document.cookie')
driver.quit()  # 退出浏覽器

sid_flag = 'Coremail.sid='  # sid起始辨別
if (start := cookies.find(sid_flag)) == -1:
    print('cookies:', cookies)
    exit(0)
start += len(sid_flag)

if (end := cookies.find(';', start)) == -1:
    sid = cookies[start:]  # sid在結尾
else:
    sid = cookies[start:end]  # sid在中間

# 下面隻是拿擷取收件箱的請求結果,其他請求自行抓取分析
url = 'https://mail.163.com/js6/s?sid=' + sid + '&func=mbox:listMessages&mbox_folder_enter=1'
data = {'var': '<?xml version="1.0"?><object><int name="fid">1</int><string name="order">date</string><boolean name="desc">true</boolean><int name="limit">20</int><int name="start">0</int><boolean name="skipLockedFolders">false</boolean><string name="topFlag">top</string><boolean name="returnTag">true</boolean><boolean name="returnTotal">true</boolean></object>'}
headers = {
    'Accept': 'text/javascript',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-Mode': 'cors',
    'Accept-Encoding': 'gzip, deflate, br',
    'Host': 'mail.163.com',
    'Origin': "https://mail.163.com",
    'Referer': "https://mail.163.com/js6/main.jsp?sid=" + sid + "&df=mail163_letter",
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
    'Cookie': cookies
}
resp = requests.post(url, data, headers=headers).text
print(resp)
           

3.遇到問題

  1. 登入元素在iframe裡面導緻一開始無法定位元素,切換到iframe裡面即可
  2. 使用driver.get_cookies()擷取得cookie總是無法滿足requests後續請求,最終發現該方法傳回的cookie比真實的要少。最後曲線救國,通過selenium執行js方法擷取cookie

作者:janbar

出處:https://www.cnblogs.com/janbar

本文版權歸作者和部落格園所有,歡迎轉載,轉載請标明出處。喜歡我的文章請 [關注我] 吧。

如果您覺得本篇博文對您有所收獲,可點選 [推薦] 并 [收藏] ,或到右側 [打賞] 裡請我喝杯咖啡,非常感謝。