利用selenium-打码平台-滑块验证码
2023-4-15 16:12:9 Author: mp.weixin.qq.com(查看原文) 阅读量:14 收藏

前言

太久没学习了,刚好最近有点想法,打码平台提供Python的SDK,不提供GO的,加上好久没写代码了,就用Python来恢复一下手感,顺便整理一下历史笔记,记录一下过程吧。

环境准备

  • Python3
  • Selenium:(pip3 install selenium)
  • Chromedriver:最好选择和当前电脑中版本一致或相差不大的

基础测试代码

import timefrom selenium import webdriver
driver = webdriver.Chrome(executable_path="./chromedriver")driver.get('https://www.baidu.com/')time.sleep(5)driver.quit()

如果能打开百度,就说明一切正常。基础用法可参考:【2022 年】Python3 爬虫教程 - 经典动态渲染工具 Selenium 的使用

如果要使用Xpath去定位组件,可以用 chrome 应用商店提供的 Xpath Helper,用法如下

image-20221009142517050

反爬绕过+拖动代码测试

各种高级点的验证码都需要点击或者拖动的,这里用滑块验证码举例,代码为拖动组件的代码。

import timefrom selenium import webdriverfrom selenium.webdriver import ActionChainsfrom selenium.webdriver.chrome.options import Options
chrome_options = Options()# chrome_options.add_argument('--headless') # 无界面模式chrome_options.add_argument('--window-size=1920,1080') # 设置框大小,避免无头模式识别不出按钮chrome_options.add_argument('--disable-gpu') # 禁用显卡chrome_options.add_argument('--incognito') # 隐私模式chrome_options.add_argument("--user-agent={}".format("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.11")) # 替换UAchrome_options.add_argument("--disable-blink-features=AutomationControlled") # 从 Chrome 88 开始,它的 V8 引擎升级了,加了这个参数,window.navigator.webdriver=false
# 不显示上方的 Chrome正在受到自动化测试软件的控制chrome_options.add_experimental_option('useAutomationExtension', False)chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
driver = webdriver.Chrome(executable_path="./chromedriver", options=chrome_options)driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')driver.switch_to.frame("iframeResult")
source = driver.find_element_by_id("draggable")target = driver.find_element_by_id("droppable")actions = ActionChains(driver)# 从1个组件拖动到另一个组件actions.drag_and_drop(source, target)# 根据像素拖动# actions.drag_and_drop_by_offset(source, 250, 0)actions.perform()
time.sleep(30)driver.quit()

实战京东验证码(失败)

京东在注册处 https://reg.jd.com/reg/person?ReturnUrl=https%3A//www.jd.com/ 存在滑动验证码

image-20221009153837663

直接用上方的代码,肯定是不行的,因为上方代码直接拖动一步到位,没有过程,一下就被识别出来是机器人了。于是尝试一点点的拖,稍微改良版如下:

ActionChains(wd).click_and_hold(source).perform()for i in range(10):    ActionChains(wd).move_by_offset(offset/10, 0).perform()ActionChains(wd).pause(0.5).release().perform()

效果如下:

2022-10-09 15.43.33

