Parsing HTML di Java dengan Jsoup

1. Ikhtisar

Jsoup adalah pustaka Java open source yang digunakan terutama untuk mengekstraksi data dari HTML. Ini juga memungkinkan Anda untuk memanipulasi dan mengeluarkan HTML. Ini memiliki jalur pengembangan yang stabil, dokumentasi yang bagus, dan API yang lancar dan fleksibel. Jsoup juga dapat digunakan untuk mengurai dan membangun XML.

Dalam tutorial ini, kita akan menggunakan Spring Blog untuk mengilustrasikan latihan gesekan yang mendemonstrasikan beberapa fitur jsoup:

  • Memuat: mengambil dan mem-parsing HTML menjadi Dokumen
  • Pemfilteran: memilih data yang diinginkan ke dalam Elemen dan menjelajahinya
  • Mengekstrak: mendapatkan atribut, teks, dan HTML dari node
  • Memodifikasi: menambahkan / mengedit / menghapus node dan mengedit atributnya

2. Ketergantungan Maven

Untuk menggunakan pustaka jsoup dalam proyek Anda, tambahkan ketergantungan ke pom.xml Anda :

 org.jsoup jsoup 1.10.2 

Anda dapat menemukan versi terbaru jsoup di repositori Maven Central.

3. Sekilas tentang Jsoup

Jsoup memuat HTML halaman dan membangun pohon DOM yang sesuai. Pohon ini bekerja dengan cara yang sama seperti DOM di browser, menawarkan metode yang mirip dengan jQuery dan vanilla JavaScript untuk memilih, melintasi, memanipulasi teks / HTML / atribut dan menambah / menghapus elemen.

Jika Anda merasa nyaman dengan penyeleksi sisi klien dan traversing / manipulasi DOM, Anda akan menemukan jsoup sangat familiar. Periksa betapa mudahnya mencetak paragraf halaman:

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

Ingatlah bahwa jsoup hanya menafsirkan HTML - tidak menafsirkan JavaScript. Oleh karena itu, perubahan pada DOM yang biasanya terjadi setelah halaman dimuat di browser yang mendukung JavaScript tidak akan terlihat di jsoup.

4. Memuat

Fase pemuatan terdiri dari pengambilan dan penguraian HTML ke dalam Dokumen . Jsoup menjamin penguraian HTML apa pun, dari yang paling tidak valid hingga yang benar-benar divalidasi, seperti yang akan dilakukan browser modern. Ini dapat dicapai dengan memuat String , InputStream , File atau URL.

Mari memuat Dokumen dari URL Blog Spring:

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

Perhatikan metode get , ini mewakili panggilan HTTP GET. Anda juga dapat melakukan HTTP POST dengan metode posting (atau Anda dapat menggunakan metode yang menerima jenis metode HTTP sebagai parameter).

Jika Anda perlu mendeteksi kode status abnormal (misalnya 404), Anda harus menangkap pengecualian HttpStatusException :

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

Terkadang, koneksi perlu sedikit lebih disesuaikan. Jsoup.connect (…) mengembalikan Koneksi yang memungkinkan Anda menyetel, antara lain, agen pengguna, perujuk, batas waktu koneksi, cookie, data posting, dan header:

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

Karena koneksi mengikuti antarmuka yang lancar, Anda dapat menghubungkan metode ini sebelum memanggil metode HTTP yang diinginkan:

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

Anda dapat mempelajari lebih lanjut tentang pengaturan Koneksi dengan menjelajahi Javadoc yang sesuai.

5. Penyaringan

Sekarang kita memiliki HTML yang diubah menjadi Dokumen , sekarang saatnya untuk menavigasinya dan menemukan apa yang kita cari. Di sinilah kemiripan dengan jQuery / JavaScript lebih jelas, karena penyeleksi dan metode traversingnya serupa.

5.1. Memilih

The Document pilih metode menerima String mewakili pemilih, menggunakan sintaks pemilih yang sama seperti dalam CSS atau JavaScript, dan mengambil daftar pencocokan Elements . Daftar ini bisa kosong tapi tidak nol .

