背景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打印出來了,能夠說是基本完成了需求。