很多时候登录操作是比较复杂的,因为存在各种反爆破操作,以及为了安全性提交数据都会存在加密。如果要完全模拟代码去实现登录操作是比较复杂 并且该网站后续更新了登录安全相关功能 那么登录的模拟操作又得修改。但是通过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.遇到问题
登录元素在iframe里面导致一开始无法定位元素 切换到iframe里面即可使用driver.get_cookies()获取得cookie总是无法满足requests后续请求 最终发现该方法返回的cookie比真实的要少。最后曲线救国 通过selenium执行js方法获取cookie


