1概要


Jsoup

は、主にHTMLからデータを抽出するために使用されるオープンソースのJavaライブラリです。 HTMLを操作して出力することもできます。それは着実な開発ライン、素晴らしいドキュメンテーション、そして流暢で柔軟なAPIを持っています。 JsoupはXMLの解析と構築にも使用できます。

このチュートリアルでは、jsoupのいくつかの機能を実演するスクレーピング演習を説明するためにhttps://spring.io/blog[Spring Blog]を使用します。

  • Loading:HTMLを取得して

    Document

    に解析する

  • フィルタリング:目的のデータを

    Elements

    に選択してトラバースする

それ
** 抽出:ノードの属性、テキスト、HTMLを取得する

  • 修正:ノードの追加/編集/削除とそれらの属性の編集


2 Mavenの依存関係

プロジェクトでjsoupライブラリを利用するには、

pom.xml

に依存関係を追加します。

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.2</version>
</dependency>


jsoup

の最新バージョンを見つけることができます。 Maven Centralリポジトリ


3一目でわかるJsoup

JsoupはページHTMLを読み込み、対応するDOMツリーを構築します。このツリーはブラウザのDOMと同じように機能し、jQueryやJavaScriptのようなテキスト/HTML/属性の選択、トラバース、操作、要素の追加/削除を行うメソッドを提供します。

クライアントサイドのセレクタとDOMのトラバース/操作に慣れている人は、jsoupがとてもおなじみでしょう。ページの段落を印刷するのがどれほど簡単かを確認します。

Document doc = Jsoup.connect("http://example.com").get();
doc.select("p").forEach(System.out::println);

jsoupはHTMLのみを解釈し、JavaScriptは解釈しません。したがって、JavaScript対応のブラウザでページを読み込んだ後に通常行われるDOMへの変更は、jsoupでは表示されません。


4ロード中

ロードフェーズは、HTMLを


Document


にフェッチして解析することからなります。

Jsoupは、最新のブラウザが行うように、最も無効なものから完全に検証されたものまで、あらゆるHTMLの解析を保証します。これは、

String



InputStream



File

、またはURLをロードすることによって実現できます。

Spring BlogのURLから

Document

をロードしましょう。

String blogUrl = "https://spring.io/blog";
Document doc = Jsoup.connect(blogUrl).get();


get

メソッドに注目してください。これはHTTP GET呼び出しを表します。 HTTP POSTを

post

メソッドで実行することもできます(または、HTTPメソッドタイプをパラメータとして受け取る

method

を使用することもできます)。

異常なステータスコード(404など)を検出する必要がある場合は、

HttpStatusException

例外を捕捉する必要があります。

try {
   Document doc404 = Jsoup.connect("https://spring.io/will-not-be-found").get();
} catch (HttpStatusException ex) {
  //...
}

時々、接続はもう少しカスタマイズされる必要があります。


Jsoup.connect(…​)



Connection

を返します。これを使用すると、とりわけ、ユーザーエージェント、参照元、接続タイムアウト、Cookie、投稿データ、およびヘッダーを設定できます。

Connection connection = Jsoup.connect(blogUrl);
connection.userAgent("Mozilla");
connection.timeout(5000);
connection.cookie("cookiename", "val234");
connection.cookie("cookiename", "val234");
connection.referrer("http://google.com");
connection.header("headersecurity", "xyz123");
Document docCustomConn = connection.get();

接続は流暢なインターフェースをたどるので、目的のHTTPメソッドを呼び出す前にこれらのメソッドを連鎖させることができます。

Document docCustomConn = Jsoup.connect(blogUrl)
  .userAgent("Mozilla")
  .timeout(5000)
  .cookie("cookiename", "val234")
  .cookie("anothercookie", "ilovejsoup")
  .referrer("http://google.com")
  .header("headersecurity", "xyz123")
  .get();


Connection

設定の詳細については、https://jsoup.org/apidocs/org/jsoup/Connection.html[対応するJavadocを参照]を参照してください。


5フィルタリング

HTMLを

Document

に変換したので、今度はそれをナビゲートして探しているものを見つける時間です。 jQuery/JavaScriptとの類似性は、セレクターとトラバース方法が似ているため、より明白になります。


5.1.

を選択


Document


select

メソッドは、セレクタを表す

String

を、同じセレクタ構文https://api.jquery.com/category/selectors/[CSSまたはJavaScriptの場合]を使用して受け取り、一致する

Elements

のリストを取得します。このリストは空にすることができますが

null

にすることはできません。


select

メソッドを使用していくつかの選択を見てみましょう。

Elements links = doc.select("a");
Elements sections = doc.select("section");
Elements logo = doc.select(".spring-logo--container");
Elements pagination = doc.select("#pagination__control");
Elements divsDescendant = doc.select("header div");
Elements divsDirect = doc.select("header > div");

一般的な

select

の代わりに、ブラウザDOMからヒントを得た、より明示的なメソッドを使用することもできます。

Element pag = doc.getElementById("pagination__control");
Elements desktopOnly = doc.getElementsByClass("desktopOnly");


Element



Document

のスーパークラスなので、


Document


