selenium的滑块验证码的模拟登录(猪八戒网站二:对于上个博客的优化)

那么就直接上代码

import time
from PIL import Image
import random
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# from py import password
from shu import *        #导入自己的账号密码包
# 三个canvas标签分别对应了缺口图,滑块图和完整图
def canvas():
    time.sleep(3)
    # 1.让滑块隐藏,截取缺口图;
    slice_js = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display="none"'
    driver.execute_script(slice_js)
    slice_path = r'./slice.png'
    driver.find_element(By.CLASS_NAME,"geetest_canvas_bg").screenshot(slice_path)
    # # 2.隐藏缺口图,显示滑块图,截取滑块图;
    slice_js1 = 'document.getElementsByClassName("geetest_canvas_slice")[0].style.display=""'
    bg_js='document.getElementsByClassName("geetest_canvas_bg")[0].style.display="none"'
    driver.execute_script(bg_js+';'+slice_js1)
    bg_path=r'./bg.png'
    driver.find_element(By.CLASS_NAME,'geetest_canvas_slice').screenshot(bg_path)
    # #3.截取完整图
    fullbg_js = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display="block"'
    driver.execute_script(fullbg_js)
    fullbg_path=r'./fullbg.png'
    driver.find_element(By.CLASS_NAME,'geetest_canvas_fullbg').screenshot(fullbg_path)
    # 4.显示完整图
    bg_js1 = 'document.getElementsByClassName("geetest_canvas_bg")[0].style.display=""'
    fullbg_js1 = 'document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display=""'
    driver.execute_script(bg_js1+';'+fullbg_js1)
    return bg_path,slice_path,fullbg_path
# 计算距离
def get_x(bg_path):
    #计算滑块图左边缘的距离
    bgimg=Image.open(bg_path)
    x,y=bgimg.size
    for i in range(x):
        for j in range(y):
            # 彩色图片每个点是一个元祖,
            bg=bgimg.getpixel((i,j))
            #将彩色图片的像素点相加,返回一个小于250的坐标
            if bg[0]+bg[1]+bg[2] <250:
                return (i,j),bg
def get_X(slice_path,fullbg_path):
    #获取缺口左边缘的X坐标
       slimg=Image.open(slice_path)
       fulimg=Image.open(fullbg_path)
       x,y=slimg.size
       for w in range(x):
           for h in range(y):
               # 彩色图片每个点是一个元祖
               sl_img=slimg.getpixel((w,h))
               ful_img=fulimg.getpixel((w,h))
               #将完整图和滑块图作比较
               r=ful_img[0]-sl_img[0]
               g=ful_img[1]-sl_img[1]
               b=ful_img[2]-sl_img[2]
               abs_value=abs(r)+abs(g)+abs(b)
               if abs_value >120:
                   return w,h
# 计算距离, 距离=滑块左边缘的X坐标-滑块右边缘的X坐标
def get_distance(bg_path,slice_path,fullbg_path):
    # 缺口图的距离
    get_X1=get_X(slice_path, fullbg_path)[0]
    # 计算距离
    # 滑块图的距离
    get_x1=get_x(bg_path)[0][0]
    dis=get_X1-get_x1
    return dis

#三.模拟人工移动
def get_track(distance):
    '''
    拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速
    匀变速运动基本公式:
    ①v=v0+at
    ②s=v0t+(1/2)at²
    ③v²-v0²=2as
    :param distance: 需要移动的距离
    :return: 存放每0.2秒移动的距离
    '''
    # 初速度
    v = 0
    # 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移
    t = 0.2
    # 位移/轨迹列表,列表内的一个元素代表0.2s的位移
    tracks = []
    # 当前的位移
    current = 0
    # 到达mid值开始减速
    mid = distance * 5 / 8
    distance += 10  # 先滑过一点,最后再反着滑动回来
    # a = random.randint(1,3)
    while current < distance:
        t=random.randint(1,4)/10
        if current < mid:
            # 加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细
            a = random.randint(1, 3)  # 加速运动
        else:
            a = -random.randint(2, 4)  # 减速运动
        # 初速度
        v0 = v
        # 0.2秒时间内的位移
        s = v0 * t + 0.5 * a * (t ** 2)
        # 当前的位置
        current += s
        # 添加到轨迹列表
        tracks.append(round(s))

        # 速度已经达到v,该速度作为下次的初速度
        v = v0 + a * t
    temp=10+round(current-distance)  #比原来正确的位置多了的像素
    # 反着滑动到大概准确位置
    for i in range(5):
        num=-random.randint(1, 3)
        tracks.append(num)
        temp+=num
    #位移补偿
    tracks.append(abs(temp)) if temp<0  else  tracks.append(-temp)
    # random.shuffle(tracks)
    print(tracks)
    return tracks
