新版无完整背景图片滑块验证码

步骤:

1、将图片灰度,两张都要灰度

2、将图片锐化,两张都要锐化

3、计算2d卷积核,两张都要计算

4、卷积结果最大的点所在区域即为与卷积核(小滑块)边缘重合度最高的区域。

那么在背景图中,与小滑块重合度最高的区域应该为缺口区域。因此我们找到的卷积结果最大的点就是背景图缺口的中心点。

import requests
import cv2
import time
import os
from scipy import signal
from selenium import webdriver	#用来驱动浏览器的
from selenium.webdriver import ActionChains	#破解滑动验证码的时候用,可拖动图片
from selenium.webdriver.common.keys import Keys

# 通过新版无原图滑块验证码
class Pass_slide:

    def __init__(self):
        self.driver = webdriver.Chrome()


    def input_user_pwd(self):
        self.driver.get('https://star.toutiao.com/')
        # 数字账号密码登录
        self.driver.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[2]/div[2]/div[1]').click()
        time.sleep(1)
        self.driver.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[1]').click()
        time.sleep(1)
        # 输入账号
        self.driver.find_element_by_xpath('//*[@id="account-sdk"]/section/div[3]/div[1]/div[2]/div/input').send_keys(
            'username'
        )
        # 输入密码
        self.driver.find_element_by_xpath('//*[@id="account-sdk"]/section/div[3]/div[2]/div/div/input').send_keys(
            'password'
        )
        time.sleep(1)
        # 点击登录
        self.driver.find_element_by_xpath('//*[@id="account-sdk"]/section/div[6]/button').click()
        time.sleep(1)

    def slide_button(self):
        # 定位滑块位置
        # 方式一:通过图片定位位置
        # button = self.driver.find_element_by_xpath('//*[@id="account-sdk-slide-container"]/div/div[2]/img[2]')
        # 方式二: 用 Xpath 定位位置
        # button = self.driver.find_element_by_xpath(
        #     '//*[@id="account-sdk-slide-container"]/div/div[3]/div[2]/div[2]/div'
        # )
        # 方式三:通过 class 来定位
        button = self.driver.find_element_by_class_name('sc-jKJlTe')
        time.sleep(1)
        return button

    def move_to_slide(self,distance):
        # tracks是要传入的移动轨迹
        ActionChains(self.driver).click_and_hold(self.slide_button()).perform()  # 移动
        for x in self.track(distance):
            ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()
        time.sleep(0.3)
        ActionChains(self.driver).release().perform()

    def track(self, distance):  # distance为传入的总距离
        # 移动轨迹
        track = []
        current = 0  # 当前位移
        mid = distance * 4 / 5  # 减速阈值
        t = 0.2  # 计算间隔
        v = 1  # 初速度
        while current < distance:
            if current < mid:
                a = 4  # 加速度为2
            else:
                a = -3  # 加速度为-2
            v0 = v
            v = v0 + a * t  # 当前速度
            move = v0 * t + 1 / 2 * a * t * t  # 移动距离
            current += move  # 当前位移
            track.append(round(move))  # 加入轨迹
        return track

    def download_slide_auth_code_img(self):
        # 下载滑块,和背景缺口图片
        if not os.path.exists('./Auth_Slide_Img'):
            os.mkdir('./Auth_Slide_Img')
        big_img_url = self.driver.find_element_by_xpath(
            '//*[@id="account-sdk-slide-container"]/div/div[2]/img[1]').get_attribute('src')  # 缺口背景图片 地址
        small_img_url = self.driver.find_element_by_xpath(
            '//*[@id="account-sdk-slide-container"]/div/div[2]/img[2]').get_attribute('src')  # 滑块的图片 地址

        with open('Auth_Slide_Img/big_slide_img.jpg', 'wb') as f:
            f.write(requests.get(big_img_url).content)
        with open('Auth_Slide_Img/small_slide_img.jpg', 'wb') as f:
            f.write(requests.get(small_img_url).content)


    # 图片转为 灰度图片
    def img2gray(self, image):
        self.download_slide_auth_code_img()
        img_rgb = cv2.imread(image)  # 读入图片
        img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)  # 转灰度图片
        # cv2.imwrite(image, img_gray)  # 保存图片,第一个参数:path, 第二个参数:保存的图片
        return img_gray

    # 锐化边缘
    def canny_edge(self, image):
        self.img2gray(image)
        img = cv2.imread(image, 0)
        blur = cv2.GaussianBlur(img, (3, 3), 0)  # 用高斯滤波处理原图像降噪
        canny = cv2.Canny(blur, threshold1=200, threshold2=300)  # 锐化图片
        # cv2.imwrite(image, canny)  # 保存图片
        # cv2.imshow('candy', can)  # 弹出图片
        cv2.waitKey()
        cv2.destroyAllWindows()  # 关闭窗口
        return canny

    # 计算 2d 卷积
    def convole2d(self, bg_array, fillter):
        bg_h, bg_w = bg_array.shape[:2]
        fillter_h, fillter_w = fillter.shape[:2]
        c_full = signal.convolve(bg_array, fillter, mode='full')
        kr, kc = fillter_h // 2, fillter_w // 2
        c_same = c_full[
                 fillter_h - kr - 1: bg_h + fillter_h - kr - 1,
                 fillter_w - kc - 1: bg_w + fillter_w - kr - 1,
                 ]
        return c_same

    # 最终位置
    def find_max_point(self, arrays, search_on_horizontal_center=False):
        max_point = 0
        max_point_pos = None

        array_rows, arrays_cols = arrays.shape
        if search_on_horizontal_center:
            for col in range(arrays_cols):
                if arrays[array_rows // 2, col] > max_point:
                    max_point = arrays[array_rows // 2, col]
                    max_point_pos = col, array_rows // 2
        else:
            for row in range(array_rows):
                for col in range(arrays_cols):
                    if arrays[row, col] > max_point:
                        max_point = arrays[row, col]
                        max_point_pos = col, row

        return max_point_pos

    def main(self):
        self.input_user_pwd()
        canny1 = self.canny_edge('Auth_Slide_Img/big_slide_img.jpg')
        canny2 = self.canny_edge('Auth_Slide_Img/small_slide_img.jpg')
        convoled_after = self.convole2d(canny1, canny2)
        distance = self.find_max_point(convoled_after)
        print(distance)
        self.move_to_slide(distance[0])
        return distance[0]

    def is_login(self):

        try:
            time.sleep(3)
            html = self.driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div[1]/button/i').click()
            print('login success!')
            self.driver.find_element_by_xpath(
                '/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/span').click()
            time.sleep(1)
            self.driver.find_element_by_xpath(
                '/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[3]/div/div[1]/button/i').click()
            return True
        except:
            self.driver.close()
            print('login failed trying...')
            # self.is_login()
            return False

    def movement_search(self):
        self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div[1]/div/div[2]/div[3]/div/div[1]/input').send_keys('口红')
        time.sleep(10)
        self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div[1]/div/div[2]/div[3]/i').send_keys(Keys.ENTER)
        time.sleep(6)
        self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div/div/div[1]/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]').click()
        price1 = self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div/div[2]/div[2]/div[1]/div[1]/div[1]/div[1]/div/div[1]/div[1]/div/text()').extract()
        price2 = self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div[1]/div/text()').extract()
        print(price1, price2)



run = Pass_slide()
run.main()
login_result = run.is_login()
print(login_result)

run.movement_search()


 posted on 2020-09-11 12:07  Rannie`  阅读(749)  评论(0编辑  收藏  举报
去除动画
找回动画