使用OpenCV 破解QQ登录中的滑动验证码
系列文章目录
第一篇: Java实现QQ登录
第二篇: Selenium QQ自动化登录
第三篇: 使用OpenCV 破解QQ登录中的滑动验证码
文章目录
系列文章目录
文章目录
前言
一、登录流程
二、验证办法
1.滑动验证码
2.获取缺口坐标
2.1 获得两张验证码的url
2.2 处理图片获得x坐标
2.3 调用结果
总结
前言
前面几篇文章中介绍了在安全状态下,QQ登录的几种方法,但是只要是,该账号登录在新IP上,或用新账号登录本IP,都会使得登录流程转向非安全状态,即会有图片验证码,如下:
提示:以下是本篇文章正文内容,下面案例可供参考
一、登录流程
如我在第一篇文章中介绍那样:Java实现QQ登录,会多出几个请求,其中我们会看到又两个img的请求:
而这两个请求正是获得验证码图片和图片缺口的接口。
二、验证办法
1.滑动验证码
当我们拖动滑块并停止时,会向后台发送一个cap_union_new_verify的请求,这个request的data里,又这样一个关键的数据,ans
经过分析得知,这个ans的值,正式滑动验证码中缺口图片在原图中的位置,那么我们只要能获得这个缺口坐标,即可获得正确request data。
2.获取缺口坐标
我们使用OpenCV来处理图片
2.1 获得两张验证码的url
大图:
https://t.captcha.qq.com/hycdn?index=1&image=937349372142954496?aid=21000501&sess=s0QmzAR9jp0J_P9zQf6-BikkZVSLAm3IZz9JBiMAkRnqiQQ-ehtcopO3OYgJzF9ZLrA1B6phmWOrNtG1YEarWRA9wRp2gHvMW9lzGN5bZgFvIdgvL1ljAEcUq-ASo3WNABJPoMJP-UWSkRsimXX2wetiGFbUg7pMjUYGBPJAUxL8gCiyRnbKExWMrjyzVu4onNqzoxRU4_Ou9jexaVzeERJRo-WahiuPG2NyiohF5390zOVQ1tmDAmDg**&sid=607792806632235317&img_index=1&subsid=9
缺口图:
https://t.captcha.qq.com/hycdn?index=2&image=937349372142954496?aid=21000501&sess=s0QmzAR9jp0J_P9zQf6-BikkZVSLAm3IZz9JBiMAkRnqiQQ-ehtcopO3OYgJzF9ZLrA1B6phmWOrNtG1YEarWRA9wRp2gHvMW9lzGN5bZgFvIdgvL1ljAEcUq-ASo3WNABJPoMJP-UWSkRsimXX2wetiGFbUg7pMjUYGBPJAUxL8gCiyRnbKExWMrjyzVu4onNqzoxRU4_Ou9jexaVzeERJRo-WahiuPG2NyiohF5390zOVQ1tmDAmDg**&sid=607792806632235317&img_index=2&subsid=10
url中最重要的参数sess可从上一个请求:cap_union_prehandle中的response中获得。
验证码的图有时间限制,一段时间后会过期
2.2 处理图片获得x坐标
因为滑块是左右滑动的,所以y坐标固定,我们先滑动一下获得他的y坐标,本例中的y坐标是41。
使用下面程序:
// 加载opencv环境public static String dllPath = "D:\\workcode\\txslider\\src\\main\\resources\\opencv\\opencv_java3413.dll";/*** 获取验证滑动距离** @return*/public static int getTencentDistance(String bUrl, String sUrl, int top) {System.load(dllPath);File bFile = new File("D:\\cap_union_new_getcapbysig.jpg");File sFile = new File("D:\\cap_union_new_getcapbysig.png");try {FileUtils.copyURLToFile(new URL(bUrl), bFile);FileUtils.copyURLToFile(new URL(sUrl), sFile);BufferedImage bgBI = ImageIO.read(bFile);BufferedImage sBI = ImageIO.read(sFile);// 裁剪bgBI = bgBI.getSubimage(360, top, bgBI.getWidth() - 370, sBI.getHeight());ImageIO.write(bgBI, "png", bFile);Mat s_mat = Imgcodecs.imread(sFile.getPath());Mat b_mat = Imgcodecs.imread(bFile.getPath());// 转灰度图像Mat s_newMat = new Mat();Imgproc.cvtColor(s_mat, s_newMat, Imgproc.COLOR_BGR2GRAY);// 二值化图像binaryzation(s_newMat);Imgcodecs.imwrite(sFile.getPath(), s_newMat);int result_rows = b_mat.rows() - s_mat.rows() + 1;int result_cols = b_mat.cols() - s_mat.cols() + 1;Mat g_result = new Mat(result_rows, result_cols, CvType.CV_32FC1);Imgproc.matchTemplate(b_mat, s_mat, g_result, Imgproc.TM_SQDIFF); // 归一化平方差匹配法// 归一化相关匹配法Core.normalize(g_result, g_result, 0, 1, Core.NORM_MINMAX, -1, new Mat());Core.MinMaxLocResult mmlr = Core.minMaxLoc(g_result);Point matchLocation = mmlr.maxLoc; // 此处使用maxLoc还是minLoc取决于使用的匹配算法Imgproc.rectangle(b_mat, matchLocation,new Point(matchLocation.x + s_mat.cols(), matchLocation.y + s_mat.rows()), new Scalar(0, 0, 0, 0));return (int) ((matchLocation.x + s_mat.cols() + 360 - sBI.getWidth()));} catch (Throwable e) {e.printStackTrace();return 0;} finally {bFile.delete();sFile.delete();}}/**** @param mat* 二值化图像*/public static void binaryzation(Mat mat) {int BLACK = 0;int WHITE = 255;int ucThre = 0, ucThre_new = 127;int nBack_count, nData_count;int nBack_sum, nData_sum;int nValue;int i, j;int width = mat.width(), height = mat.height();// 寻找最佳的阙值while (ucThre != ucThre_new) {nBack_sum = nData_sum = 0;nBack_count = nData_count = 0;for (j = 0; j < height; ++j) {for (i = 0; i < width; i++) {nValue = (int) mat.get(j, i)[0];if (nValue > ucThre_new) {nBack_sum += nValue;nBack_count++;} else {nData_sum += nValue;nData_count++;}}}nBack_sum = nBack_sum / nBack_count;nData_sum = nData_sum / nData_count;ucThre = ucThre_new;ucThre_new = (nBack_sum + nData_sum) / 2;}// 二值化处理int nBlack = 0;int nWhite = 0;for (j = 0; j < height; ++j) {for (i = 0; i < width; ++i) {nValue = (int) mat.get(j, i)[0];if (nValue > ucThre_new) {mat.put(j, i, WHITE);nWhite++;} else {mat.put(j, i, BLACK);nBlack++;}}}// 确保白底黑字if (nBlack > nWhite) {for (j = 0; j < height; ++j) {for (i = 0; i < width; ++i) {nValue = (int) (mat.get(j, i)[0]);if (nValue == 0) {mat.put(j, i, WHITE);} else {mat.put(j, i, BLACK);}}}}}
主要思想为:根据传入的y坐标和两个图片的url,将网络上的图片先保存在本地,然后对大图进行切图,减少一些计算量,然后二值化两张图,接着使用归一化相关匹配法,计算出切图后的x距离,最后加上原来的x距离,即可得到最终的x坐标。
2.3 调用结果
getTencentDistance("https://t.captcha.qq.com/hycdn?index=1&image=937349372142954496?aid=21000501&sess=s0QmzAR9jp0J_P9zQf6-BikkZVSLAm3IZz9JBiMAkRnqiQQ-ehtcopO3OYgJzF9ZLrA1B6phmWOrNtG1YEarWRA9wRp2gHvMW9lzGN5bZgFvIdgvL1ljAEcUq-ASo3WNABJPoMJP-UWSkRsimXX2wetiGFbUg7pMjUYGBPJAUxL8gCiyRnbKExWMrjyzVu4onNqzoxRU4_Ou9jexaVzeERJRo-WahiuPG2NyiohF5390zOVQ1tmDAmDg**&sid=607792806632235317&img_index=1&subsid=9","https://t.captcha.qq.com/hycdn?index=2&image=937349372142954496?aid=21000501&sess=s0QmzAR9jp0J_P9zQf6-BikkZVSLAm3IZz9JBiMAkRnqiQQ-ehtcopO3OYgJzF9ZLrA1B6phmWOrNtG1YEarWRA9wRp2gHvMW9lzGN5bZgFvIdgvL1ljAEcUq-ASo3WNABJPoMJP-UWSkRsimXX2wetiGFbUg7pMjUYGBPJAUxL8gCiyRnbKExWMrjyzVu4onNqzoxRU4_Ou9jexaVzeERJRo-WahiuPG2NyiohF5390zOVQ1tmDAmDg**&sid=607792806632235317&img_index=2&subsid=10",41)
调用getTencentDistance方法,传入大图和缺口图的地址,并传入y坐标。
最终结果为:
而实际y坐标为
相差6个像素点,在可接受范围内。
总结
本文主要介绍了用opencv,来识别滑动验证码中,缺口图片相对背景图的x坐标,获得了x坐标位置,即可模拟手动滑动,完成验证码的突破,结合前面几篇文章,即可完成有验证码情况下的登录。
当然还有更方便的方式,即通过Selenium自动模仿人手动滑动的方法,这种方法将在下篇文章中介绍。
使用OpenCV 破解QQ登录中的滑动验证码相关推荐
- 自动化测试中的滑动验证码解决方案
很多同学反馈,在web自动化的过程中,经常会被登录的验证码给卡住,不知道如何去通过验证码的验证. 今天专门给大家来聊聊验证码的问题,一般的情况下遇到验证码我们可以都可以找开发去帮忙解决,关闭验证码,或 ...
- RPA中关于“滑动”验证码与按照“语序”点击两类验证码
学Python,用RPA 艺赛旗RPA2020.1版本 正在免费下载使用中,欢迎下载使用 www.i-search.com.cn/index.html?from=line1 最近发现很多伙伴在项目中都 ...
- 为啥QQ登录一直要求输入验证码
目前QQ空间官方进行了过滤处理,有可能你发表同一主题或操作频率过快被系统侦测到.然后限制了.所以会一直出现验证码错误.这样必须等一会儿.. 有可能你输入的验证码确实没有错误,但还是有提示错误,可能会会 ...
- 使用第三方打码平台图鉴识别滑动验证码模拟登录
文章目录 一.图鉴的账户注册 识别流程 二.欧模网案例滑动验证码模拟登录 页面分析 三.代码分析 四.欧模网案例展示 总结 一.图鉴的账户注册 图鉴网页地址: http://www.ttshitu.c ...
- java 滑块验证码 开源,Java AWT生成滑动验证码
最近工作需要在登录时使用滑动验证码做登录校验,在生成验证码图片的时候碰到了不小的麻烦 : (. 网上能查到的做法基本上都是使用一张已存在的实际图片作为滑块的图形模板,然后按照此模板做二重循环逐像素地从 ...
- .NET 6 实现滑动验证码(九)、搭建验证码API服务端
上一篇介绍了实现验证码生成的方法跟验证方法.本篇文章介绍如何在项目中使用. 目录 项目配置 项目配置 在实际应用中,我们可以添加打包好的.nupkg文件,也可以使用添加现有项目的方式,把源码添加到现有 ...
- 使用opencv破解滑块验证码:以今日头条PC端登录页面滑块验证码为例
本文目标人群:python爬虫工程师 一.首先看看破解的效果图 二.滑块验证码的破解 滑块验证码的破解的难点主要有两个:计算出滑块到缺口的距离和模拟人拖动滑块的轨迹. 如何计算出滑块到缺口的距离?从网 ...
- python+opencv+selenium自动化登录邮箱并解决滑动验证
前言 大家做自动化登录时可能都遇到过滑块验证码需要手动验证的问题,这次我们就来解决他 如下: 在我们做自动化登录时,总会遇到各种奇奇怪怪的验证码,滑块验证码就是其中最常见的一种.若我们的程序自动输 ...
- Day06,selenium的剩余用法、万能登录破解和爬取京东商品信息,及破解极验滑动验证码...
一.自动登录抽屉新热榜 from selenium import webdriver import timedriver = webdriver.Chrome(r'D:\BaiduNetdiskDow ...
最新文章
- python趣味编程100_《Python游戏趣味编程》 第8章 勇闯地下一百层
- Python中模块(Module)和包(Package)的区别
- win10 2004 最新版图文安装流程
- 数据库系统概念总结:第三章 SQL
- 将字符串中的空格用%20替换
- python转换窗口无响应_Tkinter窗口显示(没有响应),但代码正在运行
- mysql++编程规范_建议收藏 - 专业的MySQL开发规范
- php找不到intl,php_intl.dll找不到指定模块怎么办
- Bailian2715 谁拿了最多奖学金【分段计算处理】(Vijos P1001)
- 如何使用SQL Server游标
- 在一线城市做Java开发如何月薪达到两万,需要技术水平达到什么程度?
- 如何恢复隐藏的窗口 已知进程名称_Windows 10如何显示文件名后缀?
- DotNetBar SuperGridControl控件
- 常用网络测试命令——ping命令
- 信息规范和信息安全素养计算机,技师学院计算机专业学生信息安全意识培养的教学研究...
- Ubuntu 解压 zip、z01、z02等文件方法
- css 右上角 翻开动画_CSS3 transition动画、transform变换、animation动画
- 直播疑难杂症排查(7)— 黑屏、花屏、闪屏问题
- NET Core 模板项目 - NuGet
- Linux内核学习路线