Java jsoupを使ったWebスクレイピング

code html digital coding web 1076536

JavaでWebのデータをスクレイピングするために、jsoupを利用します。jsoupはJavaのWebスクレイピングライブラリとして人気があるため、Web上で情報が多く見つかります。また記述方法もシンプルで分かりやすいといった特徴があります。

目次

プロジェクトの準備

build.gardleに以下を追加します。

dependencies {
    implementation group: 'org.jsoup', name: 'jsoup', version: '1.15.4'
}

スクレイピングするコードの作成

以下のライブラリをimportします。

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;

実際にスクレイピングするコードを記述します。

    public static void jsoupScraping() throws IOException {
        Document subreddit = Jsoup.connect("https://www.reddit.com/r/java/").userAgent("Mozilla").data("name", "jsoup").get();
        System.out.println(subreddit);
    }

コンソールに取得したHTMLが出力されれば成功です。

ログイン画面の対策

Webスクレイピングしたいサイトがログイン後の場合、先程の方法ではうまくいきません。そのため、先にログインページに対してユーザー名とパスワードをPOSTし、発行されたクッキーをセットした状態で実際にスクレイピングしたいページにアクセスする必要があります。これを実装すると以下のようになります。

    public static void jsoup() {
        Document document;

        // ユーザ名・パスワード
        final String USERNAME = "ユーザー名";
        final String PASS = "パスワード";

        // ログインページのURL
        final String LOGIN_URL = "ログインページのPOST先URL";
        String mainUrl = "スクレイピングしたいページのURL";

        // ユーザーエージェント
        final String UA = "Mozilla";

        try {
            // ログインページからレスポンスを取得
            Connection.Response response = Jsoup.connect(LOGIN_URL)
                    .method(Connection.Method.GET)
                    .execute();

            // フォームのname
            response = Jsoup.connect(LOGIN_URL)
                    .data("フォームname(ログイン名)", USERNAME, "フォームのname(パスワード)", PASS)
                    .userAgent(UA)
                    .cookies(response.cookies())
                    .method(Connection.Method.POST)
                    .execute();

            System.out.println(response.statusCode());
            System.out.println(response.parse());

            // ログインページから取得したクッキーを使ってアクセス
            document = Jsoup.connect(mainUrl)
                    .userAgent(UA)
                    .cookies(response.cookies())
                    .get();
//            System.out.println(document);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

以下のフォームの場合、各パラメータは次のとおりです。

  • ログインページのPOST先URL: https://loginurl
  • フォームname(ログイン名): email
  • フォームのname(パスワード): passwd
<form id="login" name="login" action="https://loginurl" method="post">
<div>ログインはコチラ</div><input type="text" name="email" value="" id="email" class="lginFmId" placeholder="メールアドレスを入力してください" title="メールアドレス">
<input type="password" name="passwd" id="passwd" class="lginFmPw" placeholder="パスワードを入力してください" title="パスワード">
<input type="submit" value="ログイン" class="lginFmLi"><div class="clear"></div>
<input type="hidden" name="url" id="hiddenURL" value="https://xxx">
<input type="hidden" name="done" value="https://xxx/">
</form>

フォーム上入力項目がIDとパスワードだけであっても、以下のようにhiddenパラメータで、ログイン画面で生成されたトークンをログインURLに一緒にPOSTする必要がある場合もあります。

<form id="login" name="login" action="https://loginurl" method="post">
<div>ログインはコチラ</div><input type="text" name="email" value="" id="email" class="lginFmId" placeholder="メールアドレスを入力してください" title="メールアドレス">
<input type="password" name="passwd" id="passwd" class="lginFmPw" placeholder="パスワードを入力してください" title="パスワード">
<input type="submit" value="ログイン" class="lginFmLi"><div class="clear"></div>
<input type="hidden" name="postkey" id="postkey" value="32aa027553e3e5a8139118e240b6323d">
<input type="hidden" name="refToken" id="refToken" value="e2f4aae6781d8905611665292773929c817777e526ac81de9289152ea98f19cb">
<input type="hidden" name="url" id="hiddenURL" value="https://xxx">
<input type="hidden" name="done" value="https://xxx">
</form>

この場合は以下のようにもう一ステップを挟む必要があります。

  • 一度ログインページのURLにアクセスしhiddenパラメータのトークンを取得
  • ID、パスワード、トークンをログインURLにPOST
  • Cookieを保持した状態で実際にWebスクレイピングしたいページにアクセス

jsoupのデメリットと代替策

jsoupは、広く使われており情報が探しやすい、記述が簡単といったメリットがありますが、一方でデメリットもあります。

それは、javascriptに対応していないということです。Webサイトの中にはjavascriptが無効な状態でアクセスすると正常に表示されない、正しく機能しないといったことが発生し、期待するWebスクレイピングが行えない可能性があります。

そのような場合は、以下のような代替策が考えられます。

  • Javascriptに対応したスクレイピングライブラリを使用する
  • ChromeのようなWebブラウザをJavaで操作することで自動化するSeleniumを用いる

サイトポリシーを確認しよう

スクレイピングは大変強力な手法ですが、実際に利用する前にサイトポリシーで禁止されていないか確認するようにしましょう。また、禁止されていなくてもWebサーバーに負担をかけないように実行間隔を長めに取る、不必要にスクレイピングを行わないなど注意しましょう。

参考

よかったらシェアしてね!
目次