selenium实践,破解极验第三代滑动验证码,80%成功率

 
# coding=utf-8

from selenium import webdriver
import time
import random
from PIL import Image
from PIL import ImageChops
import operator
import cv2
from selenium.webdriver.common.action_chains import ActionChains
import os

'''
失败有三种原因: 
1. 没对准: 可调整滑动list 
2. 被验出是机器: 可把滑动分成多段,并调试中间的等待时间,模拟成真人
3. 图片没处理好,导致没对准: 优化图片对比函数 
目前发现拼图距离越远成功率越高,太近有概率被检测出为机器,推测原因可能是近的也花费时间太久,导致被发现 
'''


def get_url(url):
    driver.get(url)
    driver.maximize_window()
    user_input = driver.find_element_by_id('input1').send_keys('xxxx')
    password_input = driver.find_element_by_id('input2').send_keys('xxxx')
    signin_button = driver.find_element_by_id('signin').click()
    time.sleep(1)
    get_png()


def get_png():
    '''''获取没缺口的图片'''
    geetest_verify_tip = driver.find_element_by_class_name('geetest_radar_tip').click()
    cut_png('get_png.png')
    get_nick_png()  # 调函数截缺口图


def cut_png(name):
    '''''截图操作'''
    time.sleep(1)
    driver.save_screenshot(name)  # 截整个网页
    url_png = driver.find_elements_by_xpath('//div/canvas')[0]  # 获取图片元素
    left = url_png.location['x']
    top = url_png.location['y']
    elementWidth = url_png.location['x'] + url_png.size['width']
    elementHeight = url_png.location['y'] + url_png.size['height']
    picture = Image.open(name)
    picture = picture.crop((left, top, elementWidth, elementHeight - 26))  # 截图保存 26px是把多余文字去掉
    print(left, top, elementWidth, elementHeight - 26)
    picture.save(name)


def get_nick_png():
    '''''获取有缺口的图片'''
    geetest_slider_button = driver.find_element_by_class_name('geetest_slider_button').click()
    cut_png('get_nick_png.png')
    compare_images()


def compare_images(png1='get_png.png', png2='get_nick_png.png', png3='zzz.png'):
    '''''对比图片,比较不同点,生成新图片'''
    image_one = Image.open(png1)
    image_two = Image.open(png2)
    diff = ImageChops.difference(image_one, image_two)
    # diff = ImageChops.invert(diff)      #反转颜色
    diff.save(png3)
    png_red()


def png_red(png_name='zzz.png'):
    '''''描红'''
    img = cv2.imread(png_name)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(gray, 60, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    cv2.drawContours(img, contours, -1, (0, 0, 255), 2)
    # cv2.imshow("img", img)          # 展示
    cv2.imwrite('img.png', img)  # 保存
    Clipping_loop('img.png')


def Clipping_loop(png_name):
    '''''得到需要滑动的距离'''
    picture = Image.open(png_name)
    width = picture.size[0]
    height = picture.size[1]
    width_list = [w for w in range(width)]
    heigth_list = [h for h in range(height)]

    for w in width_list[::-1]:
        for h in heigth_list[::-1]:
            pixel = picture.getpixel((w, h))
            if tuple(pixel) == (255, 0, 0):  # 得到从右边数第一个像素点
                print(w - 47, w)  # 1.需要滑动的距离  2.算出的实际距离
                distance = w - 47  # 得出需要滑动的距离
                get_distance(distance)
                return distance


def get_distance(distance):
    '''''算每次滑动多少'''
    num = 0
    distance += 19
    v = 0
    t = 0.2
    mid = distance * 7 / 8
    num_list = []
    while num < distance:
        if num < mid:
            a = 2
        else:
            a = -3

        s = v * t + 0.5 * a * (t ** 2)
        v = v + a * t
        num += s
        num_list.append(round(s))

    back_tracks = [-3, -3, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -0.5]
    tracks = {'num_list': num_list, 'back_tracks': back_tracks}
    print(tracks)
    run(tracks)


def run(tracks):
    '''''滑动'''
    '''''难点就在滑动上,策略是把滑动分为n段进行,模拟真人,现在拼图越远成功率越高'''
    dragger = driver.find_element_by_class_name('geetest_slider_button')  # 定位
    action = ActionChains(driver)
    action.click_and_hold(dragger).perform()  # 按住不松
    time.sleep(random.random())

    time.sleep(0.5)
    for num in tracks['num_list'][0:35]:  # 右滑
        action.move_by_offset(xoffset=num, yoffset=0)
        print(num)
    action.perform()  # 执行滑动
    time.sleep(0.005)

    dragger = driver.find_element_by_class_name('geetest_slider_button')  # 再次定位按钮
    action = ActionChains(driver)
    action.click_and_hold(dragger).perform()
    for num in tracks['num_list'][35:40]:  # 右滑
        action.move_by_offset(xoffset=num, yoffset=0)
        print(num)
    action.perform()  # 执行滑动
    time.sleep(0.004)

    dragger = driver.find_element_by_class_name('geetest_slider_button')  # 再次定位按钮
    action = ActionChains(driver)
    action.click_and_hold(dragger).perform()
    for num in tracks['num_list'][40:]:  # 右滑
        action.move_by_offset(xoffset=num, yoffset=0)
        print(num)
    action.perform()  # 执行滑动
    time.sleep(0.007)

    dragger = driver.find_element_by_class_name('geetest_slider_button')  # 再次定位按钮
    action = ActionChains(driver)
    action.click_and_hold(dragger).perform()  # 按住
    for back_track in tracks['back_tracks'][0:10]:  # 左滑
        action.move_by_offset(xoffset=back_track, yoffset=0)
        print(back_track)
    action.perform()  # 执行滑动
    time.sleep(0.04)

    dragger = driver.find_element_by_class_name('geetest_slider_button')  # 再次定位按钮
    action = ActionChains(driver)
    action.click_and_hold(dragger).perform()  # 按住
    for back_track in tracks['back_tracks'][10:]:  # 左滑
        action.move_by_offset(xoffset=back_track, yoffset=0)
        print(back_track)

    action.release().perform()  # 松开鼠标 执行滑动

    time.sleep(2)
    driver.quit()


if __name__ == '__main__':
    driver = webdriver.Chrome('F:\Google\Chrome\Application\chromedriver.exe')
    get_url('https://passport.cnblogs.com/user/signin')

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值