使用 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 相关文章推荐
基于jsTree的无限级树JSON数据的转换代码
Jul 27 Javascript
js控制表单奇偶行样式的简单方法
Jul 31 Javascript
浅谈JavaScript中的string拥有方法的原因
Aug 28 Javascript
JavaScript关于提高网站性能的几点建议(一)
Jul 24 Javascript
微信js-sdk上传与下载图片接口用法示例
Oct 12 Javascript
Vue.js教程之计算属性
Nov 11 Javascript
angular 组件通信的几种实现方式
Jul 13 Javascript
解决layui 复选框等内置控件不显示的问题
Aug 14 Javascript
Promise扫盲贴
Jun 24 Javascript
微信小程序点击滚动到指定位置的实现
May 22 Javascript
JS数组转字符串实现方法解析
Sep 04 Javascript
Vue项目中如何封装axios(统一管理http请求)
May 02 Vue.js
基于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/11/16 PHP
php调用mysql存储过程
2007/02/14 PHP
浅析php原型模式
2014/11/25 PHP
php实现Linux服务器木马排查及加固功能
2014/12/29 PHP
php实现兼容2038年后Unix时间戳转换函数
2015/03/18 PHP
CodeIgniter删除和设置Cookie的方法
2015/04/07 PHP
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法
2015/07/06 PHP
PHP mysqli事务操作常用方法分析
2017/07/22 PHP
JavaScript 版本自动生成文章摘要
2008/07/23 Javascript
javascript 自动填写表单的实现方法
2010/04/09 Javascript
转换字符串为json对象的方法详解
2013/11/29 Javascript
form表单序列化详解(推荐)
2017/08/15 Javascript
使用webpack-dev-server处理跨域请求的方法
2018/04/18 Javascript
layui table设置前台过滤转义等方法
2018/08/17 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
vue+element获取el-table某行的下标,根据下标操作数组对象方式
2020/08/07 Javascript
[05:13]TI4 中国战队 机场出征!!
2014/07/07 DOTA
python实现的系统实用log类实例
2015/06/30 Python
TensorFlow实现卷积神经网络
2018/05/24 Python
python生成n个元素的全组合方法
2018/11/13 Python
python利用Tesseract识别验证码的方法示例
2019/01/21 Python
python使用tomorrow实现多线程的例子
2019/07/20 Python
Python编程快速上手——PDF文件操作案例分析
2020/02/28 Python
python查询MySQL将数据写入Excel
2020/10/29 Python
纯css3制作的火影忍者写轮眼开眼至轮回眼及进化过程实例
2014/11/11 HTML / CSS
CSS3 input框的实现代码类似Google登录的动画效果
2020/08/04 HTML / CSS
HTML5画渐变背景图片并自动下载实现步骤
2013/11/18 HTML / CSS
详解canvas绘图时遇到的跨域问题
2018/03/22 HTML / CSS
给老师的检讨书
2014/02/11 职场文书
小学竞选班长演讲稿
2014/09/09 职场文书
庆祝三八妇女节标语
2014/10/09 职场文书
教师节校长致辞
2015/07/31 职场文书
暑假打工感想
2015/08/07 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书
Winsows11性能如何? win11性能测评多核竟比Win10差了10%
2021/11/21 数码科技
windows11选中自动复制怎么开启? Win11自动复制所选内容的方法
2022/07/23 数码科技