#seleium操作
def move(tracks):
    button=driver.find_element(By.CLASS_NAME,'geetest_slider_button')
    #显示等待
    # WebDriverWait(driver,timeout=10).until(EC.element_to_be_selected(button))
    ActionChains(driver).click_and_hold(button).perform()
    for x in tracks:
        ActionChains(driver).move_by_offset(xoffset=x,yoffset=0).perform()
    ActionChains(driver).release(button).perform()
    time.sleep(2)


driver=webdriver.Chrome()
driver.implicitly_wait(10)
driver.get('https://account.zbj.com/login?isFromIndex=1&fromurl=https%3A%2F%2Fweinan.zbj.com%2F')
# 窗口最大化
driver.maximize_window()
#点击
time.sleep(2)
driver.find_element(By.CSS_SELECTOR,'#utopia_widget_10 > ul > ol > a > span >img').click()

#输入账号
driver.find_element(By.ID,'username').send_keys(USER)
#输入密码
driver.find_element(By.ID,'password').send_keys(PASSWORD)
# 点击按钮进行验证
time.sleep(1)
driver.find_element(By.CLASS_NAME,"geetest_radar_tip").click()
content=driver.find_elements(By.CSS_SELECTOR,'#password-captcha-box > div.geetest_holder.geetest_wind.geetest_radar_success > div.geetest_btn > div.geetest_ghost_success.geetest_success_animate > div > div.geetest_success_radar_tip > span.geetest_success_radar_tip_content')
if content:
    if  '验证成功' in  content[0].text:
        driver.find_element(By.CSS_SELECTOR,'#login > div > div.zbj-form-item.login-form-button > button').click()
# 获取缺口图,滑块图和完整图
bg_path,slice_path,fullbg_path=canvas()
#dis=缺口图的距离-滑块图的距离
dis=get_distance(bg_path,slice_path,fullbg_path)
print(dis)
count=3
while count>0:
    #模拟人工操作
    tracks=get_track(dis)
    #seleium操作,按住滑动条,滑动并且松开鼠标
    move(tracks)
    bok=driver.find_element(By.XPATH,'//*[@id="password-captcha-box"]/div[2]/div[2]/div[2]/div/div[2]/span[1]').text
    if bok:
        print('校验成功',bok)
        driver.find_element(By.XPATH,'//*[@id="login"]/div/div[5]/button').click()
        # driver.find_element(By.CLASS_NAME,'j-uc-ad-force-qiwei-close').click()
        break
    else:
       count+=1
    bok_1=driver.find_element(By.CLASS_NAME,"geetest_reset_tip_content")
    bok_2=bok_1.text
    # 出现被怪兽吃掉  网络不给力
    if '请点击重试' in bok_2:
        bok_1.click()
        # 获取缺口图,滑块图和完整图
        bg_path, slice_path, fullbg_path = canvas()
        dis1 = get_distance(bg_path, slice_path, fullbg_path)
        tracks = get_track(dis1)
        print(dis1)
        move(tracks)



time.sleep(3)
# driver.close()

自己的密码包:xx.py

USER='xxxx'
PASSWORD='xxxx'

具体步骤看我上个博客。唉,路漫漫其修远兮,吾将上下而求索。

猜你喜欢

转载自blog.csdn.net/qq_62870237/article/details/124431146