使用 Node.js 模拟滑动拼图验证码操作的示例代码


Posted in Javascript onNovember 02, 2017

近几年,网页上各种新型验证码层出不穷,其中一种比较常见的是滑动验证码,比如下图这种。

使用 Node.js 模拟滑动拼图验证码操作的示例代码

本文介绍了一种使用纯前端方法寻找滑动终点并模拟滑动的方法。

我们需要三个依赖库: puppeteer 、 Resemble.js 以及canvas 。其中 puppeteer 用于打开并操作页面, Resemble.jscanvas 用于寻找滑动验证码的终点位置。相关依赖如下:

"dependencies": {
 "canvas": "^1.6.7",
 "puppeteer": "^0.12.0",
 "resemblejs": "^2.2.6"
}

接下来是实现要点。首先,引入所需的库,定义一些常量。

const fs = require('fs')
const puppeteer = require('puppeteer')
const resemble = require('resemblejs')
const Canvas = require('canvas')

const URL = 'xxx' // 验证码页面访问地址
const width = 600
const height = 400
const slider_width = 44

const sleep = duration => {
 return new Promise(resolve => {
 setTimeout(resolve, duration)
 })
}

接下来,使用 puppeteer 打开验证码页面:

const browser = await puppeteer.launch()
const page = await browser.newPage()
page.setViewport({width, height})

await page.goto(URL, {
 waitUntil: 'networkidle'
})

然后往页面上注入一段 JS ,获取验证码滑块的位置。这一段代码可能需要你根据自己页面的实际情况进行调整。

const offset = await page.evaluate(() => {
 let offset_ifr = $('iframe').offset()

 return {
 top: offset_ifr.top + 222,
 left: offset_ifr.left + 10
 }
})

接下来,模拟按下鼠标左键,再放开,并分别截图。

await page.mouse.move(offset.left + 10, offset.top + 10)
// 按下鼠标
await page.mouse.down({
 button: 'left'
})
// 等待图片出现
await sleep(500)
// 截图
await page.screenshot({path: 'screenshot2.png'})

await page.mouse.up({
 button: 'left'
})
// 等待图片出现
await sleep(500)
// 截图
await page.screenshot({path: 'screenshot3.png'})

此时可以得到两个图片:

使用 Node.js 模拟滑动拼图验证码操作的示例代码

以及:

使用 Node.js 模拟滑动拼图验证码操作的示例代码

可以看到,两个图其余部分都相同,区别在于是否显示验证码滑块以及目标位置。

接下来,就轮到 Resemble.js 出场了,可以使用它获得两个图片的 diff 结果。

await new Promise(resolve => {
 resemble.outputSettings({
 transparency: 0
 })
 resemble('screenshot2.png')
 .compareTo('screenshot3.png')
 .ignoreColors()
 .onComplete(data => {
  fs.writeFileSync('diff.png', data.getBuffer())
  resolve()
 })
})

结果如下:

使用 Node.js 模拟滑动拼图验证码操作的示例代码

接下来,再使用 canvas 库,将这个 diff 图片读入内存,从右上角开始查找,很容易即可找到最右侧色块的位置,也即滑块终点的位置。

const getDestinationX = min_x => {
 const canvas = new Canvas(width, height)
 const ctx = canvas.getContext('2d')
 const buf = fs.readFileSync('diff.png')
 const img = new Canvas.Image()
 img.src = buf
 ctx.drawImage(img, 0, 0, width, height)
 const img_data = ctx.getImageData(0, 0, width, height).data

 let destination_x = -1

 for (let y = 0; y < height; y++) {
 for (let x = width; x >= min_x; x--) {
  let p = width * y + x
  p = p << 2
  if (img_data[p + 3] === 255 && img_data[p - 10 * 4 + 3] === 255) {
  destination_x = x
  break
  }
 }
 if (destination_x > -1) break
 }

 return destination_x - slider_width
}

这样,便获得了滑块的起始位置以及终点位置,再使用 puppeteerpage.mouse.move 方法模拟拖动,将滑块拖到终点位置即可。

使用 Node.js 模拟滑动拼图验证码操作的示例代码

