这段时间一直在做京东滑块验证,也翻阅大量博客,我认为有两处难点:
- 滑动轨迹 - 京东将大量模拟人为的轨迹方程都被封了,导致即使对齐也无法通过验证。
- 滑动距离 - 经过翻阅博客,发现大多数博客采用的方法是通过cv2识别计算出滑动距离,这个方法通过率并不高(可能是我技术有限,使用cv2方式一次都没通过)。
滑动轨迹自然不必多说,网上一搜一大堆,我使用的是模拟人为加速度,最后滑超一点然后滑动回来(代码放在后面)
滑动距离,一开始使用cv2搞了一整天一次也没通过,最后改用深度学习模型,自测通过率超过80%,废话不多说直接看成果。
JD_1
首先下载滑动背景图作为模型训练输入,训练好模型后为了方便调用,搭建Flask接口,其次下载背景图调用模型API接口,将图片作为推理输入,这里注意:京东滑动背景图是base64格式,需要先解码保存,随后传入模型进行推理。
# 推理函数
def requests_img(base):
image_base64 = base[22:]
imgdata = base64.b64decode(image_base64) # base64解码
with open(f"images/test.png", 'wb') as f:
f.write(imgdata)
data = {
'image': open('images/test.png', 'rb')
}
data = requests.post('http://127.0.0.1:5000/upload', files=data) # 将图片传入API接口获得缺口左上和右下角缺口
return data.json().get('result').get('xmin')*0.82 # 下载的图片和网站上预览图片大小不一致,所以需要设置偏移
# 移动轨迹函数
def get_track8(distance):
# 移动轨迹
tracks = []
# 当前位移
current = 0
# 减速阈值
mid = distance * 4 / 5
# 时间间隔
t = 0.2
# 初始速度
v = 0
while current < distance:
if current < mid:
a = random.uniform(2, 5)
else:
a = -(random.uniform(12.5, 13.5))
v0 = v
v = v0 + a * t
x = v0 * t + 1 / 2 * a * t * t
current += x
if 0.6 < current - distance < 1:
x = x - 0.53
tracks.append(round(x, 2))
elif 1 < current - distance < 1.5:
x = x - 1.4
tracks.append(round(x, 2))
elif 1.5 < current - distance < 3:
x = x - 1.8
tracks.append(round(x, 2))
else:
tracks.append(round(x, 2))
print(sum(tracks))
return tracks
第一次发文,希望各位大佬多多指正,如果需要源码或者模型定制尽管私信我,感谢支持!!
---------------------------------------------------------分割线---------------------------------------------------------------
刚刚有兄弟后台私信,向我要源码和模型,我所幸直接粘在下面了,兄弟们需要自己拿就好,仅供交流学习!!
另外模型和配置文件我还不会在这里发,需要的话私信我就好了
# -*- coding:utf-8 -*-
from configparser import ConfigParser
import random
from selenium import webdriver
import time
import base64
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import requests
class CreateConfig:
def __init__(self, wz):
config = ConfigParser(interpolation=None)
config.read('config.ini', encoding='utf-8')
self.key = config.get('keys', wz)
self.passwd = config.get('passwd', wz)
self.key_send = config.get('XPATH', f'{wz}_key_send')
self.passwd_send = config.get('XPATH', f'{wz}_passwd_send')
self.login = config.get('XPATH', f'{wz}_login')
self.hk = config.get('XPATH', f'{wz}_hk')
self.url = config.get('URL', f'{wz}_url')
self.ua = config.get('UA', 'ua')
self.img = config.get('XPATH', f'{wz}_img')
self.img_save_path = config.get('PATH', 'img_path')
self.wz = wz
self.title = config.get('TITLE', f'{wz}_title')
class BrowserLogin(CreateConfig):
def __init__(self, wz):
super().__init__(wz)
self.options = Options()
self.options.add_argument(self.ua)
self.options.add_argument('disable-infobars')
self.options.add_experimental_option("useAutomationExtension", False)
self.browser = webdriver.Chrome(options=self.options)
def browser_login(self):
time.sleep(1)
return self.browser.find_element(By.XPATH, self.hk), self.browser.find_element(By.XPATH,
self.img).get_attribute('src')
def detect(self, img_url):
if self.wz == 'JD':
image_base64 = img_url[22:]
img_data = base64.b64decode(image_base64)
elif self.wz == 'ZH':
img_data = requests.get(img_url).content
with open(self.img_save_path, 'wb') as f:
f.write(img_data)
data = {
'image': open(self.img_save_path, 'rb')
}
data = requests.post('http://127.0.0.1:5000/upload', files=data)
if self.wz == 'JD':
return data.json().get('result').get('xmin') * 0.82
else:
return data.json().get('result').get('xmax')
def get_track(self, distance):
"""
根据偏移量和手动操作模拟计算移动轨迹
:param distance: 偏移量
:return: 移动轨迹
"""
# 移动轨迹
tracks = []
# 当前位移
current = 0
# 减速阈值
mid = distance * 4 / 5
# 时间间隔
t = 0.2
# 初始速度
v = 0
while current < distance:
if current < mid:
a = random.uniform(2, 5)
else:
a = -(random.uniform(12.5, 13.5))
v0 = v
v = v0 + a * t
x = v0 * t + 1 / 2 * a * t * t
current += x
if 0.6 < current - distance < 1:
x = x - 0.53
tracks.append(round(x, 2))
elif 1 < current - distance < 1.5:
x = x - 1.4
tracks.append(round(x, 2))
elif 1.5 < current - distance < 3:
x = x - 1.8
tracks.append(round(x, 2))
else:
tracks.append(round(x, 2))
print(sum(tracks))
return tracks
def move_to_gap(self, slider, tracks): # slider是要移动的滑块,tracks是要传入的移动轨迹
ActionChains(self.browser).click_and_hold(slider).perform()
for track in tracks:
ActionChains(self.browser).move_by_offset(xoffset=track, yoffset=0).perform()
time.sleep(0.18)
# 反向滑动
ActionChains(self.browser).move_by_offset(xoffset=-3, yoffset=0).perform()
ActionChains(self.browser).move_by_offset(xoffset=3, yoffset=0).perform()
time.sleep(0.7)
ActionChains(self.browser).release().perform()
def run(self):
"""
:return:
"""
self.browser.get(self.url)
time.sleep(0.5)
self.browser.refresh()
time.sleep(0.7)
self.browser.find_element(By.XPATH, self.key_send).send_keys(self.key)
self.browser.find_element(By.XPATH, self.passwd_send).send_keys(self.passwd)
time.sleep(0.8)
self.browser.find_element(By.XPATH, self.login).click()
time.sleep(1)
while True:
title = self.browser.title
if title != self.title:
break
else:
hk, img_url = self.browser_login()
detect_value = self.detect(img_url)
self.move_to_gap(hk, self.get_track(int(detect_value)))
time.sleep(2)
if __name__ == '__main__':
bro = BrowserLogin('JD')
bro.run()
版权归原作者 Thing_big 所有, 如有侵权,请联系我们删除。