Önde gelen Java HTML ayrıştırıcılarının artıları ve eksileri nelerdir? [kapalı]


175

SO ve Google'da arama yaparken, çeşitli taraflarca sürekli olarak önerilen birkaç Java HTML ayrıştırıcısı olduğunu gördüm. Ne yazık ki, çeşitli kütüphanelerin güçlü ve zayıf yanları hakkında herhangi bir bilgi bulmak zordur. Bazı insanların bu kütüphaneleri karşılaştırmak için biraz harcadıklarını ve öğrendiklerini paylaşabileceklerini umuyorum.

İşte gördüklerim:

Ve özlediğim büyük bir ayrıştırıcı varsa, artılarını ve eksilerini de duymak isterim.

Teşekkürler!

Yanıtlar:


223

Genel

Bilinen hemen hemen tüm HTML ayrıştırıcıları W3C DOM API'sini (JAXP API'sinin bir parçası, XML işleme için Java API'sı) uygular ve JAXP API org.w3c.dom.Documenttarafından doğrudan kullanıma hazır bir destek sunar . Büyük farklılıklar genellikle söz konusu ayrıştırıcının özelliklerinde bulunur. Çoğu ayrıştırıcı, JTidy , NekoHTML , TagSoup ve HtmlCleaner gibi iyi biçimlendirilmemiş HTML ("tagsoup") ile belirli derecede affedici ve yumuşaktır . W3C DOM ve JAXP API'sini kullanarak HTML kaynağını (örneğin HTML-geçerliliğini <br>bir XML-geçerliliği ile değiştirmek <br />) genellikle "bu şekilde" HTML ayrıştırıcılarını kullanırsınız.

Atlar sadece olanlardır HtmlUnit'in ve Jsoup .

HtmlUnit'in

HtmlUnit , programlı bir webbrowser gibi davranma imkanı veren tamamen kendi API'sı sağlar. Form değerlerini girin, öğeleri tıklayın, JavaScript'i çağırın vb. Tek başına bir HTML ayrıştırıcıdan çok daha fazlası. Gerçek bir "GUI'siz webbrowser" ve HTML birimi test aracıdır.

Jsoup

Jsoup ayrıca tamamen kendi API'sı sağlar. Size jQuery benzeri CSS seçicileri kullanarak öğeleri seçme imkanı verir ve ilgilenilen öğeleri almak için HTML DOM ağacında gezinmek için kaygan bir API sağlar.

Özellikle HTML DOM ağacının çapraz hareketi Jsoup'un en büyük gücüdür. Birlikte çalışanlar org.w3c.dom.Document, ayrıntılı NodeListve NodeAPI'ları kullanarak DOM'dan geçmenin ne kadar acı olduğunu biliyorlar . Doğru, XPathhayatı kolaylaştırır, ama yine de, bu başka bir öğrenme eğrisi ve yine de ayrıntılı olabilir.

Aşağıda, sorunuzun ilk paragrafını ve tüm yanıtlayanların adlarını ayıklamak için XPath ile birlikte JTidy gibi bir "düz" W3C DOM ayrıştırıcı kullanan bir örnek (O olmadan beri XPath kullanıyorum, ilgili bilgileri toplamak için gerekli kod aksi takdirde, faydalı / yardımcı yöntemler yazmadan 10 kat daha fazla büyüyecektir).

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

Ve işte Jsoup ile nasıl aynısını yapacağınıza dair bir örnek:

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

Farkı görüyor musunuz? Sadece daha az kod değil, aynı zamanda CSS seçicileriyle (örneğin, web siteleri geliştirerek ve / veya jQuery kullanarak) ılımlı bir deneyime sahipseniz Jsoup'u da kavramak nispeten kolaydır.

özet

Her birinin artıları ve eksileri şimdi yeterince açık olmalıdır. Sadece standart JAXP API'sini kullanarak geçiş yapmak istiyorsanız, belirtilen ilk ayrıştırıcı grubuna gidin. Oldukça vardır çok onları. Hangisini seçeceğiniz, sağladığı özelliklere (HTML temizliği sizin için nasıl kolaylaştırılmıştır? Bazı dinleyiciler / yakalayıcılar ve etikete özgü temizleyiciler var mı?) Ve kütüphanenin sağlamlığına (ne sıklıkta güncellenir / korunur / sabitlenir?) ). HTML'yi birim olarak test etmek isterseniz, HtmlUnit gitmenin yoludur. HTML'den (genellikle gerçek dünya gereksiniminden daha fazla) belirli verileri ayıklamak isterseniz, Jsoup gitmenin yoludur.


