Python implements JD slider verification code login

Don't say much and go directly to the code, if you don't understand, just read the comments or private messages

import time

from urllib import request

import cv2
import pyautogui
from selenium import webdriver
from selenium.webdriver import ChromeOptions
import random

# 登陆账号
USERNAME = 'xxxx'
# 登陆密码
PASSWORD = 'xxxx'
# 滑块距离屏幕左上角的x, y像素, 需根据自己屏幕大小调整
SLIDE_X_POSITION, SLIDE_Y_POSITION = 881, 441


class SlideUtils:

    @staticmethod
    def find_pic(background, slide):
        """
        获取背景图与滑块图的最佳位置
        """
        # 读取背景灰度图片
        background_gray = cv2.imread(background, 0)
        # 读取滑块灰度图片
        slide_gray = cv2.imread(slide, 0)
        # 匹配滑块位置
        res = cv2.matchTemplate(background_gray, slide_gray, cv2.TM_CCOEFF_NORMED)
        # 获取最佳与最差匹配
        value = cv2.minMaxLoc(res)
        return value[2][0]

    @staticmethod
    def slide_by_autogui(x, y, offset):
        """
        使用pyautogui实现滑块并自定义轨迹方程
        """
        xx = x + offset
        pyautogui.moveTo(x, y, duration=0.1)
        pyautogui.mouseDown()
        y += random.randint(9, 19)
        pyautogui.moveTo(x + int(offset * random.randint(15, 23) / 20), y, duration=0.28)
        y += random.randint(-9, 0)
        pyautogui.moveTo(x + int(offset * random.randint(17, 21) / 20), y, duration=random.randint(20, 31) / 100)
        y += random.randint(0, 8)
        pyautogui.moveTo(xx, y, duration=0.3)
        pyautogui.mouseUp()


def send_keys_interval(element, text, interval=0.1):
    """
    webdriver 模拟人输入文本信息
    """
    for c in text:
        element.send_keys(c)
        time.sleep(random.randint(int(interval * 500), int(interval * 1500)) / 1000)


class JdLoginChromeWebdriverPlus:
    """
    京东登录chrome webdriver增强
    """
    def __init__(self, retry_times=5):
        option = ChromeOptions()
        option.add_experimental_option('excludeSwitches', ['enable-automation'])
        self.driver = webdriver.Chrome(options=option)
        self.driver.maximize_window()
        self.retry_times = retry_times
        self.login_success = False

    def login(self, username, password):
        driver = self.driver
        driver.get('https://passport.jd.com/uc/login')
        # 切換账号密码登录
        driver.find_element_by_class_name('login-tab-r').find_element_by_tag_name('a').click()
        # 设置账号密码
        send_keys_interval(driver.find_element_by_id('loginname'), username)
        send_keys_interval(driver.find_element_by_id('nloginpwd'), password)

        time.sleep(random.random())

        # 登录
        driver.find_element_by_id('loginsubmit').click()

        time.sleep(random.randint(1, 3))

        for i in range(self.retry_times):
            # 获取验证码图片
            # 用于找到登录图片的大图
            try:
                background = driver.find_element_by_xpath(r'//div/div[@class="JDJRV-bigimg"]/img')
            except:
                # 未查找到登陆图片则认为成功
                self.login_success = True
                break
            # 用来找到登录图片的小滑块
            slide = driver.find_element_by_xpath(r'//div/div[@class="JDJRV-smallimg"]/img')
            background_url = background.get_attribute("src")
            slide_url = slide.get_attribute("src")
            background_img = 'background_img.png'
            slide_img = 'slide_img.png'
            # 下载背景大图保存到本地
            request.urlretrieve(background_url, background_img)
            # 下载滑块保存到本地
            request.urlretrieve(slide_url, slide_img)
            # 获取最佳x偏移量
            x = SlideUtils.find_pic(background_img, slide_img)
            print(f'本地最佳偏移量: {
      
      x}')
            # 计算缩放
            # 获取下载背景图宽度
            w1 = cv2.imread(background_img).shape[1]
            # 获取网页背景图宽度
            w2 = background.size['width']
            # 计算实际页面x偏移量
            x = x * w2 / w1
            print(f'实际最佳偏移量: {
      
      x}')
            # 其中x为屏幕左上角至滑块中心的横向像素值,y为屏幕左上角至滑块中心纵向像素值, 可根据自己屏幕配置
            SlideUtils.slide_by_autogui(SLIDE_X_POSITION, SLIDE_Y_POSITION, x)

    def is_login(self):
        """
        是否已登录成功 
        """
        return self.login_success

    def get_cookies(self):
        """
        获取webdriver cookies
        """
        return self.driver.get_cookies()

    def get_cookies_dict(self):
        """
        获取字典结构的cookie
        """
        cookies = self.get_cookies()
        res = {
    
    }
        for cookie in cookies:
            res[cookie['name']] = cookie['value']
        return res

    def get_driver(self):
        """
        获取webdriver对象
        """
        return self.driver

    def close(self):
        self.driver.close()

    def quit(self):
        self.driver.quit()


driver = JdLoginChromeWebdriverPlus()
driver.login(USERNAME, PASSWORD)
print(driver.is_login())
print(driver.get_cookies_dict())
driver.quit()

Slider trajectory equation reference: https://www.bilibili.com/video/BV1cC4y1Y7Wm

Guess you like

Origin blog.csdn.net/qq_33129963/article/details/122978406