Apa pro dan kontra dari parser Java HTML terkemuka? [Tutup]

175

Mencari SO dan Google, saya telah menemukan bahwa ada beberapa parser HTML Java yang secara konsisten direkomendasikan oleh berbagai pihak. Sayangnya sulit menemukan informasi tentang kekuatan dan kelemahan berbagai perpustakaan. Saya berharap bahwa beberapa orang telah menghabiskan beberapa membandingkan perpustakaan ini, dan dapat membagikan apa yang telah mereka pelajari.

Inilah yang saya lihat:

Dan jika ada pengurai utama yang saya lewatkan, saya akan senang mendengar tentang pro dan kontra juga.

Terima kasih!

Avi Flax
sumber

Jawaban:

223

Umum

Hampir semua parser HTML yang dikenal mengimplementasikan W3C DOM API (bagian dari JAXP API, Java API untuk pemrosesan XML) dan memberi Anda org.w3c.dom.Documentpunggung yang siap digunakan langsung oleh JAXP API. Perbedaan utama biasanya ditemukan dalam fitur parser yang bersangkutan. Sebagian besar parser sampai tingkat tertentu memaafkan dan lunak dengan HTML yang tidak berformat baik ("tagoup"), seperti JTidy , NekoHTML , TagSoup dan HtmlCleaner . Anda biasanya menggunakan parser HTML semacam ini untuk "merapikan" sumber HTML (misalnya mengganti HTML-valid <br>dengan XML-valid<br /> ), sehingga Anda dapat melewatinya "dengan cara biasa" menggunakan W3C DOM dan JAXP API.

Satu-satunya yang melompat keluar adalah HtmlUnit dan Jsoup .

HtmlUnit

HtmlUnit menyediakan API sepenuhnya milik Anda yang memberi Anda kemungkinan untuk bertindak seperti browser web secara terprogram. Yaitu memasukkan nilai formulir, klik elemen, aktifkan JavaScript, dan sebagainya. Ini jauh lebih dari seorang parser HTML saja. Ini adalah "penjelajah web tanpa GUI" yang nyata dan alat pengujian unit HTML.

Jsoup

Jsoup juga menyediakan API yang sepenuhnya miliknya. Ini memberi Anda kemungkinan untuk memilih elemen menggunakan pemilih CSS seperti jQuery dan menyediakan API yang apik untuk melintasi pohon DOM HTML untuk mendapatkan elemen yang menarik.

Khususnya melintasi pohon HTML DOM adalah kekuatan utama Jsoup. Orang yang telah bekerja dengan org.w3c.dom.Documenttahu betapa sakitnya untuk melintasi DOM menggunakan verbose NodeListdan NodeAPI. Benar,XPath membuat hidup lebih mudah, tapi tetap saja, itu adalah kurva belajar yang lain dan bisa berakhir dengan kata lain.

Berikut adalah contoh yang menggunakan parser DOM W3C "biasa" seperti JTidy yang dikombinasikan dengan XPath untuk mengekstrak paragraf pertama dari pertanyaan Anda dan nama-nama semua penjawab (saya menggunakan XPath karena tanpa itu, kode yang diperlukan untuk mengumpulkan informasi yang menarik) jika tidak akan tumbuh 10 kali lebih besar, tanpa menulis utilitas / metode pembantu).

String url = "http://stackoverflow.com/questions/3152138";
Document document = new Tidy().parseDOM(new URL(url).openStream(), null);
XPath xpath = XPathFactory.newInstance().newXPath();
  
Node question = (Node) xpath.compile("//*[@id='question']//*[contains(@class,'post-text')]//p[1]").evaluate(document, XPathConstants.NODE);
System.out.println("Question: " + question.getFirstChild().getNodeValue());

NodeList answerers = (NodeList) xpath.compile("//*[@id='answers']//*[contains(@class,'user-details')]//a[1]").evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < answerers.getLength(); i++) {
    System.out.println("Answerer: " + answerers.item(i).getFirstChild().getNodeValue());
}

Dan inilah contoh bagaimana melakukan hal yang persis sama dengan Jsoup:

String url = "http://stackoverflow.com/questions/3152138";
Document document = Jsoup.connect(url).get();

Element question = document.select("#question .post-text p").first();
System.out.println("Question: " + question.text());

Elements answerers = document.select("#answers .user-details a");
for (Element answerer : answerers) {
    System.out.println("Answerer: " + answerer.text());
}

Apakah Anda melihat perbedaannya? Ini bukan hanya kode yang lebih sedikit, tetapi Jsoup juga relatif mudah dipahami jika Anda sudah memiliki pengalaman moderat dengan pemilih CSS (misalnya mengembangkan situs web dan / atau menggunakan jQuery).

Ringkasan

