使用 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 相关文章推荐
读jQuery之二(两种扩展)
Jun 11 Javascript
javaScript 利用闭包模拟对象的私有属性
Dec 29 Javascript
利用javaScript实现点击输入框弹出窗体选择信息
Dec 11 Javascript
javascript实现确定和取消提示框效果
Jul 10 Javascript
JavaScript模拟push
Mar 06 Javascript
jQuery排序插件tableSorter使用方法
Feb 10 Javascript
JS验证全角与半角及相互转化的介绍
May 18 Javascript
使用webpack打包koa2 框架app
Feb 02 Javascript
React Native日期时间选择组件的示例代码
Apr 27 Javascript
JavaScript实现HSL拾色器
May 21 Javascript
js实现有趣的倒计时效果
Jan 19 Javascript
JS不要再到处使用绝对等于运算符了
Apr 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
Re:从零开始的异世界生活 第2季 开播啦
2020/07/24 日漫
PHP 面向对象 PHP5 中的常量
2010/05/05 PHP
PHP命令行执行整合pathinfo模拟定时任务实例
2016/08/12 PHP
PHP切割整数工具类似微信红包金额分配的思路详解
2019/09/18 PHP
Javascript Jquery 遍历Json的实现代码
2010/03/31 Javascript
自己写的兼容ie和ff的在线文本编辑器类似ewebeditor
2012/12/12 Javascript
js工具方法弹出蒙版
2013/05/08 Javascript
js字符串截取函数slice、substring和substr的比较
2016/05/17 Javascript
Ionic快速安装教程
2016/06/03 Javascript
瀑布流的实现方式(原生js+jquery+css3)
2020/06/28 Javascript
Javascript实现前端简单的路由实例
2016/09/11 Javascript
jQuery实现在新增加的元素上添加事件方法案例分析
2017/02/09 Javascript
利用Node.js对文件进行重命名
2017/03/12 Javascript
Express URL跳转(重定向)的实现方法
2017/04/07 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
2017/04/21 Javascript
jQuery使用动画队列自定义动画操作示例
2018/06/16 jQuery
vue 设置路由的登录权限的方法
2018/07/03 Javascript
vue自定义移动端touch事件之点击、滑动、长按事件
2018/07/10 Javascript
es6 filter() 数组过滤方法总结
2019/04/03 Javascript
python检测远程服务器tcp端口的方法
2015/03/14 Python
Python实现将Excel转换为json的方法示例
2017/08/05 Python
python实现给scatter设置颜色渐变条colorbar的方法
2018/12/13 Python
python解压TAR文件至指定文件夹的实例
2019/06/10 Python
python 抓包保存为pcap文件并解析的实例
2019/07/23 Python
pycharm运行scrapy过程图解
2019/11/22 Python
Python imageio读取视频并进行编解码详解
2019/12/10 Python
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
马来西亚网上购物:Youbeli
2018/03/30 全球购物
师范毕业生自荐信
2013/10/17 职场文书
数控技术专科生自我评价
2014/01/08 职场文书
学生打架检讨书大全
2014/01/23 职场文书
锦旗标语大全
2014/06/23 职场文书
仲裁协议书
2014/09/26 职场文书
MySQL数据库超时设置配置的方法实例
2021/10/15 MySQL
victoriaMetrics库布隆过滤器初始化及使用详解
2022/04/05 Golang
面试官问我Mysql的存储引擎了解多少
2022/08/05 MySQL