当前位置:首页 > 综合

360浏览器网页验证码识别扩展

去年帮一个做数据采集的浏览朋友看项目,他打开浏览器,器网满屏都是页验“请输入验证码”的弹窗。他苦笑着说,证码每天人工点几千次,识别手指都快废了。扩展我当时就问他,浏览为什么不写个扩展自动填?器网他愣了一下——原来很多人不知道,360浏览器是页验支持Chrome扩展的,而验证码识别这件事,证码在扩展层面完全可以自己搞定。识别

360浏览器极速模式用的扩展是Chromium内核,版本号通常落后Chrome几个大版本,浏览但扩展API兼容性相当好。器网这意味着你不需要去研究什么私有接口,页验直接按Chrome扩展的标准来写就行。manifest.json里声明content_scripts,匹配目标网页,注入一段JS,剩下的就是怎么把验证码图片抠出来、发给识别服务、再把结果填回输入框。

难点不在扩展本身,在验证码图片的获取。有些网站把验证码渲染在canvas上,有些是img标签直接加载,还有些用CSS background-image。我遇到过最麻烦的一种,是图片被切成了四块,通过四个div拼在一起。这种就得用html2canvas把整个区域截图,再转成base64。扩展的content script里没有直接访问canvas像素的权限,如果图片跨域的话。解决办法是发消息给background脚本,在那边用fetch拿到图片数据,绕开跨域限制。

识别环节我试过三种方案。最省事的是接第三方打码平台,比如超级鹰、若快,传base64过去,返回文本。价格大概是一千次几块钱,准确率看验证码复杂度。第二种是本地跑一个轻量级CNN模型,用Tesseract.js做OCR,但纯数字字母的简单验证码还行,带干扰线的就废了。第三种是调用百度OCR的通用文字识别接口,免费额度够个人用,准确率比Tesseract高不少,但需要注册开发者账号。

实际写代码的时候,有个细节容易被忽略:验证码输入框通常绑定了input事件监听。你直接改value,有些网站检测不到,提交时还是提示验证码错误。得手动触发一下事件。我一般用这段:

let input = document.querySelector('#captcha-input'); let nativeInputValueSetter = Object.getOwnPropertyDescriptor( window.HTMLInputElement.prototype, 'value' ).set; nativeInputValueSetter.call(input, recognizedText); input.dispatchEvent(new Event('input', {  bubbles: true })); 

另外,别想着一个扩展通吃所有网站。每个网站的验证码刷新逻辑、输入框ID、提交按钮的触发方式都不一样。我现在的做法是写一个通用框架,把网站特定的适配代码放在一个config对象里,用URL匹配来加载对应的规则。这样新增一个网站,只需要加几行配置。

有个做抢票的朋友用这套方案,把验证码识别时间压到了300毫秒以内。他的做法是把识别服务部署在本地,用Flask起一个HTTP接口,扩展直接请求localhost。这样没有网络延迟,也不依赖第三方平台的稳定性。当然,验证码图片得先传到本地服务,这步走的是background脚本,速度很快。

最后说个坑。360浏览器有个安全机制,扩展在隐私模式下默认不启用。如果你需要在无痕窗口里跑验证码识别,得去扩展管理页面手动勾选“在隐私模式下允许”。这个选项藏得比较深,在扩展详情页的“详细信息”里。我当初找了半天,还以为是代码写错了。

整套东西写下来,核心代码不到两百行。真正花时间的是适配不同网站的验证码结构,以及处理各种奇葩的输入框事件绑定。如果你只是自己用,找个现成的打码平台,半天就能跑通。想做得稳,就得一个个网站去磨。

分享到: