前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python + selenium 爬虫模拟登录破解无原图滑动验证码

python + selenium 爬虫模拟登录破解无原图滑动验证码

作者头像
forxtz
发布2020-10-10 17:19:28
2.1K0
发布2020-10-10 17:19:28
举报
文章被收录于专栏:源懒由码源懒由码

爬虫模拟登录破解无原图滑动验证码: https://cloud.tencent.com/developer/article/1711623

需求:部分网站在频繁的使用之后,会弹出滑块验证码(极验)。有别于过去,现在的原图并不会出现,因此较过去的思路转变为以下:

1、截取带缺口的图片;

2、寻找原图,并截图;

3、比较两张图片,寻找到缺口位置距离;

4、计算运动过程,并驱动浏览器移动滑块。

参考链接基本提供了1-3步的实现,第4步存在被识别为机器操作,需要进行更新(修正以后,目前成功率应该有50%以上),记录如下。

一、启动浏览器,配置option,以防被识别为自动化。

代码语言:javascript
复制
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver import ActionChains
from PIL import Image
import numpy as np
import pandas as pd
import time

# 配置浏览器
options = webdriver.ChromeOptions()
# 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
options.add_experimental_option('excludeSwitches', ['enable-automation']) 

二、获取两张图片进行比较,通过网页分析发现。该标签,当display=block,opacity=1时,显示的为原图。

代码语言:javascript
复制
# 获取第一个图
img_name1 = r'../data/png/captcha2.png'
img_name2 = r'../data/png/captcha2_src.png'
img = wait.until(EC.presence_of_element_located((By.XPATH,'//canvas[@class="geetest_canvas_slice geetest_absolute"]')))
img.screenshot(img_name1)

# 获取原图
browser.execute_script("var x=document.getElementsByClassName('geetest_canvas_fullbg geetest_fade geetest_absolute')[0];"
                          "x.style.display='block';"
                          "x.style.opacity=1"
                          )
img = wait.until(EC.presence_of_element_located((By.XPATH,'//canvas[@class="geetest_canvas_slice geetest_absolute"]')))
img.screenshot(img_name2)
# 变回来
browser.execute_script("var x=document.getElementsByClassName('geetest_canvas_fullbg geetest_fade geetest_absolute')[0];"
                          "x.style.display='none';"
                          "x.style.opacity=0"
                          )

三、计算两张图片差异,通过rgb一定的缺值进行判断缺口。

代码语言:javascript
复制
# 如何能找到滑块的位置
def get_distance(img1,img2):
    start_x=60#初始X
    threhold=60#阈值
    for x in range(start_x,img1.size[0]):
        for y in range(img1.size[1]):
            rgb1=img1.load()[x,y]
            rgb2=img2.load()[x,y]
            res1=abs(rgb1[0]-rgb2[0])
            res2=abs(rgb1[1]-rgb2[1])
            res3=abs(rgb1[2]-rgb2[2])
            if not (res1<threhold and res2<threhold and res3<threhold):
                return x-7#测试后-7可以提高成功率

四、计算模拟移动,根据自身的挪动特点,我一般的移动操作分为三个阶段(可根据自身特点进行设计)。

1:点击滑块以后,缓慢移动一下。约移动3次。

2:快速移动到缺口附件。大概0.3s。

3:到了缺口附近以后,缓慢靠近,然后在缺口处停留大概0.5秒以后释放。

代码语言:javascript
复制
# 将整个过程分为3段,总时长大概是1.2-1.6秒
# 第一段是启动阶段,第一次点击的时候,总会比较拘谨,慢速启动,大概消费t2(0.3)秒,s2为分段数
# 第二段则是很快到达缺口附近,大概剩余d3(5)距离处
# 第三段是缓慢对接,最后停在上面0.5秒
def get_tracks(distance,s1 = 2,t2 = 0.3,s2 = 3,d3 = 5):
    # 计算d1移动过程
    dtemp = 0
    track1 = []
    for i in range(s1):
        t = np.random.randint(low = 1, high=3)
        track1.append(t)
        dtemp = dtemp + t
    
    # 计算d2距离
    distance =distance - dtemp - d3
    
    track2 = []
    a = 2 * distance /(t2 ** 2)
    dtemp = 0
    for i in range(s2):
        # 计算每段行走
        ttemp1 = t2/s2 * (i + 1)
        ttemp2 = t2/s2 * i
        t = int(0.5 * a * (ttemp1 ** 2) - 0.5 * a * (ttemp2 ** 2) )
        track2.append(t)
        dtemp = dtemp + t
        
    #由于取整了,可以存在一点误差,调整d3
    d3 = distance - dtemp + d3
    print(d3)
    track3 = []
    s = 0
    while s < d3:
        t = np.random.randint(low = 1, high=3)
        if s + t >= d3:
            track3.append(d3 - s)
            break
        else:
            s = s + t
            track3.append(t)    
    return {"track1": track1, 'track2': track2, 'track3': track3}
代码语言:javascript
复制
%%time
# 计算路径,不行,这个会被识别为计算机
#获得滑块元素
geetest_slider_button=browser.find_element_by_class_name('geetest_slider_button')
#获得距离
img1 = Image.open(img_name1)
img2 = Image.open(img_name2)
distance=get_distance(img1,img2)
#获得步数
tracks_dic=get_tracks(distance,s1 = 2,t2 = 0.2,s2 = 3,d3 = 5)
#点击并按住    ActionChains(driver).click_and_hold(geetest_slider_button).perform()
track1=tracks_dic['track1']
track2=tracks_dic['track2']
track3=tracks_dic['track3']

最后,遍历执行动作链。

代码语言:javascript
复制
%%time
# 执行
ActionChains(browser).click_and_hold(geetest_slider_button).perform()
# 执行第一步
for t in track1:
    ActionChains(browser).move_by_offset(xoffset=t,yoffset=0).perform()
#停顿一会,更像人
time.sleep(0.2)
for t in track2:
    ActionChains(browser).move_by_offset(xoffset=t,yoffset=0).perform()
for t in track3:
    ActionChains(browser).move_by_offset(xoffset=t,yoffset=0).perform()
time.sleep(0.5)
# 松开
ActionChains(browser).release(geetest_slider_button).perform()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档