import time from urllib import request import cv2 import pyautogui from selenium import webdriver from selenium.webdriver import ChromeOptions import random # 登陆账号 USERNAME = '' # 登陆密码 PASSWORD = '' # 滑块距离屏幕左上角的x, y像素, 需根据自己屏幕大小调整 开始位置 SLIDE_X_POSITION, SLIDE_Y_POSITION = 1171, 439 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() 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') # 切換账号密码登录 from selenium.webdriver.common.by import By el = driver.find_element(By.XPATH, r"//*[@id='content']/div[2]/div[1]/div/div[3]/a") el.click() click_keyi_username = driver.find_element(By.ID, "loginname").send_keys(username) click_keyi_username = driver.find_element(By.ID, "nloginpwd").send_keys(password) login_button = driver.find_element(By.ID, "loginsubmit") login_button.click() time.sleep(random.randint(1, 3)) for i in range(self.retry_times): # 获取验证码图片 # 用于找到登录图片的大图 try: background = driver.find_element(By.XPATH,r'//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[1]/img') except: # 未查找到登陆图片则认为成功 self.login_success = True break # 用来找到登录图片的小滑块 slide = driver.find_element(By.XPATH,r'//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[2]/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() if __name__ == '__main__': driver = JdLoginChromeWebdriverPlus() driver.login(USERNAME, PASSWORD) print(driver.is_login()) print(driver.get_cookies_dict()) driver.quit()
jd 滑块验证
最新推荐文章于 2024-04-12 11:35:04 发布