滑动验证码破解

背景

最近由于需要爬取一些数据,但是这个数据必须在登陆状态下才能得到,调研了很多爬虫的反爬技术的攻防,发现采用一些比较底层的爬虫框架虽然速度更快扩展性更好,但是成本比较高,目标网站任何改动都可以让整个爬虫崩溃,因此需要花大力气去维护,但是我的需求并不是大量数据,而是 “爬下来”,所以最后选择了selenium去进行爬取,理论上所见即所得,即所爬。

关于验证码

在登陆的时候,发现需要进行一个验证码的验证,验证码本质就是识别机器和人,这本身就是一个攻防战,理论上如果足够像人就够了。那剩下的就是爬虫能够如何让其更加的像人,这个话题就比较玄学了,所以验证码设计与爬虫这个猫鼠游戏其实挺有意思的。
现在常见的验证码,主要分为,图片字幕,鼠标轨迹捕捉,文字组合,以及12306这种反人类的知识认知解答等等,以至于连真人都很难识别,由于12306的垄断性质所以其可以做的很极端,但是即使是这样,也催生了一个特殊的职业,人工打码,雇佣真人来进行识别,据我所知网上所谓的一些在家点点鼠标就能赚钱的工作一部分就是这个事情。
大部分互联网公司更倾向于在用户体验和验证码识别机器与人类之间做平衡,毕竟互联网公平竞争的时代,用户体验就是王道。这次需要破解就是滑动验证码。
在这里插入图片描述
就是这样一个验证码。
在这里插入图片描述

思路整理

这个验证码它是如何进行识别的呢,就是按住下面的滑条,移动图片中的滑块与背景图中的凹陷进行匹配,匹配成完整的图片,不仅如此,整个滑动的操作本身也必须是符合正常人的一个操作,例如滑动不应该是瞬间匹配,而是先快到缺块附近,再慢慢进行精准匹配,这才是一个正常人类。
在这里插入图片描述

技术分析
  1. 竟然要模拟滑动,首先selenium本身是支持按住鼠标滑动并松开鼠标的操作的,这个可以查阅selenium文档即可。

  2. 拉动滑条的长度,需要分析整个图片缺陷的位置,并且这个像素的长度不简单就是滑条的长度,而是一个比例缩放的过程,因此第一步应该是计算出凹陷占整个图片的比例,然后再根据滑条的像素长度 乘以 比例得到最终滑动。公式:滑动比例 * 滑条长度 = 滑动像素长度。在这里插入图片描述

  3. 如何分析图片凹陷位置呢?竟然要分析图片,肯定先获取到图片,selenium path从页面抓取验证码图片,因为图片本身是由像素点构成,所以打算从分析每个像素点的特征着手,在我看来图片就是个二维数组,每个点就是一个RGB值,应该有某种方式去解析图片成这个RGB值的二维数组。于是我去开源库寻找,后来发现JDK自带就可以解析图片。

  4. 解析好了图片成二维数组,再去分析图片特征,发现只要分析这两个边的位置,其实就可以求平均,找到凹陷的正中点了,这两条竖直的白线有什么特点呢,提到“白”,肯定RGB有一定的特征。根据这个特征识别出来这些点,并通过计算得到这两个竖线的横坐标。在这里插入图片描述

  5. 然后计算出位置在整个图片长度的比例,再通过selenium拿到滑动条的长度,即可计算出滑动的长度。

  6. 模拟滑动,这个过程模拟人类滑动,不能简单的匀速,而是要随机数散列,动态剩余长度随机数滑动,剩余的长度越小,随机数的范围也就越小,因此达到一种速度放慢的效果,欺骗检测。

