Загальні
Майже всі відомі HTML-парсери реалізують API DOM W3C (частина API JAXP, Java API для обробки XML) і дає вам org.w3c.dom.Document
повернення, готове до безпосереднього використання API JAXP. Основні відмінності, як правило, знаходяться в особливостях відповідного аналізатора. Більшість парсерів певною мірою прощають і поблажливіше з не добре сформованим HTML ("tagoup"), як-от JTidy , NekoHTML , TagSoup та HtmlCleaner . Зазвичай ви використовуєте такий тип парсерів HTML, щоб "привести в порядок" джерело HTML (наприклад, замінити HTML-дійсний <br>
на допустимий XML <br />
), щоб ви могли пройти його "звичайним способом" за допомогою API W3C DOM та JAXP.
Єдині, хто вискакує, - HtmlUnit і Jsoup .
HtmlUnit
HtmlUnit надає повністю власний API, який дає вам можливість діяти як веб-браузер програмно. Тобто введіть значення форми, клацніть елементи, викликайте JavaScript, etcetera. Це набагато більше, ніж поодинокий аналіз HTML. Це справжній інструмент для тестування веб-браузерів без графічного інтерфейсу та HTML.
Jsoup
Jsoup також пропонує повністю власний API. Це дає можливість вибирати елементи за допомогою селекторів CSS, подібних jQuery , та забезпечує гладкий API для переходу до дерева HTML DOM, щоб отримати цікаві елементи.
Зокрема, перехід дерева HTML DOM є основною силою Jsoup. Ті, хто працював з цим, org.w3c.dom.Document
знають, який страшний біль пройти через DOM за допомогою верболозу NodeList
та Node
API. Щоправда, XPath
полегшує життя, але все-таки це ще одна крива навчання, і вона може бути все-таки багатослівною.
Ось приклад, який використовує "простий" парсер W3C DOM типу JTidy у поєднанні з XPath, щоб витягнути перший абзац вашого запитання та імена всіх відповідачів (я використовую XPath, оскільки без нього код необхідний для збору цікавої інформації інакше вони виростуть у 10 разів більшими, не пишучи корисних / допоміжних методів).
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());
}
І ось приклад, як зробити те саме з 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());
}
Ви бачите різницю? Це не тільки менше коду, але Jsoup також досить легко зрозуміти, якщо у вас вже є помірний досвід роботи з селекторами CSS (наприклад, розробка веб-сайтів та / або використання jQuery).
Підсумок
Плюси і мінуси кожного мають бути досить чіткими зараз. Якщо ви просто хочете використовувати стандартний API JAXP для його переходу, тоді перейдіть до першої згаданої групи парсерів. Їх досить багато . Який вибрати, залежить від функцій, які він надає (як чистка HTML спрощена для вас? Чи є деякі слухачі / перехоплювачі та засоби для чищення тегів?) Та надійність бібліотеки (як часто вона оновлюється / підтримується / фіксується? ). Якщо ви хочете спробувати тест HTML, то HtmlUnit - це шлях. Якщо ви хочете витягти конкретні дані з HTML (що більш ніж часто є реальною потребою у світі), то Jsoup - це шлях.