背景node
最近在写一个爬虫的小工具,卡在登陆这里。git
想爬的网站须要登陆才能获取数据,登陆又须要输入验证码。github
好在验证码是简单的验证码,还能够本身识别试试。npm
需求分析浏览器
一、保存验证码图片cookie
二、识别验证码app
三、对识别的验证码进行人工校准工具
功能实现网站
一、保存验证码图片url
虽然每一个网站不必定同样,可是大致的思路是差很少的,我要爬取的网站是后台返回了一个验证码图片和cookie,因此咱们须要把这两个东西都存下来。
这里用到了node中的request模块,具体没什么好说的,请求后获取response中的set-cookie,而后再把图片流存下来。request文档
let cookie = "";
let options = { url: "" headers: { Accept: "*/*", "Accept-Encoding": "utf-8", "Accept-Language": "zh-CN,zh;q=0.8", Connection: "keep-alive",'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36',//假装浏览器 }, method: 'GET', }; let stream = fs.createWriteStream("./code.jpg"); request(options, function (error, response) { cookie = response.headers["set-cookie"]; }).pipe(stream).on('close', function () { console.log(cookie); });
二、识别验证码
识别验证码须要用到两个工具一个是GraphicsMagick,另外一个是tesseract-ocr。
2.1 安装工具
在找资料的时候看到不少博客都只写了node安装他们的wrapper工具,都没有写清楚,实际上这两个工具咱们都要自行安装,安装包网上找就ok。
GraphicsMagick安装完后须要修改环境变量,在path中添加安装目录的地址,好比我安装在D盘,就添加D盘的路径。
须要注意的是,小写的分号 ; 不要忘记了
完成后输入在命令行输入gm,能出现以下信息就说明安装好了
tesseract-ocr安装完后也须要修改环境变量,操做和GraphicsMagick同样,而后须要多添加一个环境变量TESSDATA_PREFIX,变量值是你安装目录下的tessdata
完成后输入在命令行输入tesseract,能出现以下信息就说明安装好了
2.2安装node下的wrapper工具
GraphicsMagick 安装gm,安装命令是
npm install gm
tesseract-ocr安装tesseractocr,安装命令是
npm install tesseractocr
须要注意的是:找资料的时候发现不少人安装的都是node-tesseract,我在使用的时候一直报-psm这个选项错误,后来去github仓库上面找issue,发现也有人遇到这个问题,缘由是咱们安装的tesseract是最新的,-psm这个选项已经改为了--psm,因此一直报错。找了一圈也没找到解决办法,因此只好换个包来用。因而在npm的仓库里面找到了tesseractocr这个包。
他的Last publish是一年前,因此就拿来试一试,果真能用。毕竟node-tesseract是5 years ago。。。。
2.3 处理图片为阈值图片
用threshold方法来处理图片,文档的解释是:
Modify the image such that any pixel sample with an intensity value greater than the threshold is assigned the maximum intensity (white), or otherwise is assigned the minimum intensity (black).
说白了就是把图片处理成黑白的,去掉一些噪点线条,由于有噪点线条存在的话,tesseract的识别率会很低,而后阈值默认是55,可是在个人图片上55的阈值丢失的信息太多,因此我就放大了一些。
这里我还用了resize把图片放大一些,由于我在实际操做时发现,不少次识别都报了empty page这个错误,查阅资料发现是因为图片分辨率过小致使的,因此就显式地放大了图片。
gm(imgPath) .threshold(thresholdVal || 160) .resize(200, 100) .write(newPath, (err) => { if (err) return reject(err); resolve(newPath); });
操做以后图片会从下面这样
变成这样
2.4 识别图片
直接调用tesseract来识别图片中的内容,最后将识别出来的内容去空
var recognizer = function (imgPath) { return new Promise((resolve, reject) => { recognize(imgPath, (err, text) => { if (err) throw err; else resolve(text.replace(/[\r\n\s]/gm, '')); }); }) };
三、对识别的验证码进行人工校准
没有训练过的tesseract其实识别率很低,因此要加一我的工校准的操做,让咱们输入的验证码准确率能高一些。
这里用了readline-sync模块得到用户的命令行输入。
recognizer() .then(text => { console.log(`识别结果:${text}`); code = text; let res = readlineSync.question('是否使用?: '); if (res.toLowerCase() === 'n') { code = readlineSync.question('请输入实际值?: '); } console.log(code); })
总结
看看最终效果
识别率虽然不高,可是也有识别正确的,而后也把登陆的部分cookie打印出来了,能够说是基本完成了需求。