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

 

posted @ 2023-01-05 15:42  lingwang3  阅读(861)  评论(0编辑  收藏  举报