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.Document
tarafı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ı NodeList
ve Node
API'ları kullanarak DOM'dan geçmenin ne kadar acı olduğunu biliyorlar . Doğru, XPath
hayatı 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.