引子

不知道大家是否还记得之前让我刷赞的小朋友,自从他回到学校后,可能是由于学业太忙,把我们组成刷赞团队的事情忘记了,只是每天早上给我发信息帮他刷赞,迟迟没有新的用户,刷赞就没有量产的动力,我怠慢了几天没给他刷,他就不再理我了,我觉得是中了他的圈套,他只是嘴上说说要发展团队,其实只是贪恋我每天给他刷几万个赞。

效果

selnium过滑动验证码

代码

const webdriver = require('selenium-webdriver')
const firefox = require('selenium-webdriver/firefox');
const fs = require('fs')
const getPixels = require("get-pixels")
const ndarray = require("ndarray")!async function(){// 新建一个 firefox 的 driver 实例var options = new firefox.Options().setProfile('C:/Users/2bt/AppData/Roaming/Mozilla/Firefox/Profiles/m1mwcwm8.default')var driver = await new webdriver.Builder().forBrowser('firefox').setFirefoxOptions(options).build()console.log('开始模拟操作,命令提示符跳动代表着等待网页过程,默认都是10秒。如果网络较差,可能导致错误。')console.log('———————————————————————————————————————————————————————————————————————————————')main();async function main(){var distance = 0, dragX = 0 ,bgX =0 ,errX=0;// 访问极验demo页
await driver.get('http://www.jg520.com/?fid=1&tid=2095')var searchBox = driver.wait(webdriver.until.elementLocated(webdriver.By.id('inputvalue')), 10000)searchBox.sendKeys('809101180');
await driver.sleep(500)
console.log('填写QQ号')var btn = await driver.wait(webdriver.until.elementLocated(webdriver.By.id('submit_buy')), 10000)await driver.sleep(5000)await btn.click();
console.log('点击免费领取,等待验证码')try{
await driver.wait(webdriver.until.alertIsPresent(),5000);
let alert = await driver.switchTo().alert();
let alertText = await alert.getText();
if(alertText) console.log('每天限领一次,已领取,结束进程。')
await alert.accept();
return 0;
}catch(err){}btn = await driver.wait(webdriver.until.elementLocated(webdriver.By.css('.geetest_radar_tip')), 10000)
await btn.click();
await driver.sleep(3000)//找到验证码背景图元素, 是一个 canvas
const bgCanvas = await driver.wait(webdriver.until.elementLocated(webdriver.By.css('.geetest_window')), 30000)//1 截取bg图片
await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 1;document.querySelector(".geetest_canvas_slice").style.opacity = 0;')
const bgPng = await bgCanvas.takeScreenshot()
//取消隐藏
await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 1;document.querySelector(".geetest_canvas_slice").style.opacity = 1')getPixels('data:image/png;base64,'+bgPng,function(err, pixels) {if(err) {console.log("读取背景缺口位置错误")return}bgX = getBoundary(pixels,getGrey(pixels)/10*3)//console.log('读取背景缺口边界X坐标: ',bgX);
})// 获取拼图滑块按钮const button = await driver.wait(webdriver.until.elementLocated(webdriver.By.css('.geetest_slider_button')), 30000)// 初始化 actionlet actions = driver.actions({async: true})console.log('开始计算拖动位置')await driver.sleep(3000)// 把鼠标移动到滑块上, 然后点击await actions.move({origin: button,duration: 1000}).pause(100).press().move({origin: button,x: 1,duration: 10}).pause(300).perform()//截取slice图片,用于计算拖动后产生的随机位移await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 0;document.querySelector(".geetest_canvas_slice").style.opacity = 1;')const slice = await bgCanvas.takeScreenshot()//取消隐藏await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 1;document.querySelector(".geetest_canvas_slice").style.opacity = 1')getPixels('data:image/png;base64,'+slice.toString(),function(err, pixels) {if(err) {console.log("读取初始位置错误")return}dragX = getBoundary(pixels,360)})await driver.sleep(500)distance = bgX - dragX;var arr = getTrack(distance*0.8+20)//乘以0.8是因为计算出的值是以截取的canvas为基础的,真实拖动的距离需要乘以5:4这个比值console.log('开始拖动滑块,需要滑动的距离: ',distance*0.8+20)var backArr =  [-4,-5,-6,-4,-2,-1]await moveTrack(arr,backArr)//4 再次截取slice图片,看看那里出错了await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 0;document.querySelector(".geetest_canvas_slice").style.opacity = 1;')const err = await bgCanvas.takeScreenshot()//取消隐藏await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 1;document.querySelector(".geetest_canvas_slice").style.opacity = 1')getPixels('data:image/png;base64,'+err,function(err, pixels) {if(err){console.log('获取最终位置错误')return}errX = getBoundary(pixels,360)console.log('完成移动到: ',errX,',错位: ',(errX - bgX)*0.8);})await driver.sleep(3000)const successTip =  driver.wait(webdriver.until.elementLocated(webdriver.By.id('layui-layer10'),10000)).getText()if(successTip === '领取成功,等待到账,请收藏本站网址每天领福利,好东西一定要分享给好友哦!'){console.log('成功~')}else{console.log('失败~重新操作')await driver.sleep(3000)    main()}}async function moveTrack(arr,backArr){let actions = driver.actions({bridge: true})for(i=0;i<arr.length;i++){var random = Math.floor(Math.random()*200+30)await actions.move({origin: webdriver.Origin.POINTER,x:arr[i],duration:random})}await actions.pause(100)for(i=0;i<backArr.length;i++){var random = Math.floor(Math.random()*200+30)await actions.move({origin: webdriver.Origin.POINTER,x:backArr[i],duration:random})}await actions.release().perform()
}async function move(distance){await driver.sleep(1000)let actions = driver.actions({bridge: true})await actions.move({origin: webdriver.Origin.POINTER,x:distance,duration:1000}).release().perform()console.log("滑动距离: ",distance)
}async function getStep(){//截取slice图片,用于计算拖动后产生的随机位移await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 0;document.querySelector(".geetest_canvas_slice").style.opacity = 1;')const slice = await bgCanvas.takeScreenshot()//取消隐藏await driver.executeScript('document.querySelector(".geetest_canvas_bg").style.opacity = 1;document.querySelector(".geetest_canvas_slice").style.opacity = 1')getPixels('data:image/png;base64,'+slice.toString(),function(err, pixels) {if(err) {console.log("读取初始位置错误")return}dragX = getBoundary(pixels,360)console.log('getStep函数返回:' ,dragX)})
}//取模拟拖动滑块的数据
//用等差数列代替了匀加速运动
//因为匀加速运动取得的小数经过四舍五入会出现不精确,导致拖动的距离出差错
function getTrack(distance){var track = [],d=2,n=0,s=0,S=0while(S<distance){s=1+n;n=n+d;S+=s;track.push(s)}var diff = (S - distance);track.splice(-1,1,Math.round(Number(track.slice(-1))-diff))return track;
}//getBoundary查找边界函数。
//参数
//pixels是get-pixel库获取的内容
//level是灰度,用来与一个像素点rgb三个值加起来的数比较,用于确定该点的黑色程度,level越小表示越黑。
function getBoundary(pixels, level){var lastY=0, count=0;for(var i=0; i < pixels.shape[0]; i++) {for(var j=0; j < pixels.shape[1]; j++) {var rgb = pixels.get(i,j,0) + pixels.get(i,j,1) + pixels.get(i,j,2)if(rgb < level && lastY+1 == j) {count++;//console.log(rgb, i,j ,count);}else count = 0;lastY = j;if(count > 6) return i;
}
}return 0;
}//获取灰度值
function getGrey(pixels){var rgb = 0;for(var i=0; i < pixels.shape[0]; i++) {for(var j=0; j < pixels.shape[1]; j++) {rgb += pixels.get(i,j,0) + pixels.get(i,j,1) + pixels.get(i,j,2)}}return Math.floor(rgb/pixels.shape[0]/pixels.shape[1])
}}()

使用方法

好像没啥特殊的,直接node就可以。

需要用npm安装get-pixelsndarray这两个包,用来识别图像的。
我用的是firefox,如果用chrocme或safari,需要自己去替换引用和下载驱动。

周末看了点node教程,讲node适用于任务调度,强项不是计算,怪不得网上的验证码代码大多都是python写的,而且遇到问题nodejs+selenium相关的答案较少,官网的文档又比较简单,废了好大的劲。

基于nodejs+selenium自动过滑动验证码的QQ刷赞相关推荐

  1. python+selenium+chrome 做滑动验证码 会被浏览器检测到使用的自动软件导致滑动验证失败

    python+selenium+chrome 做滑动验证码 会被浏览器检测到使用的自动软件导致滑动验证失败 解决方法:代码中添加: import time from selenium import w ...

  2. selenium篇之滑动验证码

    一.介绍 现在出现了一种通过用户鼠标移动滑块来填补有缺口图片的验证码,我们叫做滑动验证码.它的原理很简单,首先生成一张图片,然后随机挖去一块,在页面展示被挖去部分的图片,再通过js获取用户滑动距离,以 ...

  3. selenium+opencv干掉滑动验证码

    我们在用自动化测试来做爬虫的时候,总是会遇见很多的验证码,其中的滑块拼接验证就是其中一种:selenium是一个自动化测试库,opencv是计算机视觉库,我们可以用这两个库来模仿人工滑动验证码,完成验 ...

  4. selenium爬虫|破解滑动验证码以极验为例

    爬虫访问一些网站遇到滑动验证码解决方案 这里是用selenium做模拟,如果是requests可以封装这个登录方法来获取登录后的cookies也是可以用的. 1 思路 先讲思路,分析流程 我们输入账号 ...

  5. selenium破解bilbili滑动验证码

    登陆b站的时候大家都会见到滑动验证码,打开开发者工具分析一下这里的验证码 1:首先需要鼠标触碰到滑动按钮才会显示出完整的验证码图片 2:点击按钮出现缺口图片 3:查看图片元素会(打开图片链接)发现完整 ...

  6. selenium登录 京东滑动验证码

    京东的滑动验证码在页面上是没有原图的,所有我是用ps把他们拼成一个的. from selenium import webdriver from selenium.webdriver import Ac ...

  7. selenium自动登录QQ邮箱(附带滑动解锁)

    问题分析:登录+滑动解锁 其实登录账号的部分本来很简单,用selenium打开QQ邮箱官网:https://mail.qq.com 然后切换frame输入帐号 和密码点击登录即可,但是部分账号,或者可 ...

  8. selenium自动化案例(二)滑动验证码破解

    文章目录 写在前面 大致思路 Python实现 几个小坑 写在前面 最近学习了滑动验证的一个破解思路,是利用OpenCV的图形匹配算法进行对比验证,从而推算出滑块移动的距离,在实际应用中比较常见,我主 ...

  9. python selenium UI自动化解决验证码的4种方法

    测试环境 windows7+ firefox50+ geckodriver # firefox浏览器驱动 python3 selenium3 selenium UI自动化解决验证码的4种方法:去掉验证 ...

