京东的滑动验证码在页面上是没有原图的,所有我是用ps把他们拼成一个的。
from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from PIL import Image import time import random def if_is_s(img_1, img_2):#判断是不是跟比较的是一张图 a = 0 for i in range(1, img_1.size[1]): for j in range(1, 3): rgb1 = img_1.load()[i, j] rgb2 = img_2.load()[i, j] res1 = abs(rgb1[0] - rgb2[0]) res2 = abs(rgb1[1] - rgb2[1]) res3 = abs(rgb1[2] - rgb2[2]) if res1 < 10 and res2 < 10 and res3 < 10: a += 1 else: a = 0 if a > 50: return True return False def get_distance(image1,image2):#找出需要滑动的距离 a = 0 threshold=60 left=57 for i in range(left,image1.size[0]): for j in range(image1.size[1]): rgb1=image1.load()[i,j] rgb2=image2.load()[i,j] res1=abs(rgb1[0]-rgb2[0]) res2=abs(rgb1[1]-rgb2[1]) res3=abs(rgb1[2]-rgb2[2]) if not (res1 < threshold and res2 < threshold and res3 < threshold): a += 1 return i+20 return i+20 def get_tracks(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 ** 2) 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)) if sum(tracks) > distance: i = sum(tracks) - distance tracks[-1] = round(tracks[-1] - i, 2) i = random.uniform(1, 3 ) i = round(i, 2) zz = random.uniform(0.1, 0.3) tracks[-1] = round(tracks[-1] + i, 2) i = round(i - zz, 2) tracks.append(-i) if sum(tracks) < distance: si = distance - sum(tracks) tracks.append(round(si, 2)) print(tracks, sum(tracks)) return tracks if __name__==\'__main__\': browser = webdriver.Firefox() browser.get(\'https://passport.jd.com/new/login\') butt = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.CLASS_NAME,\' -login\'))) butt.click() butt = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.XPATH,\'//a[@clstag=\"pageclick|keycount|login_pc_201804112|10\"]\'))) butt.click() user = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,\'loginname\'))) password = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID,\'nloginpwd\'))) user.send_keys(\'xxx\') time.sleep(2) password.send_keys(\'xxx\') izsz = 1 while izsz == 1:#无限循环直到登录成功 try: button = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.CLASS_NAME,\'btn-img.btn-entry\'))) time.sleep(2) button.click() time.sleep(2) browser.save_screenshot(\'1.png\')#截图 page_snap_obj = Image.open(\'1.png\') img = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.CLASS_NAME,\'JDJRV-bigimg\'))) local = img.location size = img.size top = local[\'y\'] bottom = local[\'y\'] + size[\'height\'] left = local[\'x\'] right = local[\'x\'] + size[\'width\'] img_1 = Image.open(\'index2.png\') img_2 = page_snap_obj.crop((left, top, right, bottom))#裁剪图片尺寸 img_2.save(\'2.png\')#保存 i = if_is_s(img_1,img_2)#判断是不是一张图,不是点击换一张 while not i: time.sleep(2) butt = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.CLASS_NAME,\'JDJRV-img-refresh\'))) butt.click() time.sleep(2) browser.save_screenshot(\'1.png\') page_snap_obj = Image.open(\'1.png\') img = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.CLASS_NAME, \'JDJRV-bigimg\'))) local = img.location size = img.size top = local[\'y\'] bottom = local[\'y\'] + size[\'height\'] left = local[\'x\'] right = local[\'x\'] + size[\'width\'] img_1 = Image.open(\'index2.png\') img_2 = page_snap_obj.crop((left, top, right, bottom)) img_2.save(\'2.png\') time.sleep(2) i = if_is_s(img_1, img_2) ji = get_distance(img_1, img_2) print(ji) tracks = get_tracks(ji) ijs = len(tracks)//5*3 tracks1 = tracks[:ijs]#对滑动轨迹继续改变 tracks2 = tracks[ijs:] z = sum(tracks1) tracks2.insert(0,z) tracks2.insert(0,0) button = WebDriverWait(browser,10).until(EC.presence_of_element_located((By.XPATH, \'//div[@class=\"JDJRV-slide-inner JDJRV-slide-btn\"]\'))) ActionChains(browser).click_and_hold(button).perform() for track in tracks: ActionChains(browser).move_by_offset(xoffset=track, yoffset=0).perform() time.sleep(0.5) # 0.5秒后释放鼠标 ActionChains(browser).release().perform() url = browser.current_url if \'https://passport.jd.com/new/login.aspx?\' in str(url): izsz = 1 else: izsz = 0 except: izsz = 1
难点就在滑动的轨迹太容易被抓,而且一种用多了也会被识别。
git https://github.com/18370652038/jd.git
继续阅读与本文标签相同的文章
上一篇 :
Vue.js常见问题精选(一)
-
《21天学通C语言(第5版)》| 每日读本书
2026-05-19栏目: 教程
-
Linux rsyslog 简记
2026-05-19栏目: 教程
-
Oracle 左连接(left join) 排序问题
2026-05-19栏目: 教程
-
Java同步:synchronized解析
2026-05-19栏目: 教程
-
Oracle查询结果集无法被redis缓存序列化问题
2026-05-19栏目: 教程
