はじめに
オープンソースのeラーニングプラットフォームである「Moodle」だが、自分で情報を取得し、解析したいと思った。MoodleにはAPIが用意されているため、システム管理者に連絡すれば使えるようになるのかもしれないが、面倒なので自前でスクレイピングできるようにした。
完全なる自分用メモのための記事。
ソースコード
//import文は省略
class login{
public static void main(String[] args){
String UA="hogehogeBOT 1.0/" //ユーザーエージェント
String id="aiueo1234" //ユーザーid
String password="123456789" //パスワード
try{
Connection.Response response=Jsoup.connect("https://moodle.org/login/index.php")
.userAgent(UA)
.method(Connection.Method.GET)
.execute();
String logintoken=response.parse().getElementsByAttributeValue("name","logintoken").get(0).attr("value");
response=Jsoup.connect("https://moodle.org/login/index.php")
.userAgent(UA)
.cookies(response.cookies())
.data("logintoken",logintoken)
.data("username",id)
.data("password",password)
.method(Connection.Method.POST)
.followRedirects(false)
.execute();
Map<String, String> cookies=response.cookies();
cookies.remove("MOODLEID1_");
while(response.statusCode()==303){
response=Jsoup.connect(response.header("Location"))
.userAgent(UA)
.cookies(cookies)
.method(Connection.Method.GET)
.followRedirects(false)
.execute();
}
String text=response.parse().outerHtml();
//ここに処理
}catch(IOException e){
System.out.println("Moodle接続時にエラーが発生しました(接続エラー)。");
e.printStackTrace();
}
}
}
その他
詰まった部分としては、ログイントークンと呼ばれる隠れたフォームが存在していたことである。ログインが必要なページに対する、スクレイピングでは大抵、login.php
などにフォームデータ付きのPOSTリクエストを投げればSession用のCookieが帰ってくるので、そのCookieをもってログインページなどに行けば上手くいく。ただ、Moodleの場合は、一度、login.php
にアクセスし、トークンを取得しなければならなかった。
ログイントークンに関しての詳細は↓
また、ログイン後、303 See Other
で 何度かリダイレクトされる。その際、 followRedirects
を初期状態にしていると、Cookieが引き継がれず、ログインできていない状態でトップページなどに戻される。よって、ステータスコードが303の間は初めに貰ったCookieをもってリダイレクトする処理を自身で書いてやることで、回避した。