上个月,朋友找我帮忙,说他在一个老旧论坛收藏了好多帖子,想让我写个小脚本,帮他批量下载下来,省得手动一个个存,太麻烦。
我当时拍胸脯答应了,心想这有啥难的?那网站看着破破烂烂的,连个像样的反爬都没有,唯一的要求就是登录的时候输个验证码。

我还美滋滋地想:不就是四位数字吗?分分钟搞定。结果点开验证码图片,我盯着屏幕看了足足五秒钟,直接懵了——数字是浅蓝色的,背景也是浅蓝波纹,中间还斜着划了好几道横线,模糊得不行。
我眯着眼睛猜了三次,才勉强输对。那一刻我突然反应过来:这玩意儿哪里是给人设计的?明明就是专门防机器的,连人都得靠蒙,更别说电脑了。
第一关:纯文字验证码,入门级送分题
最早的验证码,那是真的单纯,一点套路都没有。就是一张纯白背景,上面印几个黑体数字,没有任何干扰,清清楚楚。
识别它有多简单?用Python写个三五行代码,再调用个OCR(光学字符识别)库,比如Tesseract或者PaddleOCR,直接把图片丢进去,几秒钟就能把文字识别出来,准确率几乎能到100%。
可能有人会问,这种验证码现在还有?说实话,大多是一些老系统,懒得升级,凑合用的。毕竟这种验证码,相当于没装门,一个三行代码的爬虫,就能秒过,根本起不到防爬作用。
也正因为这样,网站很快就开始搞事情,各种干扰项就来了。
第二关:加噪点、搞扭曲,机器直接懵圈
这应该是现在最常见的一种验证码了。不再是干干净净的文字,而是加了各种“小捣乱”——比如像老旧电视机雪花点一样的椒盐噪点、乱七八遭的背景干扰线,有的还把文字弄扭曲、粘在一起。
对我们人类来说,稍微眯着眼看,大概90%都能认对,但对机器来说,直接歇菜,准确率一下就掉到60%以下,根本识别不准。
那该怎么破?其实思路很简单,就跟我们看书先擦干净书页一样,先把图片“洗干净”,再去识别,分三步来:
第一步,去噪。先把彩色图片转成黑白灰度图,然后做二值化——简单说就是设定一个标准,比这个标准亮的像素,全变成白色,暗的全变成黑色。那些孤立的小噪点,大多是小黑点,用形态学操作(比如开运算,不用记专业名词,知道能去噪就行)就能去掉。
第二步,分割。如果四个字符粘在一起,就用投影法切开:算一下图片每一列的黑点数量,字符之间肯定有空白,黑点少,就在空白的地方“下刀”,把每个字符分开。
第三步,识别。这时候再用OCR,或者自己简单训练一个小型的卷积神经网络(CNN),不用搞太复杂,准确率就能拉到85%以上。
我还记得第一次自己跑通这种带扭曲、带干扰线的验证码识别时,那种成就感,就好像——机器终于学会跟人一样,眯着眼睛看清楚字了。
第三关:滑动验证码,OCR彻底没用了
这一步,之前的纯文字识别、OCR,就彻底失效了。最典型的就是某电商平台的滑动拼图验证码:给你一张缺了一块的背景图,还有一个能拖动的滑块,你得把滑块精准拖到缺口的位置,才能通过。
这就不是识别文字了,而是识别位置,考验的是计算机视觉的能力,不是文字识别。
入门级的做法,也分三步,不难,跟着做就能上手:
首先,找图片。从网页源码里,把背景图和缺块图找出来。有些网站很直白,直接把两张图分开传;有些就比较鸡贼,把两张图拼在一起,再用CSS遮罩挡住一部分,这就需要你多看看网页源码,找到真实的图片地址。
然后,找位置。用OpenCV这个计算机视觉库,做模板匹配——把缺块图当成模板,在背景图上一点点滑动,找到相似度最高的地方,就能算出滑块需要移动的距离。
最后,模拟拖动。这一步很多新手都会忽略,也是最容易翻车的地方!如果你直接用脚本,一瞬间就把滑块从左边拖到目标位置,服务器一眼就知道你是机器,直接拦截。
正确的做法是,模拟真人的拖动轨迹:比如先加速,再减速,中间偶尔停顿一下,甚至稍微超过一点目标位置,再拉回来一点点。我试过一个最简单的办法,用随机函数生成一条加速曲线,前三分之一加速,后三分之二减速微调,虽然不完美,但对付一些中低安全级别的滑动验证,足够了。
第四关:点选、算术题,入门级最优解是“走捷径”
这是现在中小网站最常用的验证码,比滑动验证更灵活,也更难搞。比如给你一张杂乱的图片,让你按顺序点击图里的“红绿灯”“自行车”;或者给你一道简单的算术题,比如“3+8等于几”,让你输入答案。
对付这类验证码,入门级的思路,我劝你直接放弃自己搞识别——改用打码平台,这才是最省事、最划算的。
别不信,技术上你确实可以自己训练一个目标检测模型,专门找图里的“红绿灯”“自行车”,但成本太高了。一个普通的爬虫项目,总共也就赚几百块、上千块,你花两周时间调模型、训数据,纯属得不偿失。
不如花几分钱,调用一次打码平台的人工服务,或者用平台提供的API,让他们的AI帮你点一下、算一下,几分钟就能搞定,省时又省力。
这就是验证码识别的残酷真相:越往后走,你花的技术成本,和你能拿到的收益,差距就越大,没必要死磕。
第五关:无感验证,入门爬虫直接“认输”
现在最高级的验证码,就是无感验证,比如Google的reCAPTCHA v3,你连验证码的影子都看不到。
它在你浏览网页的时候,就默默在后台分析你——你的鼠标轨迹、点击习惯、页面滚动速度,甚至你的浏览器指纹,然后用一套机器学习模型,给你打个分,判断你是人还是机器。
遇到这种验证码,入门级的爬虫,基本可以直接放弃了。唯一的办法,就是拼尽全力模拟真人行为:用Selenium或者Puppeteer写完整的操作脚本,加随机延时,让鼠标移动的轨迹像真人(比如用贝塞尔曲线),偶尔加个误点击、回退操作,假装自己手滑。
但即便你做到这样,被识别出来的概率依然很高,毕竟机器分析的维度太多了,我们很难完全模拟真人的所有行为。
写给新手的三条实在建议,少走弯路
最后,结合我自己踩过的坑,给大家三条入门建议,都是实在话,照着做,能少走很多弯路:
第一,从最简单的开始,别好高骛远。如果目标网站的验证码,只是纯数字加一点点干扰,先试试OCR,别一上来就搞深度学习、训练模型,杀鸡不用牛刀,简单的方法能解决问题,就别复杂化。
第二,算清楚时间账,别死磕。花一天时间,调试滑动验证码的拖动轨迹,是值得的;但花一周时间,训练一个点选模型,就不如直接对接打码平台。你的时间,比那几分钱的打码费贵多了,别捡了芝麻丢了西瓜。
第三,守住法律和道德的底线。记住,验证码存在的意义,是保护网站和真实用户的安全。破解它,不代表你可以去干刷单、抢票、撞库这些违规违法的事。技术本身是中性的,但用技术的人,得有底线。
回到开头那个老旧论坛——最后我并没有写复杂的识别代码。因为我发现,网站有个“看不清楚?换一张”的功能,我直接在爬虫里写了个循环,让它每识别失败一次,就自动刷新一次验证码,直到刷出一张清晰、OCR能直接识别的图。
有时候啊,解决问题的最好办法,不是硬刚,而是绕过去——绕过问题,比死磕问题,更聪明。