およびhttps://jsoupで選択方法の操作についてさらに学ぶことができます。 org/apidocs/org/jsoup/nodes/Element.html[

Element

]Javadocs。


5.2. トラバース

  • Jsoupは、

    Document

    、一連の

    Element、または特定の

    Element__を操作するメソッドを提供し、ノードの親、兄弟、または子にナビゲートすることを可能にします。

また、

Elements

の集合の最初、最後、およびn番目(0から始まるインデックスを使用)の

Element

にジャンプすることもできます。

Element firstSection = sections.first();
Element lastSection = sections.last();
Element secondSection = sections.get(2);
Elements allParents = firstSection.parents();
Element parent = firstSection.parent();
Elements children = firstSection.children();
Elements siblings = firstSection.siblingElements();

選択を繰り返すこともできます。実際、

Elements

型のものは何でも反復できます。

sections.forEach(el -> System.out.println("section: " + el));

選択を前の選択(サブ選択)に限定することができます。

Elements sectionParagraphs = firstSection.select(".paragraph");


6. 抽出

特定の要素に到達する方法がわかったので、その内容、つまり属性、HTML、または子テキストを取得します。

ブログから最初の記事を選択し、その日付、最初のセクションのテキスト、そして最後にその内側と外側のHTMLを取得する次の例を見てください。

Element firstArticle = doc.select("article").first();
Element timeElement = firstArticle.select("time").first();
String dateTimeOfFirstArticle = timeElement.attr("datetime");
Element sectionDiv = firstArticle.select("section div").first();
String sectionDivText = sectionDiv.text();
String articleHtml = firstArticle.html();
String outerHtml = firstArticle.outerHtml();

セレクタを選択して使用するときに留意する必要があるいくつかのヒントがあります。

  • ページだけでなく、ブラウザの「ソースの表示」機能に依存

DOMが変更された可能性があるため(ブラウザコンソールで選択すると、
jsoupとは異なる結果になります)
**

https://jsoup.org/apidocs/index.html?org/jsoup/select/Selector.html

[Know

たくさんあるので、それを持っていることは常に良いことです。
少なくともそれらを以前に見たことがあります。セレクタの習得に時間がかかる
**

セレクタ用の遊び場を使用

それらを使って(そこにサンプルHTMLを貼り付けてください)
** ページ変更への依存度を低くする

妥協しているセレクタ(例:IDベースを好む)


7. 修正中

変更には、要素の属性、テキスト、およびHTMLの設定、要素の追加と削除が含まれます。それは以前にjsoupによって生成されたDOMツリー –

ドキュメント

– に対して行われます。


7.1. 属性と内部テキスト/HTMLの設定

jQueryと同様に、属性、テキスト、およびHTMLを設定するメソッドは同じ名前を持ちますが、設定される値も受け取ります。


  • attr()

    – 属性の値を設定します(属性の値が

存在しない)
**

text()

– 要素の内部テキストを設定し、内容を置き換えます


  • html()

    – 要素の内部HTMLを設定し、内容を置き換えます

これらの方法の簡単な例を見てみましょう。

timeElement.attr("datetime", "2016-12-16 15:19:54.3");
sectionDiv.text("foo bar");
firstArticle.select("h2").html("<div><span></span></div>");


7.2. 要素の作成と追加

新しい要素を追加するには、まず

Element

をインスタンス化してそれを構築する必要があります。

Element

が構築されたら、

appendChild

メソッドを使用して別の

Element

に追加することができます。新しく作成されて追加された

Element

は、

appendChild

が呼び出される要素の末尾に挿入されます。

Element link = new Element(Tag.valueOf("a"), "")
  .text("Checkout this amazing website!")
  .attr("href", "http://baeldung.com")
  .attr("target", "__blank");
firstArticle.appendChild(link);


7.3. 要素を削除する

要素を削除するには、まずそれらを選択して

remove

メソッドを実行する必要があります。

たとえば、

Document

から“

navbar-link”

クラスを含むすべての

<li>

タグ、および最初の記事のすべての画像を削除します。

doc.select("li.navbar-link").remove();
firstArticle.select("img").remove();


7.4. 修正文書をHTML

に変換する

最後に、

Document

を変更していたので、作業内容を確認したいと思うかもしれません。

これを行うには、提示されているメソッドを使用して選択、トラバース、および抽出することによって

Document

DOMツリーを探索するか、または

html()

メソッドを使用して単にそのHTMLを

String

として抽出します。

String docHtml = doc.html();


String

の出力はきれいなHTMLです。


8結論

Jsoupはどのページも掻き取るための素晴らしいライブラリです。 Javaを使用していてブラウザベースのスクレイピングを必要としない場合は、考慮に入れるべきライブラリです。フロントエンド開発に関してあなたが持っているかもしれない知識を利用し、そして良い習慣とデザインパターンに従うので、それはおなじみで使いやすいです。


jsoup API

を学び、https://jsoup.org/cookbook/[jsoup Cookbook]を読むことで、jsoupを使ってWebページをスクラップすることについてさらに学ぶことができます。

このチュートリアルで使用されているソースコードはhttps://github.com/eugenp/tutorials/tree/master/jsoup[GitHubプロジェクト]にあります。