この記事はAFTAC2019、25日目の記事です。AFTACについては藤岡さんのブログを参照してください。
1. 今回のまとめ
時間がない方のために、この記事の概要をここにまとめておきます。
スクレイピングとは、Webサイトから特定の情報をプログラムによって抜き出す技術のこと。
jsoupを用いて、スクレイピングを行った。
スクレイピングは上手く使うと有益だが、法律と利用規約を守らなければならない。
僕の大学は、学生同士では学籍番号や名前、最終ログイン時刻などの個人情報管理がガバガバ。
2. はじめに
また、お前か......と言われそうです。そして、例によって例のごとく、今回もJavaです。
なぜ、こんなにJavaの記事ばかりなのでしょうか......。まあ、話(記事)のネタになりやすいものといえば、クリエイティブ(?)に自分が作ったものを紹介することですからね......。
さて、今回の記事は、タイトルの通り、「Javaでスクレイピングした話」です。
スクレイピングとは、Wikipediaによると
「ウェブスクレイピングとは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラーあるいはウェブ・スパイダーとも呼ばれる。」
とあります。簡単に言えば、特定のWebサイトから特定の情報をプログラムによって抜き出す技術のことです。以前、このAFTAC2019で、「LINE Botをつくった話」という記事を書きました。この記事ではあまり言及しませんでしたが、例えば、「大阪府大阪市の注意報・警報一覧(Yahoo天気・災害)」というページから、現在発令中の注意報や警報がなんなのかを取得する、と言ったことです。
どうやって行うかということですが、(LINE Botの時も今回の記事の時も)僕が採った手法は、リクエストを送信しソースコードを得て、それを解析することで行っています。ブラウザで適当なページを開き、「Ctrl+U」を押すか、URLの前に「view-source:」をつけると表示される(iOSではできないらしいです)、Webページの内容を指定した文字情報がソースコードです。これを取得し、プログラムによって必要な部分だけ抜き出します。
ところで、話は飛びますが、うちの大学にはいわゆるeポートフォリオ、つまり授業の課題や振り返り、学習目標などを自己評価したり保存しておける、WEBシステムがあります。そのページを見ていたところ、僕は「活動内容」という全生徒がどれだけ課題を提出しているのか、最終ログイン時刻はいつか、などが分かる恐怖の(?)ページを見つけました。以下の画像のようなページが119ページに渡って存在しています。

と、いってもログイン後のページにリンクが貼られているので、非公開情報では無いのだとおもいます。
とまあ、個人情報ガバガバなうちの大学ですが、このページを見たときに、(全学生の学籍番号と名前を取得できるんじゃね?)と思いついたので、実際にやってみました。別に、その情報を公開したりするつもりはなく、自分の腕試しとして、プログラムを組んでみました。
3. 設計
まず、「全学生」の情報、とありますが、正確には現在、このWEBシステムにアカウントの存在する学生のみです。卒業生の方と思われるアカウントも存在していたので、それもまとめて取得しました。
今回は単なるスクレイピングではなく、ログイン後のページをスクレイピングしなければなりません。そこで、以下のように行いました。
ログイン用のphpファイルに、通常のログイン時と全く同じリクエストを送信
1で返却されたクッキーを使い、「活動内容」を表示させるphpにリクエストを送信
2で返却されたソースコードから必要な部分だけ切り出し、テキストファイルへ書き込み
10秒待ってから、2へ戻る
「活動内容」のページは119ページまであるので、2~4の工程を119回行って終了します。

リクエストを送受信するのは、Javaの標準ライブラリのHttpURLConnectionを使って自前で実装しても良かったですが、3の工程で面倒なhtmlソースコードの解析を行わないといけないことがわかっていたので、HTMLパーサライブラリのjsoupを利用しました。
2でログイン時のクッキーを利用しているのは、セッションの関係です。セッションとクッキー、そしてPHPとの関係についてはこのサイトに概要的なことがまとめられているので、読んでみてはどうでしょう。
また、4の工程で10秒待っているのは、サーバーに負荷を掛けないためです。一応、スクレイピングという行為は、一歩間違えると違法となる行為です。例えば、1秒で数十回から数百回のリクエストを送信すると、「電子計算機損壊等業務妨害罪」などに当たる可能性がありますし、著作物を無断でスクレイピングすると、著作権法違反などに当たる可能性があります。そのため、細心の注意を払い、10秒間も待っています。
気づいた点として、なぜそのような設計にしたのか、意図が不明ですが、「活動内容」を表示させるphpは1ページ目のみ、通常のGETを行っており、2ページ目以降を取得したい場合は、page_noというフォームデータをPOSTで送信することによって取得する構造になっていました。
全学生のデータは、1行につき「[学籍番号] [名前]」のようにテキストデータとして保存していたのですが、あとから、CSV形式にしておけばエクセルやらスプレッドシートなどで見れることに気づき、こんな感じのスペースをカンマに変換して別ファイルへ出力するプログラムと手動の拡張子変更でお茶を濁しておきました。


最終的には、XLSX形式にして完了としました。(灰色の部分には、名前が出ています)
4. 感想など
サーバーとやり取りしている情報は大抵開発者ツール(F12)で見られるので、簡単でした。まあ、プログラマでもない限り、開発者ツールなんて使わないでしょうが、どんな情報が、どこに送られているのかなど、様々な情報が見られます。あとは、スマホで表示させたらどんなふうに見えるんだろう、なんていうことも開発者ツールで出来ます。興味があれば、PC版のブラウザ(Chrome、Firefox、Edgeなど)で適当なページを開き、F12キーを押してみてください。
スクレイピングの肝ともなる、ソースコードの解析ですが、ライブラリのおかげで、かなり楽に取捨選択できました。今回は、学籍番号の数字6桁が入っているかどうかで判定しました。しかし、たまにですが、大学院生のアカウントなど、学籍番号が付与されていないものもあったので、それらについてはソースコードをテキストデータとして保存しておき、後から手動で確認する、という方式を取りました。ちょっとめんどくさかったのと、正規表現がまだまだ弱い部分だな、と感じました。もっと、いろいろ作って練習していきたいです。
スクレイピングは、活用できれば、かなり有益なものです。利用規約と法律に抵触したり、他人の迷惑にならない範囲で、有効に活用していきたいです。
......うちの大学、個人情報ガバガバすぎなのでは。
らきいば