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