基于 selenium 模拟登陆 12306 滑块问题 已解决
首先注明,在使用 selenium 模拟登陆之前我首先用浏览器手动登录过 12306,这一步可能也影响了后续验证,影响先忽略
先讲重点,这里需要规避检测和去除特征识别,不然滑块验证就会出现如图错误哎呀,出错了,点击刷新再来一次(error:tMKTxq)
解决方法是(借鉴其它博主的方法,先拿来主义,原理不深纠):
# 实现规避检测
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option("detach", True)
bro=webdriver.Chrome(service=ser,options=option)
# 传入 URL
bro.get("https://kyfw.12306.cn/otn/resources/login.html")
# 采取去除特征识别,即以下两行代码。
script = 'Object.defineProperty(navigator, "webdriver", {get: () => false,});'
bro.execute_script(script)
可以采用以下代码进行验证,输出结果为False
则滑块认证请求可以实现
js = 'return window.navigator.webdriver'
print(bro.execute_script(js)) # 可以直接在终端输出webdriver检测结果
打开 12306 官网登录界面,按 F12 进入开发者模式,点击元素选择键(箭头1所示),然后点击账号输入栏(箭头2所示),可以看到其对应的标签 id="J-userName"
,在这里使用 find_element(By.ID/CLASSNAME,'')
,进行标签查找
然后便可以用send_keys("")
实现账号输入
# 找到用户名输入标签
userName_TAG=bro.find_element(By.ID,"J-userName")
userName_TAG.send_keys("183xxxx0472")
sleep(1)
同样的可以找到密码输入对应的标签
可以实现密码填充
password_TAG=bro.find_element(By.ID,"J-password")
password_TAG.send_keys("2022xxxxLZHx")
sleep(1)
依次可以找到登录的id="J-login"
对应的标签
账号密码传入完毕,然后使用click()
点击登录
login_TAG=bro.find_element(By.ID,"J-login")
login_TAG.click()
sleep(1)
滑块对应的id="nc_1_n1z"
找到滑块
#找到滑块
div_TAG=bro.find_element(By.ID,"nc_1_n1z")
拖动滑块,对应位置像素值变化,可以看到滑块最终位置为 300
拖动滑块需要使用动作链,定义动作链对象,点击并拖动使用 click_and_hold(div_TAG)
:
# 动作链
action=ActionChains(bro)
# 点击并长按指定的标签
action.click_and_hold(div_TAG)
使用move_by_offset(x,y): x 水平方向 y数值方向 两个参数
实现滑块水平 300 像素拖动,移动过程中,采用渐移或一步到位影响不大
# 渐移
for i in range(5):
#perform() 立即执行动作链操作
# move_by_offset(x,y): x 水平方向 y数值方向 两个参数
action.move_by_offset(60,0).perform()
sleep(0.3)
最后释放滑块
action.release().perform()
最终实现代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# 导入动作链对应的类
from selenium.webdriver import ActionChains
# 反检测
from selenium.webdriver import ChromeOptions
from time import sleep
option=ChromeOptions()
# 谷歌驱动路径
ser = Service(executable_path='./chromedriver.exe')
# 实现规避检测
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option("detach", True)
bro=webdriver.Chrome(service=ser,options=option)
# 传入 URL
bro.get("https://kyfw.12306.cn/otn/resources/login.html")
# 采取去除特征识别,即以下两行代码。
script = 'Object.defineProperty(navigator, "webdriver", {get: () => false,});'
bro.execute_script(script)
js = 'return window.navigator.webdriver'
print(bro.execute_script(js)) # 可以直接在终端输出webdriver检测结果
# 找到用户名输入标签
userName_TAG=bro.find_element(By.ID,"J-userName")
userName_TAG.send_keys("183xxxx0472")
sleep(1)
password_TAG=bro.find_element(By.ID,"J-password")
password_TAG.send_keys("2022waxxxxx")
sleep(1)
login_TAG=bro.find_element(By.ID,"J-login")
login_TAG.click()
sleep(1)
#找到滑块
div_TAG=bro.find_element(By.ID,"nc_1_n1z")
# 动作链
action=ActionChains(bro)
# 点击并长按指定的标签
action.click_and_hold(div_TAG)
# 渐移
for i in range(5):
#perform() 立即执行动作链操作
# move_by_offset(x,y): x 水平方向 y数值方向 两个参数
action.move_by_offset(60,0).perform()
sleep(0.3)
action.release().perform()
# print(div_TAG)