最新文章

  1. nodejs web开发入门: Simple-TODO Nodejs 实现版
  2. 前端构建工具之争——Webpack vs Gulp 谁会被拍死在沙滩上
  3. python_day6 shutil模块
  4. jQuery kxbdMarquee 无缝滚动
  5. 两个不同网段的局域网如何互通_不同网段之间如何通信?
  6. 一次动态代理的填坑之旅
  7. 红帽linux lnmp搭建,RedHat/CentOs系统搭建lnmp环境
  8. AI芯片浮出新玩家OURS,来者何人?新晋图灵奖得主华人弟子谭章熹
  9. 算法:258. Add Digits 各位相加
  10. 纸鸢|物联网云平台小工具集合常见 MQTT 客户端比较
  11. 谈谈我对《ThoughtWorks文集》中多语言开发部分的看法
  12. Cordova插件之跳转第三方app
  13. Windows“控制面板”在哪?win10怎么打开控制面板(快捷方法)打开控制面板的多种方法都在这里
  14. 笔记本共享网络给台式机
  15. Rviz显示不出数据了之一文搞懂Qos
  16. 使用 Byzanz 录制 Gif 动画或 Ogv 视频
  17. ESP32开发2——新建项目
  18. android App中bug收集的工具类
  19. from scipy.misc import imread, imresize, imsave 报错的解决方法
  20. 从零学习Fluter(八):Flutter的四种运行模式--Debug、Release、Profile和test以及命名规范...

热门文章

  1. 打造吸睛运动耳机 Skullcandy推出“独立紫”限量套装
  2. 盘点十大能净化空气的植物
  3. 有哪些可以直接PS图片的在线工具呀
  4. iFIERO -- SkyNinja天猪之城 SpriteKit iOS游戏源码
  5. 一张图不用,纯CSS 做个生日贺卡
  6. a73*2+a53*2指的是什么_小鸡宝宝考考你 买空调时推销员经常提到的1匹2匹等指的是空调的|小鸡|宝宝-360GAME...
  7. 实战:云开发·实现奶茶店小程序(二)
  8. 一文讲清Python的7大学习路线(建议收藏)
  9. python格式化输出日期_1、Python 日期时间格式化输出
  10. Python:ffmpeg修改视频分辨率