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サーバーに負担をかけないように実行間隔を長めに取る、不必要にスクレイピングを行わないなど注意しましょう。