Pro dan kontra masing-masing harus cukup jelas sekarang. Jika Anda hanya ingin menggunakan API JAXP standar untuk melewatinya, maka pergi untuk grup parser yang disebutkan pertama. Ada cukup banyak dari mereka. Yang mana yang akan dipilih tergantung pada fitur yang disediakannya (bagaimana pembersihan HTML dipermudah untuk Anda? Apakah ada beberapa pendengar / pencegat dan pembersih khusus-tag?) Dan kekokohan perpustakaan (seberapa sering diperbarui / dirawat / diperbaiki? ). Jika Anda ingin menguji unit HTML, maka HtmlUnit adalah cara untuk melakukannya. Jika Anda suka mengekstraksi data spesifik dari HTML (yang seringkali merupakan persyaratan dunia nyata), maka Jsoup adalah cara untuk melakukannya.

BalusC
sumber
Ada pro / kontra besar yang dihilangkan di sini: Jericho adalah satu-satunya parser yang saya tahu yang memungkinkan Anda untuk memanipulasi HTML jahat sambil mempertahankan format spasi putih dan kesalahan HTML (jika ada).
Adam Gent
3
Jsoupitu bagus. Saya mencoba antarmuka dengan modul lain yang berfungsi dengan org.w3c.dom.*API. Ternyata Jsoup tidak mematuhi org.w3c.dom.*kontrak
Thamme Gowda
13

Artikel ini membandingkan aspek-aspek tertentu dari parser berikut:

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

Ini sama sekali bukan ringkasan yang lengkap, dan itu berasal dari 2008. Tetapi Anda mungkin merasa terbantu.

Matt Solnit
sumber
Ini hanya jawaban tautan. Bisakah Anda menambahkan detail terkait di sini?
Reinstate Monica - notmaynard
7

Tambahkan Parser HTML validator.nu , sebuah implementasi dari algoritma parsing HTML5 di Jawa, ke daftar Anda.

Di sisi positifnya, ini dirancang khusus untuk mencocokkan HTML5, dan di jantung validator HTML5, jadi sangat mungkin untuk mencocokkan perilaku parsing browser masa depan dengan tingkat akurasi yang sangat tinggi.

Di sisi minus, warisan parsing tidak ada browser bekerja persis seperti ini, dan karena HTML5 masih dalam konsep, dapat berubah.

Dalam praktiknya, masalah semacam itu hanya memengaruhi kasus sudut yang tidak jelas, dan untuk semua tujuan praktis, merupakan pengurai yang sangat baik.

Alohci
sumber
7

Saya menemukan Jericho HTML Parser ditulis dengan sangat baik, terus diperbarui (yang banyak parsernya tidak), tidak ada dependensi, dan mudah digunakan.

MJB
sumber
6

Saya hanya akan menambahkan jawaban @MJB setelah bekerja dengan sebagian besar parsing pustaka HTML di Jawa, ada pro / kontra besar yang dihilangkan: parser yang mempertahankan pemformatan dan kesalahan HTML pada input dan output.

Itu adalah sebagian besar parser ketika Anda mengubah dokumen akan menghilangkan spasi, komentar, dan kesalahan DOM terutama jika mereka adalah perpustakaan seperti XML.

Jericho adalah satu-satunya parser yang saya tahu yang memungkinkan Anda untuk memanipulasi HTML jahat sambil mempertahankan format spasi putih dan kesalahan HTML (jika ada).

Adam Gent
sumber
3

Dua opsi lainnya adalah HTMLCleaner dan HTMLParser .

Saya telah mencoba sebagian besar parser di sini untuk kerangka kerja crawler / ekstraksi data yang telah saya kembangkan. Saya menggunakan HTMLCleaner untuk sebagian besar pekerjaan ekstraksi data. Ini karena mendukung dialek HTML, XHTML, HTML 5, dengan ruang nama yang cukup modern, dan mendukung DOM, sehingga dimungkinkan untuk menggunakannya dengan Java yang dibangun pada implementasi XPath .

Ini jauh lebih mudah untuk melakukan ini dengan HTMLCleaner daripada beberapa parser lain: JSoup misalnya mendukung antarmuka seperti DOM, daripada DOM, sehingga beberapa perakitan diperlukan . Jericho memiliki antarmuka SAX-line sehingga sekali lagi diperlukan beberapa pekerjaan meskipun Sujit Pal memiliki deskripsi yang baik tentang bagaimana melakukan ini tetapi pada akhirnya HTMLCleaner hanya bekerja lebih baik.

Saya juga menggunakan HTMLParser dan Jericho untuk tugas ekstraksi tabel, yang menggantikan beberapa kode yang ditulis menggunakan libhtml-tableextract-perl Perl . Saya menggunakan HTMLParser untuk memfilter HTML untuk tabel, kemudian menggunakan Jericho untuk menguraikannya. Saya setuju dengan komentar MJB dan Adam bahwa Jericho baik dalam beberapa kasus karena mempertahankan HTML yang mendasarinya. Ini memiliki semacam antarmuka SAX non-standar, jadi untuk pemrosesan XPath HTMLCleaner lebih baik.

Parsing HTML di Java adalah masalah yang sangat sulit karena semua parser tampaknya berjuang pada jenis konten HTML yang cacat tertentu.

Mark Butler
sumber