python selenium web网站登录缺口图片验证码识别

发布时间 2023-05-30 16:07:48作者: BelleLs
def login():
    driver = webdriver.Chrome("browser_driver/chromedriver.exe")
    driver.get("http://xxxxxx/#/login")
    driver.maximize_window()
    sleep(1)
    driver.find_element(By.CSS_SELECTOR, '[placeholder="请输入手机号"]').send_keys("18866664444")
    sleep(1)
    driver.find_element(By.XPATH, '//span[contains(string(),"获取验证码")]/..').click()
    sleep(1)
    while True:
        # 获取缺口图片和背景图片的base64字符串
        arr_s = driver.find_element(By.XPATH, '//div[@class="verify-sub-block"]').find_element(By.TAG_NAME, 'img')\
            .get_attribute("src").split(",")[1]
        arr_b = driver.find_element(By.XPATH, '//div[@class="verify-img-panel"]').find_element(By.TAG_NAME, 'img')\
            .get_attribute("src").split(",")[1]

        # 解码并写入文件
        img_data_s = base64.b64decode(arr_s)
        with open("../resource/img_s.png", mode="wb") as f:
            f.write(img_data_s)
        img_data_b = base64.b64decode(arr_b)
        with open("../resource/img_b.png", mode="wb") as f:
            f.write(img_data_b)

        # 读取缺口图片和背景图片
        s_img = cv2.imread('../resource/img_s.png')
        b_img = cv2.imread('../resource/img_b.png')

        # 识别图片边缘的灰度图(轮廓线)
        s_edge = cv2.Canny(s_img, 100, 200)
        b_edge = cv2.Canny(b_img, 100, 200)

        # 转换图片为RGB格式
        s_pic = cv2.cvtColor(s_edge, cv2.COLOR_GRAY2RGB)
        b_pic = cv2.cvtColor(b_edge, cv2.COLOR_GRAY2RGB)

        # 缺口匹配,res每个位置的匹配结果,代表了匹配的概率,选出其中概率的最高点,即为缺口位置
        res = cv2.matchTemplate(b_pic, s_pic, cv2.TM_CCOEFF_NORMED)

        # min_val匹配的最小值, max_val匹配的最大值,min_loc最小的位置, max_loc最大位置
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

        slider = driver.find_element(By.CLASS_NAME, 'verify-move-block')
        action = ActionChains(driver)
        
        # 观察有12左右的位置偏差,所以在x坐标位移加上了12的偏差值
        action.drag_and_drop_by_offset(slider, xoffset=max_loc[0]+12, yoffset=0).perform()
        sleep(1.5)

        # 判断验证通过后退出循环
        try:
            driver.find_element(By.XPATH, '//span[contains(string(),"获取验证码")]/../span[2]')
            break
        except NoSuchElementException:
            continue
    # 登录
    driver.find_element(By.XPATH, '//span[contains(string(),"登 录")]/..').click()
    sleep(2)