從零開始打造乙個12306驗證碼識別系統

2021-10-05 19:45:54 字數 2365 閱讀 9300

12306驗證碼從簡單的數字驗證碼進化到圖形識別驗證碼,成功攔住了需要購票的民眾,但並沒有攔住機器,今天我們用一篇文章講解如何從零開始設計並實現一套12306驗證碼識別系統,所有思路已成功實現並達到一張驗證碼300ms內識別完成並到12306**驗證通過。

12306包含以下兩種:

包含兩個問題的驗證碼:

包含乙個問題的驗證碼:

中的資訊包含兩個部分,一部分是第一行的問題,如剪紙、話梅、棉棒等,另一部分是下半部分的,其中包含八張,其中每一張必定屬於乙個問題,且至少乙個問題是第一行的問題,為了能夠做到自動識別,需要做到,

當我們能使用機器做到上面的三個步驟時我們就能做到自動識別驗證碼了。

通過觀察發現每一張驗證碼的 下圖中所有的 這部分文字都是一樣的,它的長度也是一樣的,所以我們可以使用**將前面公共部分去掉,只留下後面的問題部分(通過畫素操作保留後面的問題部分生成一張新的)

因為驗證碼中的問題可能是1個,也可能是2個,所以我們需要能夠識別出問題的個數(兩個問題的問題部分背景一般是白色的,該張是12306識別到我請求次數頻繁後返回的,所以我們處理背景是白色的就可以),通過觀察我們發現兩個問題相隔有一片空白部分,而且乙個問題的多個字之間相隔比較緊密,所以我們可以通過畫素(白色)探測來確定該是包含兩個問題還是乙個問題,假設使用乙個橫線從上到下,當該條線上存在非白色畫素且中間包含白色畫素(可以指定寬度)且向下移動時時白色畫素連續則說明該驗證碼包含兩個問題,我們可以選擇非白色畫素中間的白色畫素的某一條線作為分離依據(一般選擇中間連續白色畫素的中點),將問題分離生成兩個問題;如果探測時沒有包含這種情況則說明該驗證碼只有乙個問題。

當我們拿到只包含問題的後就可以去識別上面的漢字了,可以選擇光學識別,也可以選擇使用機器學習技術來識別漢字,在實際操作過程中發現光學識別不能很好的識別出漢字,因為12306返回的上的漢字有各種奇形怪狀且相連比較緊密,我使用的是機器學習的方式,通過對一批進行標註後使用機器學習生成模型(可能需要比較多的標註,我選擇的是第三方打碼平台,把傳到平台,平台返回上面的漢字,機器學習參考文章

),當標註比較多且型別比較全時能達到99%的準確率。

我們拿到驗證碼的問題後需要知道下半部分的哪些圖形屬於該問題,所以需要先將下半部分的多個圖形分離成只包含乙個圖形的單張,通過觀察發現每張的的大小都一樣,所以通過計算出每個座標後使用硬編碼的方式分離出,推薦使用windows自帶的工具檢視畫素座標。

如果我們剛開始可能沒有任何一張的分類資料,這時我們依然可以選擇第三方打碼平台進行標註積累原始資料,當我們已經有了一批資料積累後可以選擇答案探測方式,這裡有乙個比較關鍵的點是如何確定兩張是同一張,也就是拿到一張後如何從我們的已有資料裡尋找這張並拿到它的分類,推薦使用phash演算法,該演算法將一張轉換為50位的0、1字串,如何通過計算兩張生成的字串的漢明距離來確定兩張的相似度(因為場景比較特殊,可以將距離值設為3,大於3則不是一張),使用這種方式時推薦使用elasticsearch將索引,搜尋時使用字元匹配搜尋方式(設定最小匹配數為47)進行搜尋來尋找相同,也可以直接對進行md5,當兩張的md5一樣時則是同一張(這種方式需要在進行分離時保證這張在的不同位置時分離出的的md5一樣),使用這種方式時則可以直接資料庫進行儲存和查詢,非常方便。

確定每乙個圖形的分類後即可與問題進行對比,選擇分類一樣的圖形並使用該圖形在中的座標生成答案,使用該答案呼叫12306的驗證介面進行驗證,如果通過則可以直接登入或時提交購票請求,否則重試即可。

每乙個圖形都有確定的分類可能是比較理想的情況,更多可能其中乙個或多個圖形屬於未知分類,甚至所有圖形都屬於未知分類,這裡可以使用推測法,基於已知圖形分類和未知圖形分類生成所有推測的答案,並將這些答案列表與該驗證碼關聯(將完整的驗證碼以及特徵儲存到資料,方便下次遇到同一張時查詢),然後從推測的答案列表中選擇乙個答案到12306進行驗證,當驗證不通過時拋棄該答案,等待下次遇到相同時再從剩餘答案中選擇乙個答案,直到乙個答案成功。當拿到乙個成功答案時可以將不屬於答案的圖形進行標記,標記該圖形肯定不屬於這張驗證碼的問題(乙個分類或兩個分類),同時將作為答案的圖形進行標記(如果問題是乙個分類時該圖形分類已確定,否則將該圖形標記可能是這兩個分類,或者基於已有的可能標記直接確定圖形分類),下次其它生成推測答案時可以參考該標記,生成更少的推測答案列表,甚至直接生成正確答案,這樣我們可以定時請求12306驗證碼介面進行圖形分類學習,如果所有圖形分類都已確定則我們的庫能做到不用進行驗證碼重試,因為12306定期放出新圖形,這要求我們需要不斷進行學習。

按照以上步驟實現的12306驗證碼識別程式真實可用,現在還能想起那些徹夜寫**的夜晚。

IntelliJ IDEA 從零開始建立乙個專案

1 如果intellij idea中當前沒有開啟的專案,單擊歡迎介面上的建立新專案。否則,選擇 然後會開啟新建專案嚮導視窗 2 在嚮導的第一頁,在左側窗格中,選擇專案類別。這可能是你要使用的技術,專案的目標平台或執行時等。在頁面的右側部分以及後續步驟中的設定取決於所選專案類別。對於相應的說明,請參閱...

IntelliJ IDEA 從零開始建立乙個專案

1 如果intellij idea中當前沒有開啟的專案,單擊歡迎介面上的建立新專案。否則,選擇 然後會開啟新建專案嚮導視窗 2 在嚮導的第一頁,在左側窗格中,選擇專案類別。這可能是你要使用的技術,專案的目標平台或執行時等。在頁面的右側部分以及後續步驟中的設定取決於所選專案類別。對於相應的說明,請參閱...

IntelliJ IDEA 從零開始建立乙個專案

1 如果intellij idea中當前沒有開啟的專案,單擊歡迎介面上的建立新專案。否則,選擇 然後會開啟新建專案嚮導視窗 2 在嚮導的第一頁,在左側窗格中,選擇專案類別。這可能是你要使用的技術,專案的目標平台或執行時等。在頁面的右側部分以及後續步驟中的設定取決於所選專案類別。對於相應的說明,請參閱...