Burada atlanan büyük bir pro / con var: Jericho, beyaz alan biçimlendirmesini ve HTML'nin yanlışlığını (varsa) korurken kötü HTML'yi değiştirmenize izin veren tek ayrıştırıcı.
Adam Gent

3
Jsoupiyidir. org.w3c.dom.*API ile çalışan başka bir modülle arayüz oluşturmaya çalıştım . Jsoup'un org.w3c.dom.*sözleşmeye
uymadığını tespit etti

13

Bu makale aşağıdaki ayrıştırıcıların belirli yönlerini karşılaştırmaktadır:

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

Bu hiçbir şekilde tam bir özet değildir ve 2008'den alınmıştır. Ama yararlı bulabilirsiniz.


Bu yalnızca bağlantıya verilen bir yanıttır. İlgili ayrıntıları buraya ekleyebilir misiniz?
Monica'yı eski durumuna getirme - notmaynard

7

Ekle validator.nu HTML Ayrıştırıcı listenize, Java HTML5 ayrıştırma algoritması bir uygulama.

Artı tarafta, özellikle HTML5 ile ve HTML5 doğrulayıcısının kalbinde yer alacak şekilde tasarlanmıştır, bu nedenle gelecekteki tarayıcının ayrıştırma davranışını çok yüksek bir doğruluk derecesiyle eşleştirme olasılığı yüksektir.

Eksi tarafta, hiçbir tarayıcının eski ayrıştırma işlemi tam olarak böyle çalışır ve HTML5 hala taslak halindeyken değişebilir.

Uygulamada, bu tür problemler sadece belirsiz köşe vakalarını etkiler ve tüm pratik amaçlar için mükemmel bir ayrıştırıcıdır.


7

Buldum Jericho HTML Ayrıştırıcı çok iyi yazılacak tarih (ayrıştırıcıları birçok değildir), hiçbir bağımlılıkları ve kolay kullanımı ile kadar devam etti.


6

Java'daki HTML ayrıştırma kitaplıklarının çoğuyla çalıştıktan sonra @MJB yanıtına ekleyeceğim, atlanan büyük bir pro / con var: giriş ve çıkıştaki HTML'nin biçimlendirmesini ve yanlışlığını koruyan ayrıştırıcılar.

Belgeyi değiştirdiğinizde çoğu ayrıştırıcı, özellikle XML benzeri bir kitaplıksa DOM'un boşluk, yorum ve yanlışlığını uçurur.

Jericho , beyaz alan biçimlendirmesini ve HTML'nin yanlışlığını (varsa) korurken kötü HTML'yi değiştirmenize izin veren tek ayrıştırıcıdır.


3

Diğer iki seçenek HTMLCleaner ve HTMLParser'dır .

Buradaki ayrıştırıcıların çoğunu geliştirdiğim bir tarayıcı / veri çıkarma çerçevesi için denedim. HTMLCleaner'ı veri çıkarma işinin büyük kısmı için kullanıyorum. Bunun nedeni, HTML, XHTML, HTML 5'in ad alanlarıyla makul derecede modern bir lehçesini desteklemesi ve DOM'u desteklemesidir, bu nedenle Java'nın yerleşik XPath uygulamasıyla kullanmak mümkündür .

HTMLCleaner ile bunu diğer ayrıştırıcılardan bazılarından çok daha kolaydır: Örneğin JSoup, DOM yerine DOM benzeri bir arayüzü destekler, bu nedenle bazı montajlar gereklidir . Jericho bir SAX hattı arayüzüne sahiptir, bu yüzden Sujit Pal'in bunun nasıl yapılacağına dair iyi bir açıklaması olmasına rağmen HTMLCleaner daha iyi çalıştı.

Ayrıca Perl's libhtml-tableextract-perl kullanılarak yazılmış bazı kodların yerine bir tablo çıkarma görevi için HTMLParser ve Jericho kullanıyorum . Tablo için HTML filtrelemek için HTMLParser kullanın, sonra ayrıştırmak için Jericho kullanın. MJB ve Adam'ın Jericho'nun temel HTML'yi koruduğu için iyi olduğu yorumlarına katılıyorum. Standart olmayan bir SAX arayüzüne sahiptir, bu yüzden XPath işleme için HTMLCleaner daha iyidir.

Tüm ayrıştırıcılar belirli türden hatalı biçimlendirilmiş HTML içeriği üzerinde mücadele ediyor gibi göründüğü için, Java'da HTML'yi ayrıştırmak şaşırtıcı derecede zor bir sorundur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.