selenium web自动化滑块验证码破解
京东登录页面滑块验证码破解步骤:
1.获取验证码图片base64编码、滑块图片base64编码
2.将base64编码转换成图片保存到指定目录下
3.获取验证码图片缺口的横坐标(通过opencv-python获取 pip install opencv-python)
4.获取滑块的横坐标、纵坐标
5.使用pyautogui来模拟滑动 (pip install pyautogui)
6.失败后重试(通过图片大小来判断滑动是否成功)
代码如下:testCase.py
import base64 from time import sleep import pyautogui from selenium import webdriver from Captcha.common.funcs import identify_gap driver = webdriver.Chrome() driver.maximize_window() driver.get('https://passport.jd.com/new/login.aspx') # 输入账号密码点击登录 driver.find_element('xpath', '//a[text()="账户登录"]').click() driver.find_element('xpath', '//*[@id="loginname"]').send_keys('weueidslf') driver.find_element('xpath', '//*[@id="nloginpwd"]').send_keys('weueidslf') driver.find_element('xpath', '//*[@id="loginsubmit"]').click() # 5. 失败后重试 while True: sleep(2) # 1.获取图片base64编码 # 背景图转换成base64编码 ele_bg = driver.find_element('xpath', '//div[@class="JDJRV-bigimg"]/img') base64_bg = ele_bg.get_attribute('src')[22:] # 滑块图片转换成base64编码 ele_bl = driver.find_element('xpath', '//div[@class="JDJRV-smallimg"]/img') base64_bl = ele_bl.get_attribute('src')[22:] print(base64_bl) # 当获取到的图片宽度不对时,说明图片消失了,破解成功,不需要再重试 if ele_bg.size.get('width') < 10: break # 2.将base64编码转换成图片保存到指定目录下 f = open('./lib/bg.jpg', mode='wb') f.write(base64.b64decode(base64_bg)) f.close() f = open('./lib/bl.jpg', mode='wb') f.write(base64.b64decode(base64_bl)) f.close() # 3.获取图片缺口的横坐标(通过opencv-python获取) x = identify_gap('./lib/bg.jpg', './lib/bl.jpg') # 原图和网页不一样大,需要处理缩放 x = int(x * 278 / 360) print("处理缩放后的缺口的横坐标:", x) # 4.获取滑块的坐标 # 如果电脑屏幕有缩放,需要*缩放比例,例如缩放125%:横坐标:int(ele_bl.location.get('x')*125%) 纵坐标需要加上浏览器顶部到京东页面的距离 bl_x = int(ele_bl.location.get('x')) bl_y = int(ele_bl.location.get('y')) + 145 print("滑块的坐标:", bl_x, bl_y) # 5.使用pyautogui来模拟滑动 # 鼠标移动到滑块的位置 pyautogui.moveTo(bl_x, bl_y) sleep(2) # 按下鼠标 pyautogui.mouseDown() # 移动鼠标到验证码缺口的位置(如果滑一次就移动到缺口位置,则还是不能登录,需要模拟人为滑动,滑动位置调整几次) pyautogui.moveTo(bl_x + x - 15, bl_y, duration=0.4) pyautogui.moveTo(bl_x + x + 11, bl_y, duration=0.3) pyautogui.moveTo(bl_x + x, bl_y, duration=0.3) # 松开鼠标 pyautogui.mouseUp() sleep(2) driver.quit()
funcs.py (获取验证码缺口位置)
import cv2 def identify_gap(bg, tp): ''' bg: 背景图片 tp: 缺口图片 ''' # 读取背景图片和缺口图片 bg_img = cv2.imread(bg) # 背景图片 tp_img = cv2.imread(tp) # 缺口图片 # 识别图片边缘 bg_edge = cv2.Canny(bg_img, 100, 200) tp_edge = cv2.Canny(tp_img, 100, 200) # 转换图片格式 bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB) tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB) # 缺口匹配 res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配 # 绘制方框 th, tw = tp_pic.shape[:2] tl = max_loc # 左上角点的坐标 br = (tl[0] + tw, tl[1] + th) # 右下角点的坐标 cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2) # 绘制矩形 # cv2.imwrite(out, bg_img) # 保存在本地 # 返回缺口的X坐标 print("返回缺口的X坐标", tl[0]) return tl[0] if __name__ == '__main__': identify_gap('../lib/bg.jpg', '../lib/bl.jpg')
工程目录: