K-業務ポータルをクロールできるだろうか?

힘센캥거루
2025년 5월 28일(수정됨)
3
54

最近、K-業務ポータルが公文書のタイトルを3か月単位で区切って表示しているのを見て、こんな考えをしてみた。

もしクロールで公文書のタイトルをすべて集めて3年間分をエクセルで作っておいたら?

filterを利用して簡単に公文書番号を検索できると思った。

結論から言うと不可能だった。

K-業務ポータルをクロールできるだろうか?-1

1. 誰でも計画はある。

私の壮大な計画はこうだった。

1. pythonのseleniumで業務ポータルにアクセスしログインする。
2. xpathを利用してtableタグ内のtrとtdを収集し、データフレームにする。
3. datetimeとdeltaを利用して日付を計算し、3か月単位で区切って公文書をすべて収集する。
4. エクセル、またはGoogleスプレッドシートに入れて適切に利用する。

しかし実際に業務ポータルに入ってみたところ、tableどころかiframeも見つけられなかった。

4時間も無駄にしながらクロールが不可能な理由を一度書いてみる。

2. 君のセキュリティは?

1. WebDRM

K-業務ポータルをクロールできるだろうか?-2

最初の障壁はWebDRMだった。

これのせいで開発者モードを開くこともできなかった。

しかし開発者モードが既に開いていると、そのサイトに接続しても維持されるという点を利用してみた。

結局開発者モードを開くことに成功した。

2. ブラウザには見えるのに要素がないって?

この部分が最も理解できなかった。

確かに開発者モードでは要素がはっきり見えるのに、クロムドライバーでpage_sourceをすると要素が一つも出てこなかった。

それはseleniumを使おうが、puppeteerを使おうが同じだった。

さらに不思議なのは、コンソール内でのJavaScriptを使っても見えないということだ。

見えるのに見つからない、そんなもどかしさが私をさらに狂わせた。

const puppeteer = require('puppeteer');
const fs = require('fs');
// puppeteerを使用してウェブページのHTMLを取得するスクリプト

(async () => {
  let browser;
  try {
    browser = await puppeteer.launch({
      headless: false,
      args: ['--no-sandbox', '--disable-setuid-sandbox'],
      defaultViewport: null,
      userDataDir: './user_data',
    });

    const page = await browser.newPage();

    await page.goto('https://klef.goe.go.kr/keris_ui/main.do', {
      waitUntil: 'networkidle0', // すべてのリソース読み込み待ち
      timeout: 60000, // 最大60秒待機
    });

    const html = await page.content();
    fs.writeFileSync('schoolDoc.html', html, 'utf8');
    console.log('HTMLファイルがschoolDoc.htmlとして保存されました。');

  } catch (error) {
    console.error('エラー発生:', error);
  } finally {
    if (browser) await browser.close();
  }
})();

こうして保存したファイルを再び開いてみると、以下のような姿が見えた。

私が欲しかったテーブルは出ず、ログインモジュールが表示された。

K-業務ポータルをクロールできるだろうか?-3

なぜだろうと思い考えてみると、公文書を表示するテーブル自体が別のインストール型プログラムではないかと思った。

そう考えると少し楽に諦めることができた。

3. 業務ポータルはWebソケットを使用している。

まず業務ポータルは一般的なREST APIを通じてデータを送信するのではなく、websocketを利用してユーザーとデータをやり取りする。

この点が非常に興味深かった。

K-業務ポータルをクロールできるだろうか?-4

それでrequestsのような他のライブラリでクッキーをコピーし新しい接続を試みようとしても、websocketのハンドシェイクプロセスとセッション維持方式のため不可能だった。

しかしここで挫折することはできなかった。

selenium-wireを利用してwebsocketを通わる要求と応答を見てみることにした。

# 要求を巡回
for request in driver.requests:
    if request.response:
        content_type = request.response.headers.get('Content-Type', '')
        if content_type.startswith('application/json'):
            print("== 要求URL:", request.url)
            try:
                body = request.response.body.decode('utf-8', errors='ignore')
                print("== 応答内容:", body)
            except Exception as e:
                print("== デコードエラー:", e)

driver.quit()

そしてbase64でエンコードされたようなアルファベットが出てきた。

これを再びデコードしたが規格に合わず失敗。

ここで私は入るのをやめることに決めた。

3. 感じたこと

公共機関のサイトの速度が遅いことに不満を感じていたが、今回掘り下げてみるとそれでもセキュリティだけはしっかりしているようだと感じた。

遠隔でデータ一つ得るのも簡単ではなく、たくさん学ばせてもらった。

しかし次回も挑戦してみたくなる。

K-業務ポータルをクロールできるだろうか?-5

관련 글

学校業務の自動化 - AIを利用した生活記録簿チェック 教科別・特別記述編
学校業務の自動化 - AIを利用した生活記録簿チェック 教科別・特別記述編
学校で最も意味がなく、きつくて退屈な業務を一つ挙げろと言われたら、自分は生活記録簿(生徒指導要録)チェックを選ぶだろう。中学校では生活記録簿がそれほど重要ではないが、高等学校では入試と関係しているため非常に重要である。問題は、このような生活記録簿の点検で探すものが、せいぜい単純な誤字脱字、記載禁止用...
ゼロから作りながら学ぶ LLM 第7章 読書レビューとチャレンジの感想
ゼロから作りながら学ぶ LLM 第7章 読書レビューとチャレンジの感想
第7章の内容は、指示に従うように微調整するプロセスだ。ある質問に対して、期待する応答を返すようにすること。やはり必要なのはデータである。1. 指示微調整の手順ここでの要点は、質問と応答のデータセットを用意し、入力-出力のペアとして学習させること。これをプロンプトスタイルと呼ぶ。その他は以前のプロセス...
ゼロから作りながら学ぶ LLM 第6章 読書レビュー
ゼロから作りながら学ぶ LLM 第6章 読書レビュー
第6章は、分類のためのファインチューニングについてである。例として出てくるのは、スパム分類器の作成。スパム分類器は、あるメールなどがスパムかスパムでないかを分類するものなので、出力結果は 0 や 1 のような値になる必要がある。1. ファインチューニングの手順ファインチューニングのプロセスは、モデル...
ゼロから作りながら学ぶ LLM 第5章 読書レビュー
ゼロから作りながら学ぶ LLM 第5章 読書レビュー
今日は12月14日だ。実はチャレンジ期間はすでに2週間も過ぎてしまったが、だからといってレビューを書くのをあきらめることはできなかった。こうして残しておくTILが、あとで自分の血となり肉となるからだ。コードそのものよりも、その意味に集中して書いてみようと思う。1. モデルの損失計算GPTモデルを作っ...
ゼロから作りながら学ぶ LLM 第4章 読書レビュー
ゼロから作りながら学ぶ LLM 第4章 読書レビュー
今日は11月26日なので、毎日1章ずつ読み切ればチャレンジ成功だ。長男と次男の妨害の中で、それが可能かどうかは分からない。1. ダミー・トランスフォーマーGPTモデルを作りながら、PyTorchからトランスフォーマーのダミーブロックを持ってくる箇所を見た。調べてみると、PyTorch の nn の中...
ゼロから作りながら学ぶLLM第3章読書感想
ゼロから作りながら学ぶLLM第3章読書感想
MacBookに大量の水をこぼしてパニックになり、3〜4日無駄にした。今考えてみると、どうせMacBookは駄目になったし、修理に出すと思って何かをすればよかったと思う。とにかく少し遅れたけど、最後までやるべきだと思い、第3章の感想を残す。1. アテンションメカニズム3章...

댓글을 불러오는 중...