京东的滑动验证码在页面上是没有原图的,所有我是用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

收藏 打印