使用 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 相关文章推荐
Extjs4中tree的拖拽功能(可以两棵树之间拖拽) 简单实例
Dec 08 Javascript
JavaScript学习笔记之JS对象
Jan 22 Javascript
ajax+jQuery实现级联显示地址的方法
May 06 Javascript
JavaScript数组去重的3种方法和代码实例
Jul 01 Javascript
Vue DevTools调试工具的使用
Dec 05 Javascript
Vue完整项目构建(进阶篇)
Feb 10 Javascript
elementUI select组件value值注意事项详解
May 29 Javascript
浅析Vue下的components模板使用及应用
Nov 27 Javascript
Bootstrap简单实用的表单验证插件BootstrapValidator用法实例详解
Mar 29 Javascript
精读《Vue3.0 Function API》
May 20 Javascript
微信小程序调用wx.getImageInfo遇到的坑解决
May 31 Javascript
四十九个javascript小知识实用技巧
Nov 20 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以post形式发送xml的方法
2014/11/04 PHP
php实现多城市切换特效
2015/08/09 PHP
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
解决php写入数据库乱码的问题
2019/09/17 PHP
javascript hasFocus使用实例
2010/06/29 Javascript
javascript处理table表格的代码
2010/12/06 Javascript
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
js中onload与onunload的使用示例
2013/08/25 Javascript
实例代码详解javascript实现窗口抖动及qq窗口抖动
2016/01/04 Javascript
javascript实现tab响应式切换特效
2016/01/29 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
2016/03/29 Javascript
原生js的数组除重复简单实例
2016/05/24 Javascript
利用vue-router实现二级菜单内容转换
2016/11/30 Javascript
JS实现的DIV块来回滚动效果示例
2017/02/07 Javascript
vue使用stompjs实现mqtt消息推送通知
2017/06/22 Javascript
微信小程序实现图片懒加载的示例代码
2017/12/13 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
js实现的格式化数字和金额功能简单示例
2019/07/30 Javascript
Vue获取微博授权URL代码实例
2020/11/04 Javascript
python基础教程之python消息摘要算法使用示例
2014/02/10 Python
详解python分布式进程
2018/10/08 Python
Python/Django后端使用PIL Image生成头像缩略图
2019/04/30 Python
python 使用pygame工具包实现贪吃蛇游戏(多彩版)
2019/10/30 Python
python从zip中删除指定后缀文件(推荐)
2019/12/05 Python
jupyter notebook读取/导出文件/图片实例
2020/04/16 Python
Django项目uwsgi+Nginx保姆级部署教程实现
2020/04/19 Python
解决python运行效率不高的问题
2020/07/20 Python
女士鞋子、包包和服装在线,第一款10美元:ShoeDazzle
2019/07/26 全球购物
STP协议的主要用途是什么?为什么要用STP
2012/12/20 面试题
八一演出活动方案
2014/02/03 职场文书
中专生毕业个人鉴定
2014/02/26 职场文书
企业法人代表证明书
2014/09/27 职场文书
破坏寝室公物检讨书
2014/11/17 职场文书
中学感恩教育活动总结
2015/05/05 职场文书
《小小的船》教学反思
2016/02/18 职场文书
2019广播稿怎么写
2019/04/17 职场文书