上一课带大家聊了聊反爬与反反爬最基础的对抗-代理ip,别看这个简单,真正处理好了代理ip基本上解决大半的爬虫问题,包括本节的验证码。很多网站弹出验证码也是因为发现ip重复过多,比如搜狗微信搜索,如果在合理的时间切换ip,就可以完美的躲避掉搜狗微信中的验证码(注意只有搜狗微信中的验证码可以,微信中的是不可以的,其中区别可以通过浏览器中的域名来区分)。
上一篇文章写完之后,爬虫天坑的文章意外收获了不少赞,这里拜谢大家支持,同时如果天坑系列破百赞的话,我会继续更新那个系列。
要完了赞,扯完了废话,我们赶紧进入这一篇文章的正题-验证码识别。
先让我来摘抄一段验证码的介绍:
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
话说直到今天我才知道CAPTCHA原来是这么直白的英文缩写,外国人对单词的缩写狂热真是一点不比国人差啊。(突然想到刚进公司那会摸不着头脑的TGIF)
那好了,延续上篇文章的套路,我们先来看看反爬:
一.为什么验证码可以反爬?
简单来说,是人类有着一种天赋,可以很轻松的从一段图片中识别出文字和数字,而机器却不能。但是由于这些年机器学习的飞速进展。这项技能上人类和机器之间的差距越来越小,导致为了区分人和机器,人类工程师已经快达到变态的地步,终于诞生了宇宙无敌12306验证码:
当然这些年同样随着机器学习技术的飞速进展,验证码也开始出现了新的形式,比如极验验证为代表的轨迹模式,这类的优缺点我们后面再聊。
二.如何使用验证码实现反爬?
使用验证码相信是所有web工程师的基本功,百度谷歌上一搜一大堆,还有自动生成代码的。对于普通图文类的验证码,无非就是先生成随机串,再生成图片,将随机串存入session,等待用户提交后进行比对。或者也可以集成极验验证这类第三方验证服务,这里就不再赘述了。
使用验证码都会使用,那我们这里着重讲一讲到底该如何选择,这些常用验证码形式利弊各有哪些:
1.数字字母验证码:这类验证码优点是生成简单,大部分语言都自带图形库,在加入一点扭曲和噪点,基本可以解决掉初级爬虫工程师和暴力破解的脚本小子。缺点当然也显而易见,对于cnn代码只用写10行的今天,这些验证码只要有足够的标注数据,破解起来简直是轻而易举。我们在微信验证码识别中大约使用了10万张标注好的图片进行训练就可以完成类似人的准确度,具体可以参考我们的应用-微信文章爬虫[按公众号或关键字]-神箭手云
2.中文验证码:比如知乎采用过的验证码选择倒立的中文以及网易邮箱类的验证码(标记文字位置)。这类验证码一般来很少有公用的代码,因此编写起来麻烦。不过也正因为每一家采用的都不一样,在加上中文庞大的汉字库,确实给机器识别带来的比较大的挑战,如果配合好字体和扭曲,确实可以有不错的效果。
3.极验验证:这几年新型的验证码代表,很多网站争相采用。首先抛开技术角度,仅从成本角度来说,我是不太推荐大家用这类验证码的,越广泛的越不宜使用。对于一个网站特有的验证码体系,破解难度大,收益小。但这么多网站采用同一种验证码,即使破解难度再大,也必然有人会去尝试,因为收益太大。
反过来说说极验采用的技术,极验的v2版验证体系破解难度甚至比不过数字字母验证码来的复杂,唯一的优势就是现在大部分打码平台不支持。图片识别上直接对比像素就可以识别位置,唯一难点的移动轨迹,但用轨迹做分类人类和机器间的特征并不那么明显,加上网页中采集轨迹的准确性较差,因此做一些简单的模拟就可以轻松躲过轨迹识别。网上有很多破解方案。
当然验证码还有很多类型,比如12306这类,整体来说,如果对反爬要求很高,最好是自己实现,如果没有12306这种庞大的图片库,比较推荐的就是采用中文验证码模式(不是直接识别中文,而是标记中文位置类型的)。不太推荐采用极验验证这种,毕竟太多人使用意味着就像把自己的船和别人的船都连在一起,虽然稳定,但是一把火烧过来,大家全部遭殃。更不推荐采用数字+字母模式,这种实在烂大街,打码平台一分钱一次,包括算术类,麻烦自己,也没有提高太多识别门槛。
三.如何识别验证码?
识别验证码也一直是爬虫工程师的基本功,特别对于有登录需求的爬虫来说,验证码也是一道绕不过去的坎,那我们从反反爬的角度,来看看识别验证码的常用姿势。
1.打码平台:最常用,最简单的识别,唯一的难度就在于选择集成(也是一些工程性的东西),一般字母文字1分一次,中文识别略贵,计算题可能5分吧。具体大家可以去搜一搜,这里不赘述了。不支持极验这类。
2.OCR库:这个嘛,虽然换汤不换药,但是这个词听起来就显得灰尘味很重,另外,传统的ocr采用先切割再识别的方案,对于新型的验证码已经很难做了,不建议大家尝试这个方案。
3.机器学习:端到端数字字母识别神器,具体方案我在爬虫天坑系列-百度指数爬虫 这篇文章中已经有所介绍,根据识别难度和长度不同,对标注数据的需求量不一样,当然图片预处理也稍微有些区别,其他的,直接从网上找代码贴进来跑就好。(插个广告,神箭手平台支持直接运行tensorflow代码,并且自动生成serving接口)
4.神箭手库:我们内置了solveCaptcha和solveGeetest两个函数,对于部分验证码还是免费的,大家自己体会一下。
5.其他:之所以列一个其他,对于一些特殊验证码,比如12306不仅需要识别结果,还需要识别问题等等特殊的。单个问题单个对待,可能需要结合多重知识,这里就不展开讲了。
好了,最后说两句:验证码这篇一方面给大家提供了一个验证码类型的选择方案,同时也展示了识别验证码的难易和常见方法。事实上,很多时候,优秀的工程师并不是写代码写的最快的,而是遇到一个问题就知道哪个方案是最合适的。不断积累这种经验,让我们在工作中事半功倍。
有话要说