Mari kita lihat beberapa pilihan menggunakan metode pemilihan :

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");

Anda juga dapat menggunakan metode yang lebih eksplisit terinspirasi oleh DOM peramban bukan generik pilih :

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

Karena Element adalah superclass dari Document , Anda dapat mempelajari lebih lanjut tentang bekerja dengan metode pemilihan di Document and Element Javadocs.

5.2. Melintasi

Melintasi berarti menavigasi melintasi pohon DOM. Jsoup menyediakan metode yang beroperasi pada Dokumen , pada sekumpulan Elemen, atau pada Elemen tertentu , memungkinkan Anda untuk menavigasi ke orang tua, saudara, atau anak node.

Selain itu, Anda dapat melompat ke Elemen pertama, terakhir, dan n (menggunakan indeks berbasis 0) dalam satu set Elemen :

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();

Anda juga dapat beralih melalui pilihan. Faktanya, semua elemen bertipe dapat diulang:

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

Anda dapat membuat pilihan terbatas pada pilihan sebelumnya (sub-pilihan):

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

6. Mengekstrak

Kita sekarang tahu cara menjangkau elemen tertentu, jadi inilah saatnya untuk mendapatkan kontennya - yaitu atributnya, HTML, atau teks anak.

Lihat contoh ini yang memilih artikel pertama dari blog dan mendapatkan tanggalnya, teks bagian pertamanya, dan terakhir, HTML bagian dalam dan luarnya:

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();

Berikut beberapa tip yang perlu diingat saat memilih dan menggunakan selector:

  • Andalkan fitur "Lihat Sumber" di browser Anda dan tidak hanya di DOM halaman karena mungkin telah berubah (memilih di konsol browser mungkin memberikan hasil yang berbeda dari jsoup)
  • Kenali penyeleksi Anda karena ada banyak dari mereka dan selalu baik untuk setidaknya melihat mereka sebelumnya; menguasai selektor membutuhkan waktu
  • Gunakan taman bermain untuk penyeleksi untuk bereksperimen dengan mereka (tempelkan contoh HTML di sana)
  • Kurangi ketergantungan pada perubahan halaman: bidik penyeleksi terkecil dan paling tidak berkompromi (mis. Lebih suka berbasis id)

7. Memodifikasi

Memodifikasi mencakup atribut pengaturan, teks, dan HTML elemen, serta menambahkan dan menghapus elemen. Ini dilakukan ke pohon DOM yang sebelumnya dibuat oleh jsoup - Dokumen .

7.1. Mengatur Atribut dan Teks Bagian Dalam / HTML

Seperti di jQuery, metode untuk menyetel atribut, teks, dan HTML memiliki nama yang sama tetapi juga menerima nilai yang akan disetel:

  • attr () - menetapkan nilai atribut (ini membuat atribut jika tidak ada)
  • text () - mengatur elemen teks bagian dalam, menggantikan konten
  • html () - mengatur elemen dalam HTML, menggantikan konten

Mari kita lihat contoh singkat dari metode ini:

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

7.2. Membuat dan Menambahkan Elemen

To add a new element, you need to build it first by instantiating Element. Once the Element has been built, you can append it to another Element using the appendChild method. The newly created and appended Element will be inserted at the end of the element where appendChild is called:

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

7.3. Removing Elements

To remove elements, you need to select them first and run the remove method.

For example, let's remove all

  • tags that contain the “navbar-link” class from Document, and all images from the first article:

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

    7.4. Converting the Modified Document to HTML

    Finally, since we were changing the Document, we might want to check our work.

    To do this, we can explore the Document DOM tree by selecting, traversing, and extracting using the presented methods, or we can simply extract its HTML as a String using the html() method:

    String docHtml = doc.html();

    The String output is a tidy HTML.

    8. Conclusion

    Jsoup is a great library to scrape any page. If you're using Java and don't require browser-based scraping, it's a library to take into account. It's familiar and easy to use since it makes use of the knowledge you may have on front-end development and follows good practices and design patterns.

    You can learn more about scraping web pages with jsoup by studying the jsoup API and reading the jsoup cookbook.

    The source code used in this tutorial can be found in the GitHub project.