この文は Mix Space によって xLog に同期更新されています
最適なブラウジング体験を得るために、元のリンクを訪問することをお勧めします
https://www.do1e.cn/posts/deepl/nju-captcha
前言#
以前書いた NJUlogin では、アカウントとパスワードでログインする際に CAPTCHA 認識が必要でした。その際、ddddocr を使用し、良好な精度を得ました。
また、サーバーをデプロイし、友人 に手伝ってもらい、Tampermonkey スクリプトを作成してもらい、毎回ログインが必要なときに自動的に CAPTCHA を入力できるようにしました(アカウントとパスワードはブラウザが自動入力します)。そのため、ログインをクリックするだけで済みます。
しかし最近、認識モデルをより軽量にして、エッジデバイスへのデプロイを便利にしたいと考え、このプロジェクトが生まれました。(スターを求む >︿<、もし技術に関心がなく、ただ使用したいだけなら、最後までスクロールして、NJU サーバー API バージョンをお勧めします)
Github Repo not found
The embedded github repo could not be found…

データ収集#
https://github.com/Do1e/NJUcaptcha/tree/main/build_dataset
データセットの構築は基本的に自動化されており、主に以下の 2 つのツールに依存しています:
少し改造した NJUlogin で認識の正否を判断し、それぞれ異なるフォルダーに保存しました。認識エラー(おそらく数百枚?)は手動で名前を変更すれば大丈夫です。
収集者のために 100,000 枚の画像を集めるために、バックグラウンドで約 3〜4 日間実行しました。time.sleep はあまり小さくできず、そうしないと IP が封鎖されます。 >︿<
その結果、このデータセットができました。ダウンロードして使用することを歓迎します。100,000 枚の CAPTCHA 画像が含まれており、ファイル名の形式は {CAPTCHA テキスト}_{画像md5}.jpg で、CAPTCHA テキストはすべて小文字です。
データセットのダウンロードリンク:NJU-captcha-dataset.7z
解凍パスワード:@Do1e
データセットは以下の通りです:
https://github.com/Do1e/NJUcaptcha/blob/main/model/dataset.py
認識モデル#
https://github.com/Do1e/NJUcaptcha/tree/main/model
データが揃ったので、モデルを設計してトレーニングを行うことができます。モデル設計は今回完全に AI に任せましたが、結果もまずまずです。
モデルサイズ 12.98MiB -> 2.25MiB
モデル精度 99.37% -> 99.83%
スループット 173.95 images/sec -> 1076.56 images/sec [AMD Ryzen 7 8845H]
https://github.com/Do1e/NJUcaptcha/blob/main/model/model.py
もう少し小さくできるかもしれません?次回のアップグレードに取っておきましょう
サーバーのデプロイ#
https://github.com/Do1e/NJUcaptcha/tree/main/service
以前、fastapi を使用して簡単な認識サーバーを実装し、受信した base64 画像を認識して CAPTCHA の内容を返すことができました。今回はオープンソースの機会を利用して vercel にデプロイしました。Linux でのテストコマンド:
curl -s -L "https://authserver.nju.edu.cn/authserver/captcha.html" -o "captcha.jpg" && [ -f "captcha.jpg" ] && curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "captcha=$(base64 -i captcha.jpg | tr -d '\n')" "https://njucaptcha.vercel.app" || { echo "CAPTCHA 画像のダウンロードに失敗しました"; exit 1; }
Tampermonkey スクリプトの自動入力#
前言で述べたように、ログイン時に手動で認識して CAPTCHA を入力しないように、Tampermonkey スクリプトを作成しました。以前のバージョンはサーバーに基づいていました:
https://github.com/Do1e/NJUcaptcha/blob/main/njucaptcha.user.js
オープンソースコードでは依然として vercel のサービスを使用しており、速度が非常に遅く、p.nju にログインする必要がある場合には機能しません。 ( ̄﹃ ̄)
私の解決策は、校内にサービスを構築し、frp を使用して私のパブリックサーバーにマッピングし、p.nju にログインする際に内部ネットワークサービスにアクセスすることです:
const url_pub = 'https://example.com/';
const url_nju = 'https://nju.example.com/';
const currentUrl = window.location.href;
const serverUrl = currentUrl.includes('//p.nju.edu.cn') ? url_nju : url_pub;
今回のプロジェクトで最も難しいのは、クライアント側で onnx の推論を直接実行する方法でした。AI ツールを使って数時間試行錯誤した結果、成功しました。 ONNX Runtime Web を使用して実現しました。
https://github.com/Do1e/NJUcaptcha/blob/main/njucaptcha_onnx.user.js
onnx バージョンの欠点は、キャッシュがない場合にインターネットに接続し、必要な推論依存関係をダウンロードする必要があることですが、初回使用後はキャッシュされます(ort-wasm-simd-threaded.jsep.mjs と ort-wasm-simd-threaded.jsep.wasm は 7 日間しかキャッシュできず、それほど長くはありません。もし大御所が @resource のようなほぼ永久的なキャッシュを実現する方法を知っていたら、PR を提出してください)。
とにかく、上記の 2 つのソリューションにはそれぞれ利点と欠点があります。最もお勧めするのは、私の方法で自分でデプロイして使用するか、または文末に記載した NJU サーバー API バージョンを直接使用することです。
上記バージョンの Tampermonkey スクリプトは、以下のリンクをクリックすることで直接インストールできます(Tampermonkey プラグインがインストールされている前提で):
| | vercel API バージョン | NJU サーバー API バージョン | onnx ローカル推論バージョン |
| :--- | :--- | :--- |
| 利点 | 科学的なインターネット接続が不要 | ベストプラクティス、個人的には非常に完璧だと思います | 非常に速く、ページが読み込まれる前にすでに入力が完了し、p.nju にログインする際にも使用できる(キャッシュがある前提で) |
| 欠点 | 非常に遅く、p.nju にログインする際には使用できない | 校内外のサーバーをデプロイする必要があり、卒業後は使用できなくなる | キャッシュがない場合、科学的なインターネット接続が必要で、一部のファイルをキャッシュすることができず、p.nju にログインする際には使用できず、キャッシュは 7 日間のみ |
注:今回のコードは GPL-3.0 オープンソースライセンスの下で提供されています。以下のオープンソースライセンスに関する説明は無視してください。ウェブページのコードを変更するのが面倒なので、私のウェブサイトの説明権は私にありますよね