通过浏览器的Oversides Content功能,半自动化参与投票活动

一、背景

某投票活动依托著名低代码平台生成,未强绑定用户信息投票。

二、分析

(1)通过captcha/get接口获取base64的二维码图片,需要依据wordList字段按顺序点击对应文字。

(2)对用户点击的范围信息进行签名,通过/captcha/check回传服务端进行验证。

(3)验证签名正确后,调用投票接口进行投票

因为验证码需要按固定顺序文字进行点击,这也意味着除了通过机器学习识别文字位置自动点击外,几乎没有能够自动化的方法了。

三、方案

即使是半自动运行,相对比手动一项项点选,半自动也可以提升不少效率。

整个投票流程如下:

  1. 选择N个投票项目。
  2. 点击投票按钮。
  3. 点击验证码。
  4. 投票成功进入结果页,点击再次点赞。

(1)第一版半动化脚本

策略:通过F12打开浏览器控制台,输入脚本实现自动选择项目+触发投票按钮

这一版的脚本实现了第一步、第二步的自动功能,缺点是每次投票成功返回上一页后,需要重新在控制台输入代码

(2)第二版半动化脚本

策略:通过浏览器的Oversides Content功能,手动往投票页面中注入JS脚本,实现在该页面的自动功能。

这一版遇到一个问题:在页面未完全加载时,脚本已经运行完毕(找不到元素而报错)。尝试了JQuery的ready方法和dom原生加载属性,但这俩都是页面文档下载完毕时就触发了,不满足等待页面元素渲染完成的需求。

解决办法也简单,增加一个Timer定时器,定时扫描页面上的元素是否存在,存在及触发点击即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var isChecked = false;
const scanTime = setInterval(function () {
console.log('scaning...')
if (document.querySelector('.image-vote-*** .vote-button') !== null && !isChecked) {
console.log('scaning success! auto click!')
clearInterval(scanTime)
isChecked = true;
document.querySelector('.image-vote-*** .vote-button').click();
setTimeout(() => {
document.querySelector('.image-vote-*** .vote-button').click();
setTimeout(() => {
document.querySelector('.popover-submit-btn div').click();
}, 100);
}, 50);
}
}, 200);

但这时候又遇到一个问题,注入JS至页面后,每次提交都会出现”请刷新页面后重试”的报错。我怀疑每次投票时会对页面HTML进行md5签名提交至后端验证完整性,于是尝试注入至其他引用的JS文件中,测试后可行。

至此解决了每次投票后刷新页面,需要重新在控制台输入代码的问题

(3)第三版半动化脚本

策略:目前第一、第二步已完成,第三步无法自动化,但第四步自动返回却是可以实现的。

又增加了一个Timer,监听页面的再次点赞按钮,出现时则自动点击返回上一页。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var isChecked = false;
const scanTime = setInterval(function () {
console.log('scaning...')
if (document.querySelector('.image-vote-*** .vote-button') !== null && !isChecked) {
console.log('scaning success! auto click!')
clearInterval(scanTime)
isChecked = true;
document.querySelector('.image-vote-*** .vote-button').click();
setTimeout(() => {
document.querySelector('.image-vote-*** .vote-button').click();
setTimeout(() => {
document.querySelector('.popover-submit-btn div').click();
}, 100);
}, 50);
}
}, 200);

var isChecked2 = false;
const scanTime2 = setInterval(function () {
console.log('scaning...')
if (document.querySelector('.submit-again-keys') !== null && !isChecked2) {
console.log('scaning success! auto click!')
clearInterval(scanTime2)
isChecked2 = true;
document.querySelector('.submit-again-keys').click();
}
}, 100)

至此已完成了1、2、4步骤的自动化,第三步验证码仍需要手动操作。但已经把完整投票流程精简到了无脑打码的复杂度,整个投票速度也大幅度上升。

四、拓展

直到活动最后,也没有用JS实现自动操作验证码,但这并不代表无法实现这个功能。在Github上有一些开源项目,实现了Python自动识别、点击的功能(如:captcha_crack)。虽然通过BrowerJS调用Python的想法不太现实,但是通过Chrome插件转发验证码却是可以尝试的,整个思路大致如下:

  1. 读取验证码:通过提取dom元素或通过验证码生成接口来获取Base64图片
  2. 转发验证码:通过websoket进行图片转发,调用Python服务。
  3. 识别验证码:等待Python服务识别,再通过websocket返回文字及其位置。
  4. 点击验证码:通过Chrome插件API模拟点击指定位置。

评论区