python识别滑块验证码captcha并自动登录
识别滑块验证码并自动登录
import cv2 from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains from urllib.request import urlretrieve from time import sleep # 初始化 def init(): # 定义为全局变量,方便其他模块使用 global url, browser, username, password, wait # 登录界面的url url = 'https://login.ouyeel.com/sso/login?service=https://www.ouyeel56.com/ttp/wl_index/index.jsp' # 实例化一个chrome浏览器 browser = webdriver.Chrome() # 设置等待超时 wait = WebDriverWait(browser, 20) # 登录 def input_username_password(username, password): # 打开登录页面 browser.get(url) # 获取用户名输入框 user = wait.until(EC.presence_of_element_located( (By.XPATH, '//*[@placeholder="T代码/N代码"]'))) # 获取密码输入框 passwd = wait.until( EC.presence_of_element_located((By.XPATH, '//*[@placeholder="账号密码"]'))) # 账户登录tab logintab = wait.until( EC.presence_of_element_located((By.XPATH, '//*[@id="tab-accountLogin"]'))) # 登录 login = wait.until( EC.presence_of_element_located((By.XPATH, '//*[@id="pane-accountLogin"]/form/div[@class="el-form-item login-submit"]'))) # 点击logintab logintab.click() # 输入用户名 user.send_keys(username) # 输入密码 passwd.send_keys(password) # 点击登录 login.click() sleep(1) # 获取滑块距离 def get_distance(bg_img, tp_img, mark_img): ''' bg: 背景图片 tp: 缺口图片 out:输出图片 ''' # 读取背景图片和缺口图片 bg_img = cv2.imread(bg_img) # 背景图片 tp_img = cv2.imread(tp_img) # 缺口图片 # 识别图片边缘 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(mark_img, bg_img) # 保存在本地 # 返回缺口的X坐标 distance = tl[0]*2/3 # print('原来:', tl[0]) # print('真实:', distance) return distance def move_to_gap(distance): # 得到滑块标签 slider = wait.until(EC.presence_of_element_located( (By.XPATH, '//*[@class="yidun_slider"]'))) # 使用click_and_hold()方法悬停在滑块上,perform()方法用于执行 ActionChains(browser).click_and_hold(slider).perform() # 使用move_by_offset()方法拖动滑块,perform()方法用于执行 ActionChains(browser).move_by_offset(xoffset=distance, yoffset=0).perform() # 模拟人类对准时间 sleep(0.5) # 释放滑块 ActionChains(browser).release().perform() # 主程序 def login(username, password, username_sec): # 初始化 init() # 登录 input_username_password(username, password) # 处理滑块,循环直到成功 captcha_sucess = 0 while not captcha_sucess: # 多次失败遭拦截,重新获取验证图片 try: fail = browser.find_element_by_xpath( '//*[@class="yidun_tips__text yidun-fallback__tip"]') fail.click() sleep(1) except: pass sleep(1) # 获取img对应src bg_image_url = browser.find_element_by_xpath( '//*[@alt="验证码背景"]').get_attribute('src') tp_image_url = browser.find_element_by_xpath( '//*[@alt="验证码滑块"]').get_attribute('src') # 使用urlretrieve()方法根据url下载缺口图片对象 urlretrieve(url=bg_image_url, filename='bg_image.jpg') urlretrieve(url=tp_image_url, filename='tp_image.jpg') # 获取滑块距离 distance = get_distance( 'bg_image.jpg', 'tp_image.jpg', 'mark.jpg') # 移动滑块 move_to_gap(distance+12) sleep(1) # 判断是否成功 try: hhcscys011 = browser.find_element_by_xpath( '//*[text()="{}"]'.format(username_sec)) print(hhcscys011) captcha_sucess = 1 print("滑块验证成功") except: pass # 程序入口 if __name__ == '__main__': login('username', 'password', 'username_sec')
参考文章:
主体:https://blog.csdn.net/Jeeson_Z/article/details/82047685
识别缺口找到滑块距离:https://blog.csdn.net/zhangzeyuaaa/article/details/119508407