代码实战
    /*** 处理滑动验证码破解*/public boolean skipRobotTest() {try {// 下载图片ImageDownload imageDownload = new ImageDownload();WebElement img = getRobotTestImage();String imgUrl = img.getAttribute("src");imageDownload.dowloadImage(imgUrl, CURRENT_ROBOT_TEST_IMAGE);// 获取比例double slideRate = getSlideRate(CURRENT_ROBOT_TEST_IMAGE);// 滑动滑条moveButton(slideRate);} catch (Throwable e) {return true;}return false;}

为了保证破解验证码的稳定性,避免一次破解程序崩溃的尴尬,我们可以简单在调用外层写一个重试的逻辑:

 		while (!skipRobotTest()) {LogUtils.print("skip robot will retry");continue;}LogUtils.print("login success");

接下来是精彩环节:
每个像素点RGB值其实有4个字节组成的混合值,因此对应分别获取三个点值需要进行位运算。
在这里插入图片描述

     private double getSlideRate(String imageName) {try {/*获取图片的长宽,构建二维数组遍历*/BufferedImage image = ImageIO.read(new File(ChromeSupport.INS_PATH + imageName + ".jpeg"));int width = image.getWidth();int height = image.getHeight();// 标记较白的点为凹陷轮廓边缘点List<Integer> widthEdgeList = Lists.newArrayList();for (int i = 0;i < width;i ++) {for (int j = 0; j < height; j++) {// 这里分别获取RGB值的,红,绿,蓝 的值int rgb = image.getRGB(i, j);int redV = (rgb & 0xff0000) >> 16;int greenV = (rgb & 0xff00) >> 8;int blueV = (rgb & 0xff);// 分析发现,数值越大,越接近白色,因此这里分别判断三个值,达到230即可标记为一个较白的点if (redV > 230 && greenV > 230 && blueV > 230) {widthEdgeList.add(i);}}}/*统计凹陷最多的横坐标*/Map<Integer, List<Integer>> map = widthEdgeList.stream().collect(Collectors.groupingBy(Integer::intValue));ArrayList<List<Integer>> lists = Lists.newArrayList(map.values());Collections.sort(lists, (o1, o2) -> {if (o1.size() > o2.size()) {return -1;} else if (o1.size() < o2.size()) {return 1;}return 0;});// 左竖线横坐标int leftEdge = lists.get(0).get(0);// 右竖线横坐标int rightEdge = lists.get(1).get(0);// 得到凹陷正中央int slidePixel = (rightEdge + leftEdge) / 2;// 滑动比例double rate = Double.valueOf(slidePixel) / Double.valueOf(width);// 柔性调整return zoomRate(rate);} catch (IOException e) {LogUtils.errorPrint(e, "get kill robot rate error");}return 0;}

关于柔性调整,最终实验发现光滑动条*比例还不够,验证码会在越偏离整个背景图片的正中央位置进行放大比例,这个柔性比例就是在比例在某个区间的时候去进行同步放大一定的比例,去抵消被放大的比例。这个方法很简单粗暴,就是if else去调整,根据识别的成功率逐渐完善:

    /*** 发现会根据50%的偏移量需要增量* @param rate* @return*/private double zoomRate(double rate) {double originRate = rate;if (rate < 0.45) {rate -= 0.02;}if (rate >= 0.45 && rate < 0.6) {return rate;} else if (rate >= 0.6 && rate < 0.67) {rate += 0.02;} else if (rate >= 0.67 && rate < 0.75){rate += 0.02;} else if (rate >= 0.75 && rate < 0.8){rate += 0.05;} else {rate += 0.07;} LogUtils.print("kill robot slide rate %s, zoom rate %s", originRate, rate);return rate;}

准备好了所有数据,然后开始滑动操作:

    private void moveButton(double slideRate) {// 获取滑动条点击样式元素WebElement moveButtonEl = webDriver.findElement(By.xpath("xxxxxxx"));Actions moveAction = new Actions(webDriver);moveAction.clickAndHold(moveButtonEl);// 540为滑动条的全部长度,随机滑动步数int targetMoveCount = (int) (540 * slideRate);// getRandomStep获得随机长度移动数组for (Integer count : getRandomStep(targetMoveCount)) {moveAction.moveByOffset(count, 0);moveAction.perform();}moveAction.release(moveButtonEl).perform();}

随机长度生成规则:

    public List<Integer> getRandomStep(int targetMoveCount) {List<Integer> list = Lists.newArrayList();while (targetMoveCount > 0) {// 剩余长度生成随机数int count = RandomUtils.nextInt(0, targetMoveCount + 1);list.add(count);// 得到剩余长度targetMoveCount -= count;}return list;}

完成

总结

由于涉及目标网站,所以这里就不展示效果,得到这样的优化之后,成功率基本达到100%,整个过程学习到不少图片识别OCR相关的知识,也熟悉了爬虫框架,甚至了解了人体行为学的东西,还是挺好玩的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/71763.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

So easy!同时登陆两个或多个Mac版微信和QQ

如今&#xff0c;微信和QQ已经不单单是简单的社交软件了&#xff0c;也成了工作必备软件&#xff0c;工作中用它传个文件&#xff0c;发个通知&#xff0c;不知道有多方便。 但是很多人希望将工作圈和生活圈分开&#xff0c;有人想出拿两部手机的方法&#xff0c;倒是可以&…

保证同一个账号同时只能在一个设备上登录

2019独角兽企业重金招聘Python工程师标准>>> 一、使用redis存token redis key设计 access_token_{token}:{userInfoJsonStr} 用户登录成功后&#xff0c;把token作为key&#xff0c;用户信息做为value。作用&#xff1a;通过token可以查到userinfo token_by_userId_…

怎么实现同一账号只能在一台设备登录

同一账号只能在一台设备登录实现思路。 注意:登录是在白名单&#xff08;直接放行的接口&#xff09;。生成的token携带账号信息。 1.用户每次登录生成token时&#xff0c;将账号当成key&#xff0c;token当成value&#xff0c;以token的过期时间存入redis中。 2.用户访问的…

排名第一的亚马逊关键词工具

如果你还不知道如何寻找并且确定属于自己产品的关键词&#xff0c;看完这篇文章你就会有所启发了。 做电商平台的&#xff0c;甚至可以说做网站SEO的人都知道&#xff0c;流量其实可以理解为搜索词的争夺。谁占据了搜索词下的靠前位置&#xff0c;意味着高点击和高转化。经典的…

为什么加购可以让亚马逊关键词上首页?

其实关键词上首页的原理就是加购。通过加购&#xff0c;可以优化关键词的排名&#xff0c;配合测评能提高转化率&#xff0c;提高listing权重&#xff0c;使产品的排名更高&#xff0c;把最重要的位置给主推词&#xff0c;最大限度保证主推词的权重&#xff0c;后期重点推广关键…

亚马逊关键词在哪里找准确一点?

编写一条listing&#xff0c;最核心也是最关键的就是找到与这条listing最匹配的关键词。 第一&#xff1a;亚马逊搜索框的下拉框 第二&#xff1a;亚马逊后台广告报表下载的关键词 选取关键词报表中点击率及 转化率高的关键词&#xff0c;可以作为关键词素材使用。 第三&#x…

如何正确的进行亚马逊关键词研究

本篇文章将提供实用的亚马逊关键词方法以及如何改进关键词搜索结果。您必须采取以下三个步骤来为您的亚马逊列表收集关键词信息&#xff1a; 第 1 步&#xff1a;寻找您的种子关键词 首先卖家应该找到四到五个种子关键词&#xff0c;这些是能够描述您的产品是什么的主要短语。…

lazada按关键字搜索商品API接口

lazada按关键字搜索商品 API接口&#xff0c;在 lazada上搜索产品&#xff0c;如果只需要搜索单个产品的话&#xff0c;那么直接在搜索框输入“关键字”即可&#xff0c;如果需要多个产品&#xff0c;那么则需要进行关键字扩展。 lazada按关键字搜索商品 API接口分为两部分&am…

如何利用亚马逊关键词进行引流?权威关键词设置技巧来了

利用关键词获取流量是运营店铺至关重要的一步,那么亚马逊卖家怎样设置关键词才能更高效精准地引流呢?本期的亚马逊运营知识,船长BI将为大家分享关于亚马逊关键词的设置技巧。 在掌握关键词设置技巧之前,必须弄懂关键词的定义。 01、关键词的认知 关键词是代表产品的词组…

提高亚马逊关键词搜索排名的方法

亚马逊关键词搜索排名在首页是很重要的&#xff0c;因为客户都是通过关键词搜索产品&#xff0c;如果你的产品通过关键词搜索出来排在了后面几页&#xff0c;那么消费者基本上都不会去查看及购买&#xff0c;因此想要产品能被发现及购买&#xff0c;提高亚马逊关键词的搜索排名…

lazada按关键字搜索商品 API

为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个Lazada应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载 Lazada API的SDK并掌握基本的API基础知识和调用 4&#xff09;利…

亚马逊刷关键词软件——亚马逊鲲鹏系统

亚马逊刷关键词是为了让自己的产品关键词排名更靠前&#xff0c;这样可以吸引更多的客户来点击浏览&#xff0c;从而获取到更多的流量与销量&#xff0c;但是要进行刷关键词是一个比较重大的工程&#xff0c;需要大量不同的买家号来进行操作&#xff0c;这时候就可以借用软件来…

亚马逊关键词应该如何选择?

为什么在 2022 年研究亚马逊关键词仍然是一项有价值的活动 你会认为&#xff0c;到目前为止&#xff0c;所有可能的产品细分市场都将在亚马逊上以某种形式或形式覆盖&#xff0c;但现实是&#xff0c;在这个庞大的生态系统中&#xff0c;亚马逊的产品一直在发生变化。 此外&am…

亚马逊关键词上首页怎么操作?

亚马逊关键词如果排在首页可以获得更多曝光&#xff0c;产品被购买的几率也更大。但是上首页也不是那么简单的&#xff0c;亚马逊关键词上首页怎么操作&#xff1f;操作上首页也是需要有规划的。 第一阶段 规划好想要刷的关键词&#xff0c;比如用什么样的长尾词购买刷单&…

亚马逊/关键词搜索挑战

亚马逊在全球有众多站点&#xff08;14个&#xff09;&#xff0c;在爬取搜索页面时&#xff0c;存在较多的挑战。为了方便大家沟通学习&#xff0c;现将我们在研发过程中的问题一一列举。对于具体的技术细节&#xff0c;可参考之前的文章亚马逊 - 关键字搜索 - 广告排名 - Cit…

亚马逊关键词上首页的方法有哪些?

关键词上首页一般是指在某个核心关键词搜索条件下的首页48个结果内&#xff0c;自己的产品排在前10的位置。分为两种情况。第一种是广告上首页&#xff0c;通过自动广告积累一定的买家搜索词数据&#xff0c;然后针对出现频率和转化相对较高的核心关键词进行精准投放。 第二种是…

亚马逊如何获得关键词

&#xff08;1&#xff09;从竞品中获取关键词 找到BSR排名靠前竞争对手的ASIN&#xff0c;从而通过排名页面或关键词搜索找到它们&#xff1b; 用与5个ASIN匹配的Amazon所有关键字&#xff1b; 查找具备以上ASIN同时转化率高的关键词&#xff1b;通过以上方法&#xff0c;你…

亚马逊运营人才必懂:亚马逊搜索词和关键词

即使是对亚马逊seo有一定经验的卖家有时也会混淆搜索词和关键IC的概念&#xff0c;两者都对seo有帮助&#xff0c;但是作用不同。下面海熹跨境人才网就来给大家详细介绍一下亚马逊搜索词和关键词&#xff0c;一起来了解一下吧。 I. 什么是亚马逊搜索词? 亚马逊搜索词(Search …

系统U盘制作随记

随身系统U盘制作 最近花了好多时间&#xff0c;废了好多U盘才把这东西搞明白了。 主要是自己的笔记本问题比较多&#xff0c;用实验室的Hp机一下就弄好了。 用这篇博客总结一下自己&#xff0c;然后附上详细的流程以免大家踩坑。 Windows to Go 这个比较容易上手 1. 准备…

软件版本号说明

1.版本命名规范 软件版本号有四部分组成&#xff0c;第一部分为主版本号&#xff0c;第二部分为次版本号&#xff0c;第三部分为修订版本号&#xff0c;第四部分为日期版本号加希腊字母版本号&#xff0c;希腊字母版本号共有五种&#xff0c;分别为base、alpha、beta 、RC 、 …