使用 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 相关文章推荐
面向对象的javascript(笔记)
Oct 06 Javascript
JavaScript学习笔记(十七)js 优化
Feb 04 Javascript
判断目标是否是window,document,和拥有tagName的Element的代码
May 31 Javascript
jquery 扑捉回车键事件代码
Apr 24 Javascript
JavaScript基础知识学习笔记
Dec 02 Javascript
JavaScript判断FileUpload控件上传文件类型
Sep 28 Javascript
实例详解jQuery Mockjax 插件模拟 Ajax 请求
Jan 12 Javascript
使用JavaScript实现点击循环切换图片效果
Sep 03 Javascript
详解vue.js数据传递以及数据分发slot
Jan 20 Javascript
vue2 设置router-view默认路径的实例
Sep 20 Javascript
详解小程序不同页面之间通讯的解决方案
Nov 23 Javascript
JS立即执行函数功能与用法分析
Jan 15 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
php基础知识:类与对象(1)
2006/12/13 PHP
php中截取中文字符串的代码小结
2011/07/17 PHP
php 使用GD库为页面增加水印示例代码
2014/03/24 PHP
实例分析PHP将字符串转换成数字的方法
2019/01/27 PHP
PDO::rollBack讲解
2019/01/29 PHP
Laravel5.1 框架控制器基础用法实例分析
2020/01/04 PHP
javascript 硬盘序列号+其它硬件信息
2008/12/23 Javascript
js输出列表实现代码
2010/09/12 Javascript
Jquery实现自定义tooltip示例代码
2014/02/12 Javascript
jQuery实现的手机发送验证码倒计时效果代码分享
2015/08/24 Javascript
Bootstrap每天必学之工具提示(Tooltip)插件
2016/04/26 Javascript
node.js实现快速截图
2016/08/27 Javascript
利用js获取下拉框中所选的值
2016/12/01 Javascript
使用DeviceOne实现微信小程序功能
2016/12/29 Javascript
JavaScript实现图像模糊化的方法实例
2017/01/15 Javascript
jQuery实现点击下拉框中的值累加到文本框中的方法示例
2017/10/28 jQuery
在create-react-app中使用css modules的示例代码
2018/07/31 Javascript
使用vue.js在页面内组件监听scroll事件的方法
2018/09/11 Javascript
详解关于Vue版本不匹配问题(Vue packages version mismatch)
2018/09/17 Javascript
Node+OCR实现图像文字识别功能
2018/11/26 Javascript
Vue自定义属性实例分析
2019/02/23 Javascript
OpenLayers3实现测量功能
2020/09/25 Javascript
[52:22]EG vs VG Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
numpy.where() 用法详解
2019/05/27 Python
TensorBoard 计算图的可视化实现
2020/02/15 Python
基于FME使用Python过程图解
2020/05/13 Python
Python 实现国产SM3加密算法的示例代码
2020/09/21 Python
python爬虫快速响应服务器的做法
2020/11/24 Python
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
html5实现微信打飞机游戏
2014/03/27 HTML / CSS
美国现代家具和家居商店:Apt2B
2016/08/29 全球购物
关于Java finally的面试题
2016/04/27 面试题
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
任命书模板
2014/06/04 职场文书
2014幼儿园小班工作总结
2014/11/10 职场文书
2015年度环卫处工作总结
2015/07/24 职场文书