Geral
Quase todos os analisadores HTML conhecidos implementam a API DOM do W3C (parte da API JAXP, API Java para processamento XML) e oferecem um org.w3c.dom.Document
retorno pronto para uso direto pela API JAXP. As principais diferenças costumam ser encontradas nos recursos do analisador em questão. A maioria dos analisadores é, até certo ponto, indulgente e branda com HTML não-formado ("grupo de tags"), como JTidy , NekoHTML , TagSoup e HtmlCleaner . Você geralmente usa esse tipo de analisadores de HTML para "arrumar" a fonte HTML (por exemplo, substituindo o válido <br>
por HTML por um válido em XML <br />
), para que você possa percorrê-lo "da maneira usual" usando a API W3C DOM e JAXP.
Os únicos que saltam são HtmlUnit e Jsoup .
HtmlUnit
O HtmlUnit fornece uma API completamente própria, que oferece a possibilidade de agir como um navegador da Web programaticamente. Ou seja, insira os valores do formulário, clique nos elementos, chame o JavaScript, etc. É muito mais do que apenas um analisador de HTML. É um verdadeiro "navegador da web sem interface gráfica" e uma ferramenta de teste de unidade HTML.
Jsoup
O Jsoup também fornece uma API completamente própria. Ele oferece a possibilidade de selecionar elementos usando seletores CSS semelhantes ao jQuery e fornece uma API inteligente para percorrer a árvore DOM HTML e obter os elementos de interesse.
Particularmente, o deslocamento da árvore HTML DOM é a principal força do Jsoup. Os que já trabalharam org.w3c.dom.Document
sabem como é doloroso atravessar o DOM usando as APIs NodeList
e detalhadas Node
. É verdade que XPath
facilita a vida, mas, ainda assim, é outra curva de aprendizado e pode acabar sendo detalhada.
Aqui está um exemplo que usa um analisador DOM "simples" do W3C, como o JTidy, em combinação com o XPath para extrair o primeiro parágrafo da sua pergunta e os nomes de todos os respondentes (estou usando o XPath, pois sem ele, o código necessário para reunir as informações de interesse caso contrário, cresceria 10 vezes mais, sem escrever métodos utilitários / auxiliares).
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());
}
E aqui está um exemplo de como fazer exatamente o mesmo com o 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());
}
Você vê a diferença? Não é apenas menos código, mas o Jsoup também é relativamente fácil de entender se você já tem uma experiência moderada com seletores de CSS (por exemplo, desenvolvendo sites e / ou usando o jQuery).
Resumo
Os prós e contras de cada um devem ser claros o suficiente agora. Se você deseja apenas usar a API JAXP padrão para atravessá-la, vá para o primeiro grupo de analisadores mencionado. Existem muitos deles. Qual escolher depende dos recursos que fornece (como a limpeza de HTML é fácil para você? Existem alguns ouvintes / interceptadores e limpadores específicos de marcas?) E a robustez da biblioteca (com que frequência é atualizada / mantida / corrigida? ) Se você gosta de testar o HTML da unidade, o HtmlUnit é o caminho a seguir. Se você deseja extrair dados específicos do HTML (que muitas vezes é o requisito do mundo real), o Jsoup é o caminho a seguir.