当然,找到滑块终点并把滑块拖到正确的终点位置只是第一步,完善的滑动验证码并不会只判断有没有滑到正确的位置,还会分析你的拖动轨迹。要知道,人滑动的轨迹和机器滑动的轨迹是有很大不同的,至于具体如何区分就是另一个复杂的话题了。

最后,本文仅供研究参考,不要问我要详细代码。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
Aug 15 Javascript
jQuery实现页面滚动时动态加载内容的方法
Mar 20 Javascript
jquery ui resize 中border-box的bug修正
Apr 26 Javascript
基于javascript实现简单计算器功能
Jan 03 Javascript
JavaScript数组方法总结分析
May 06 Javascript
EasyUI 中combotree 默认不能选择父节点的实现方法
Nov 07 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
Jul 11 Javascript
谈谈React中的Render Props模式
Dec 06 Javascript
vue spa应用中的路由缓存问题与解决方案
May 31 Javascript
js 计算月/周的第一天和最后一天代码
Feb 01 Javascript
js实现幻灯片轮播图
Aug 14 Javascript
JavaScript实现轮播图效果
Oct 30 Javascript
基于JavaScript+HTML5 实现打地鼠小游戏逻辑流程图文详解(附完整代码)
Nov 02 #Javascript
vue-resource + json-server模拟数据的方法
Nov 02 #Javascript
详解vue-cli项目中用json-sever搭建mock服务器
Nov 02 #Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
Nov 02 #Javascript
vue项目中使用axios上传图片等文件操作
Nov 02 #Javascript
JavaScript登录验证基础教程
Nov 01 #Javascript
vue打包后显示空白正确处理方法
Nov 01 #Javascript
You might like
桌面中心(三)修改数据库
2006/10/09 PHP
hadoop中一些常用的命令介绍
2013/06/19 PHP
解析coreseek for sphinx的使用
2013/06/21 PHP
php实现的中秋博饼游戏之绘制骰子图案功能示例
2017/11/06 PHP
PHP+ajax实现获取新闻数据简单示例
2018/05/08 PHP
javascript读取xml
2006/11/04 Javascript
jquery radio 操作代码
2011/03/16 Javascript
查看源码的工具 学习jQuery源码不错的工具
2011/12/26 Javascript
js+JQuery返回顶部功能如何实现
2012/12/03 Javascript
web网页按比例显示图片实现原理及js代码
2013/08/09 Javascript
JavaScript设计模式之工厂模式和构造器模式
2015/02/11 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
Ionic + Angular.js实现验证码倒计时功能的方法
2017/06/12 Javascript
Vue.js实现双向数据绑定方法(表单自动赋值、表单自动取值)
2018/08/27 Javascript
Vue创建头部组件示例代码详解
2018/10/23 Javascript
解决vue跨域axios异步通信问题
2019/04/17 Javascript
基于elementUI竖向表格、和并列的案例
2020/10/26 Javascript
python支持断点续传的多线程下载示例
2014/01/16 Python
python字符串连接方式汇总
2014/08/21 Python
python如何实现excel数据添加到mongodb
2015/07/30 Python
python开发环境PyScripter中文乱码问题解决方案
2016/09/11 Python
python实现简单中文词频统计示例
2017/11/08 Python
Django logging配置及使用详解
2019/07/23 Python
python 操作hive pyhs2方式
2019/12/21 Python
Python调用.NET库的方法步骤
2019/12/27 Python
在python image 中实现安装中文字体
2020/05/16 Python
Keras中的多分类损失函数用法categorical_crossentropy
2020/06/11 Python
移动端Html5页面生成图片解决方案
2018/08/07 HTML / CSS
Under Armour美国官网:美国知名高端功能性运动品牌
2016/09/05 全球购物
KIKO MILANO英国官网:意大利知名化妆品和护肤品品牌
2017/09/25 全球购物
黄色火烈鸟:De Gele Flamingo
2019/03/18 全球购物
化学教师自荐信范文
2013/12/28 职场文书
观看《永远的雷锋》心得体会
2014/03/12 职场文书
房展策划方案
2014/06/07 职场文书
普通党员自我剖析材料
2014/10/07 职场文书
canvas实现贪食蛇的实践
2022/02/15 Javascript