如何使用puppeteer破解极验的滑动验证码
空床难独守 上传于 2020-07-08 00:03
在自动化测试与爬虫开发中,验证码是绕不开的屏障。极验滑动验证码作为国内主流的验证方案,其通过轨迹验证、环境检测等多层防护机制,有效阻挡了大规模自动化请求。本文将深入解析极验滑动验证码的技术原理,并结合Puppeteer框架,探讨如何在合法合规的前提下实现自动化验证流程。需要强调的是,本文内容仅供技术研究与安全防护参考,实际开发中需严格遵守目标网站的服务条款。
一、极验滑动验证码技术解析
极验第四代滑动验证码采用"行为链+环境指纹"双因子验证机制,其核心验证流程分为三个阶段:
- 前置检测:通过Canvas指纹、WebRTC IP、时区检测等18项环境指标构建设备画像
- 轨迹验证:采集鼠标移动轨迹的加速度、曲率、停顿点等200+维度特征
- 风险决策:基于机器学习模型实时计算风险评分,动态调整验证难度
典型验证流程如下:
1. 用户访问受保护页面
2. 前端加载验证SDK(v4.js)
3. 生成唯一sessionid并上报
4. 渲染滑块组件并绑定事件监听
5. 采集用户操作数据(每50ms上报一次)
6. 提交验证结果至决策引擎
7. 返回验证通过/失败状态
二、Puppeteer环境准备
安装必要依赖:
npm init -y
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
基础浏览器配置示例:
const puppeteer = require('puppeteer-extra')
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin())
async function launchBrowser() {
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--window-size=1920,1080',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...'
]
})
return browser
}
三、验证码页面定位策略
极验验证码通常通过以下方式加载:
- 动态创建iframe(id可能为"geetest_iframe")
- 注入全局变量
window.Geetest
- 触发
gt.show()
方法显示组件
定位验证码容器的推荐方式:
async function locateCaptchaFrame(page) {
// 方案1:等待iframe出现
await page.waitForSelector('iframe[src*="geetest"]', { timeout: 5000 })
const frames = page.frames()
const captchaFrame = frames.find(f =>
f.url().includes('api.geetest.com')
)
// 方案2:直接调用全局方法(需等待JS执行)
await page.evaluate(() => {
return new Promise(resolve => {
const checkInterval = setInterval(() => {
if (window.Geetest && window.Geetest.show) {
clearInterval(checkInterval)
resolve(true)
}
}, 200)
})
})
return captchaFrame || page
}
四、轨迹模拟算法实现
真实用户滑动轨迹具有以下特征:
- 起始阶段加速(0.2-0.5s)
- 中间阶段匀速(1-2s)
- 结束阶段减速(0.3-0.8s)
- 存在微小抖动(±2px随机偏移)
贝塞尔曲线轨迹生成算法:
function generateTrajectory(startX, endX, duration = 1500) {
const points = []
const controlX = startX + (endX - startX) * 0.3
const steps = Math.floor(duration / 16) // 约60fps
for (let i = 0; i
五、完整验证流程实现
整合各模块的完整解决方案:
async function solveGeetestCaptcha(page, url) {
// 1. 访问目标页面
await page.goto(url, { waitUntil: 'networkidle2' })
// 2. 定位验证码容器
const captchaFrame = await locateCaptchaFrame(page)
// 3. 触发验证码显示
await captchaFrame.evaluate(() => {
return new Promise(resolve => {
if (window.Geetest) {
window.Geetest.show()
resolve()
} else {
const btn = document.querySelector('.geetest_slider_button')
if (btn) btn.click()
setTimeout(resolve, 1000)
}
})
})
// 4. 获取滑块和背景元素
const sliderInfo = await captchaFrame.evaluate(() => {
const slider = document.querySelector('.geetest_slider_button')
const bg = document.querySelector('.geetest_canvas_bg')
const bgImage = bg ? bg.style.backgroundImage : ''
const gap = parseInt(bgImage.match(/gap=(\d+)/)?.[1] || 0)
return {
sliderRect: slider.getBoundingClientRect(),
gapX: gap
}
})
// 5. 生成模拟轨迹
const trajectory = generateTrajectory(
0,
sliderInfo.gapX,
1200 + Math.random() * 800
)
// 6. 执行滑动操作
await captchaFrame.mouse.move(
sliderInfo.sliderRect.x + 10,
sliderInfo.sliderRect.y + 10
)
await captchaFrame.mouse.down()
for (let i = 0; i 0) {
const prev = trajectory[i-1]
const delay = point.t - prev.t
await new Promise(resolve => setTimeout(resolve, delay))
}
await captchaFrame.mouse.move(
sliderInfo.sliderRect.x + 10 + point.x,
sliderInfo.sliderRect.y + 10
)
}
await captchaFrame.mouse.up()
// 7. 验证结果处理
await new Promise(resolve => setTimeout(resolve, 2000))
const result = await captchaFrame.evaluate(() => {
return document.querySelector('.geetest_success_radar_tip') ?
'success' : 'fail'
})
return result === 'success'
}
六、反检测增强策略
为应对极验的风控系统,需实施以下增强措施:
- Canvas指纹伪造:
- WebGL指纹混淆:
- 时区同步:
await page.evaluateOnNewDocument(() => {
const canvas = document.createElement('canvas')
CanvasRenderingContext2D.prototype.getImageData = function() {
return {
width: 100,
height: 100,
data: new Uint8ClampedArray(100*100*4).fill(128)
}
}
})
await page.evaluateOnNewDocument(() => {
const getParameter = WebGLRenderingContext.prototype.getParameter
WebGLRenderingContext.prototype.getParameter = function(p) {
if (p === 37445) return 'Intel Inc.' // UNMASKED_RENDERER_WEBGL
if (p === 37446) return 'Intel HD Graphics 620' // UNMASKED_VENDOR_WEBGL
return getParameter(p)
}
})
const timezone = 'Asia/Shanghai'
await page.evaluateOnNewDocument(() => {
Object.defineProperty(Intl, 'DateTimeFormat', {
configurable: true,
value: function(locale, options) {
return {
resolvedOptions() {
return { timeZone: 'Asia/Shanghai' }
}
}
}
})
})
七、法律与伦理考量
在实施自动化验证前,必须考虑以下法律风险:
- 违反《网络安全法》第46条:未经授权访问计算机系统
- 触犯《刑法》第285条:非法侵入计算机信息系统罪
- 违反目标网站《服务条款》的自动化访问限制
合规使用建议:
- 仅用于自身账号的合法自动化测试
- 控制请求频率(建议≤5次/分钟)
- 建立完善的异常处理机制
- 保留完整的操作日志
八、完整示例代码
const puppeteer = require('puppeteer-extra')
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin())
async function main() {
const browser = await puppeteer.launch({ headless: false })
const page = await browser.newPage()
// 增强反检测
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64)...')
await page.setViewport({ width: 1920, height: 1080 })
// 伪造Canvas指纹
await page.evaluateOnNewDocument(() => {
const getImageData = CanvasRenderingContext2D.prototype.getImageData
CanvasRenderingContext2D.prototype.getImageData = function() {
const arr = new Uint8ClampedArray(4)
arr[0] = Math.floor(Math.random() * 255)
arr[1] = Math.floor(Math.random() * 255)
arr[2] = Math.floor(Math.random() * 255)
arr[3] = 255
return { data: arr, width: 1, height: 1 }
}
})
const isSuccess = await solveGeetestCaptcha(page, 'https://example.com/login')
console.log('验证结果:', isSuccess ? '通过' : '失败')
await browser.close()
}
main().catch(console.error)
关键词
Puppeteer、极验验证码、滑动验证、轨迹模拟、反检测、浏览器自动化、Canvas指纹、WebGL混淆、合规使用、验证码破解
简介
本文详细解析了极验滑动验证码的技术原理与验证机制,结合Puppeteer框架提供了完整的自动化解决方案。内容涵盖验证码页面定位、轨迹生成算法、反检测增强策略等核心技术点,同时强调了法律合规与伦理考量,为开发者提供安全可靠的验证自动化实现参考。