分析下失败原因,滑动验证码,大多数验证了鼠标轨迹,像上面那样就是如下的轨迹,明显机器人。(图自:https://www.rossidata.com/PythonAnimations)

dots

实战京东验证码(成功)

后查阅资料,认识了一个新的名词 缓动函数,介绍如下:

缓动函数:自定义参数随时间变化的速率。现实生活中,物体并不是突然启动或者停止,当然也不可能一直保持匀速移动。就像我们打开抽屉的过程那样,刚开始拉的那一下动作很快,但是当抽屉被拉出来之后我们会不自觉的放慢动作。或是掉落在地板上的物体,一开始下降的速度很快,接着就会在地板上来回反弹直到停止。

参考代码:https://github.com/gdsmith/jquery.easing/blob/master/jquery.easing.js

缓动函数速查表:https://easings.net/zh-cn#

再抄点大佬代码中的get_tracks()函数,举例如下:其中返回的tracks列表就是每一次移动的位移长度。

import numpy as np

def ease_out_quad(x): return 1 - (1 - x) * (1 - x)

def ease_out_quart(x): return 1 - pow(1 - x, 4)

def ease_out_expo(x): if x == 1: return 1 else: return 1 - pow(2, -10 * x)

def ease_out_bounce(x): n1 = 7.5625 d1 = 2.75 if x < 1 / d1: return n1 * x * x elif x < 2 / d1: x -= 1.5 / d1 return n1 * x * x + 0.75 elif x < 2.5 / d1: x -= 2.25 / d1 return n1 * x * x + 0.9375 else: x -= 2.625 / d1 return n1 * x * x + 0.984375

def ease_in_out_bounce(x): return ( 1 - ease_out_bounce( 1 - 2 * x ) ) / 2 if x < 0.5 else ( 1 + ease_out_bounce( 2 * x - 1 ) ) / 2

def get_tracks(distance, seconds, ease_func): """ 可以根据滑块的偏移,需要的时间(相对时间,并不是准确时间),以及要采用的缓动函数生成拖动轨迹。 :param distance: 位移距离 :param seconds: 时间秒 :par am ease_func: 调用的缓慢函数 :return: """ tracks = [0] offsets = [0] for t in np.arange(0.0, seconds, 0.1): ease = globals()[ease_func] offset = round(ease(t / seconds) * distance) tracks.append(offset - offsets[-1]) offsets.append(offset) return offsets, tracks

a = get_tracks(100, 5, 'ease_in_out_bounce')print(sum(a[1]))print(a)
image-20221009163735024

使用 ease_out_bounce 结果如下:

# 生成轨迹_, tracks = test.get_tracks(offset, 1, 'ease_out_bounce')# 缓慢拖动ActionChains(wd).click_and_hold(source).perform()for t in tracks:    ActionChains(wd).move_by_offset(t, 0).perform()ActionChains(wd).pause(0.2).release().perform()
2022-10-09 16.51.29

对接打码平台坑点

使用平台:http://www.ttshitu.com

推荐码:478f4497b898415993e7dc9a3c4b7df8

前期,我直接用chromedriver截屏验证码图片,然后调用接口分析位移,但是一直不成功,验证码整体如下

129

该图片我本地用截图工具分析出需要水平位移的像素是129,实际传入程序使用起来也真是129

image-20221010214812324

但是在多个打码平台测试后,发现识别出来都是272左右,人麻了

image-20221010214920807

研究了一天,发现是因为自己电脑分辨率太高了

截图的大小用exiftool看应该是768x558,而我电脑用截图来看图片尺寸是383x276(接近2:1的关系),但打码平台分析图片是按照exiftool的大小结果来分析的,所以对应识别出来的位移也会大一些(差不多2倍的关系)

image-20221010215508220

解决办法也比较简单,就是给识别出来的位移距离除以2,再手动适当调整就可以了;大体代码如下:

	# 截图整个屏幕    wd.get_screenshot_as_file("1.png")    # 切割验证码    img = Image.open('1.png')    region = img.crop((700 * 2, 180 * 2, 1080 * 2, 350 * 2))  ## 左上角坐标和右下角坐标    region.save('2.png')  ## 将裁剪下来的图片保存到 举例.png
# 调用第三方平台,来获取水平位移(存在一定误差,手动调整) offset = base64_api('2.png', 33) offset = int(offset) / 2 - 10 print("识别出来需要水平位移", offset)

演示如下:

技巧

判断某个标签是否加载

一般点了验证码不会马上出来,会有一点点延迟,结合判断的代码,可以避免代码运行出现异常

from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as EC    WebDriverWait(wd, 5).until(EC.presence_of_element_located((By.NAME, "select-all")))  # 等待加载WebDriverWait(wd, 5).until(EC.presence_of_element_located((By.XPATH,"/html[@class='root61']/body/div[@class='container w']/div[@class='main ']/div[@class='reg-form']/form[@id='register-form']/div[@id='step1-wrap']/div[@class='item-getcode-wrap']/div[@class='form-item form-item-getcode']/div[@class='slide-authCode-wraper']/div[@id='slideAuthCode']/div[@class='JDJRV-slide ']/div[@class='JDJRV-slide-bg ']/div[@class='JDJRV-slide-inner JDJRV-slide-btn']")))

参考

使用 Python + Selenium 破解滑块验证码

关 注 有 礼

关注本公众号回复“718619
可以免费领取全套网络安全学习教程,安全靶场、面试指南、安全沙龙PPT、代码安全、火眼安全系统等

 还在等什么?赶紧点击下方名片关注学习吧!


文章来源: https://mp.weixin.qq.com/s?__biz=MzkwMTE4NDM5NA==&mid=2247486277&idx=3&sn=cc0439ab66e3a190d247713c112f4ed1&chksm=c0b9e5a0f7ce6cb6300a9f50b880dc01d43a62b04493bafcf4f65196123e801d1b5d3303a69f&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh