# -*- coding : utf-8 -*-
# created by Wayne
'''
使用selenium自动对网站登录的滑块验证码进行处理
'''
import time
import json
import requests
import base64 # 图片解码
from PIL import Image # 图像截图
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import presence_of_element_located as PE
from selenium.webdriver.common.action_chains import ActionChains # 行为链模拟鼠标操作
# 元素点选操作
driver = webdriver.Chrome() #使用google浏览器
driver.get('https://dun.163.com/trial/sense')#示例网站演示
# print(driver.page_source)
wait = WebDriverWait(driver, 10) # 等待10s
wait.until(PE((By.XPATH, '/html/body/main/div[1]/div/div[2]/div[2]/ul/li[2]'))).click() # 点击可疑滑块元素
js = f'window.scrollTo(0,{150})' # 滚动条下拉
driver.execute_script(js)
wait.until(PE((By.XPATH, '//div[@class="yidun_intelli-tips"]'))).click() # 点击验证图片显示
time.sleep(2) # 暂停2s截图需要
# 截图操作
path = r'd:/demo/yzm' # 保存图片路径
driver.save_screenshot(f'{path}/163hk.png')
img = Image.open(f'{path}/163hk.png') # 打开保存的图片
position = img.crop((468, 505, 841, 688)) # 截取图片的位置,x,y轴对角线坐标
position.save(f'{path}/yzm.png')
# 图片识别,调用api接口(图灵网站生成)
def b64_api(username, password, img_path, ID):
with open(img_path, 'rb') as f:
b64_data = base64.b64encode(f.read())
b64 = b64_data.decode()
data = {"username": username, "password": password, "ID": ID, "b64": b64, "version": "3.1.1"}
data_json = json.dumps(data)
result = json.loads(requests.post("http://www.tulingtech.xyz/tuling/predict", data=data_json).text)
return result
# 线性滑动处理
def get_move_track(gap):
track = [] # 移动轨迹
current = 0 # 当前位移
# 减速阈值
mid = gap * 4 / 5 # 前4/5段加速 后1/5段减速
t = 0.2 # 计算间隔
v = 0 # 初速度
while current < gap:
if current < mid:
a = 5 # 加速度为+5
else:
a = -5 # 加速度为-5
v0 = v # 初速度v0
v = v0 + a * t # 当前速度
move = v0 * t + 1 / 2 * a * t * t # 移动距离
current += move # 当前位移
track.append(round(move)) # 加入轨迹
return track
result = b64_api('username', 'password', f"{path}/yzm.png", '78915616')
print(result)# username和password要输入图灵网真实用户
hk_x = int(result['data']['滑块']['X坐标值']) # 取滑块的x坐标值
hk_q = int(result['data']['缺口']['X坐标值']) # 取滑块缺口的X坐标值
distance = int((hk_q - hk_x) * 0.82) # 计算划过的距离,调整滑块位置
move_track = get_move_track(distance) # 距离传入滑动线性处理方法实现验证码识别
# 行为链方式进行模拟鼠标操作
element = wait.until(PE((By.CLASS_NAME, 'yidun_jigsaw'))) # 验证滑块点击元素获取
ActionChains(driver).click_and_hold(element).perform() # 按住鼠标对验证元素进行模拟执行
# 循环滑块移动距离
for e in move_track:
ActionChains(driver).move_by_offset(e, 0).perform()
ActionChains(driver).release().perform() # 释放鼠标完成验证
print('验证成功...')
time.sleep(20)
driver.close() # 关闭