selenium-wire的使用,进行滑动验证码验证
1.安装
pip install selenium-wire
2.流程
1.获取滑动验证码缺图以及滑动图 2.计算其需要移送的距离 3.按住滑块按相应距离移送到相应位置 4.验证成功,后续步骤,验证失败,循环1、2、3步骤,直至成功
2.1. 访问相关网站,出现验证码
from seleniumwire import webdriver from selenium.webdriver.common.by import By from seleniumwire.webdriver import ActionChains option = webdriver.ChromeOptions() option.add_argument('--disable-blink-features=AutomationControlled') option.add_experimental_option("excludeSwitches", ['enable-automation']) driver = webdriver.Chrome(options=option) driver.implicitly_wait(10) driver.get("xxxxx网址xxxxx") driver.maximize_window() driver.find_element(by=By.ID, value='inputText').send_keys('大家好') driver.find_element(by=By.ID, value='composeUserTextBtn').click() time.sleep(2) loop(driver) list_cookies = driver.get_cookies() cookies_dict = {} for s in list_cookies: cookies_dict[s['name']] = s['value']
2.2.通过seleniumwire截取滑动验证码相关图片,保存置
content = {} all_request = driver.requests for req in all_request: if 'xxxxx/generate' == req.url: body = req.response.body content = json.loads(body) # break
background = content['result']['background'] slide = content['result']['slide'] # 转换 base64_to_image(background, full_path) base64_to_image(slide, gap_path)
def base64_to_image(base64_str, image_path=None):
"""在第一步里:base64转化为image"""
base64_data = re.sub('^data:image/.+;base64,', '', base64_str)
byte_data = base64.b64decode(base64_data)
image_data = BytesIO(byte_data)
img = Image.open(image_data)
if image_path:
img.save(image_path)
return img
2.3.计算滑动图到缺图位置距离
from io import BytesIO
from PIL import Image
def cv_imread(file_path): cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1) # im decode读取的是rgb,如果后续需要opencv处理的话,需要转换成bgr,转换后图片颜色会变化 cv_img = cv2.cvtColor(cv_img, cv2.COLOR_RGB2BGR) return cv_img def match_gaps(full, gap): """第二步:匹配缺口照片在完整照片的位置""" # 读取图片文件信息 img_full = cv_imread(full) # 以灰度模式加载图片 template = cv_imread(gap) # 方法 methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED] # 记录每个方法的距离 left = [] # 最接近值 min_ = [] for method in methods: # 匹配 res = cv2.matchTemplate(img_full, template, method) # 获取相关内容 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) if method == cv2.TM_SQDIFF_NORMED: min_.append(min_val - 0.0) left.append(min_loc[0]) else: min_.append(1.0 - max_val) left.append(max_loc[0]) index = min_.index(numpy.min(min_)) # print("选用第{:d}个方法, 差为:{:f},距离为:{:d}".format(index + 1, min_[index], left[index])) return left[index]
2.4. 根据距离,先找到按钮,模拟移动
action = ActionChains(driver) span = driver.find_element(by=By.CLASS_NAME, value='sliderMask') action.click_and_hold(span).move_by_offset(xoffset=distance+20, yoffset=0).perform() action.release().perform()
2.5.滑动后看验证图是否消失
def judgeBox(driver): """第四步:判断拼图是否存在""" box_js = "return document.getElementById('composeUserTextBtn').className" box_value = driver.execute_script(box_js) if box_value == 'compose disabled': return False else: return True
2.6. 因验证码可能失败,所以需要循环前几步骤
def loop(driver): try: full_path, gap_path = get_images(driver) distance = match_gaps(full_path, gap_path) print("distance:", distance) # tracks = get_tracks(distance) # print("tracks:", tracks) action = ActionChains(driver) span = driver.find_element(by=By.CLASS_NAME, value='sliderMask') action.click_and_hold(span).move_by_offset(xoffset=distance+20, yoffset=0).perform() action.release().perform() except: pass time.sleep(2) if judgeBox(driver): loop(driver)
此文主要参考:
https://blog.csdn.net/weixin_43801662/article/details/124660755
https://www.cnblogs.com/Owen-ET/p/16359144.html