Quais são os prós e os contras dos principais analisadores Java HTML? [fechadas]

175

Pesquisando no SO e no Google, descobri que existem alguns analisadores HTML de Java que são consistentemente recomendados por várias partes. Infelizmente, é difícil encontrar informações sobre os pontos fortes e fracos das várias bibliotecas. Espero que algumas pessoas tenham passado algum tempo comparando essas bibliotecas e possam compartilhar o que aprenderam.

Aqui está o que eu vi:

E se houver um grande analisador que eu tenha perdido, eu adoraria ouvir sobre seus prós e contras também.

Obrigado!

Avi Linho
fonte

Respostas:

223

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.Documentretorno 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.Documentsabem como é doloroso atravessar o DOM usando as APIs NodeListe detalhadas Node. É verdade que XPathfacilita 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.

BalusC
fonte
Há um enorme favor / contra que é omitido aqui: Jericho é o único analisador que conheço que permite manipular HTML desagradável, preservando a formatação de espaço em branco e a incorreta do HTML (se houver).
Adam Gent
3
Jsoupé bom. Eu tentei fazer a interface com outro módulo que funciona com org.w3c.dom.*API. Descobriu que Jsoup não obedece o org.w3c.dom.*contrato
Thamme Gowda
13

Este artigo compara certos aspectos dos seguintes analisadores:

  • NekoHTML
  • JTidy
  • TagSoup
  • HtmlCleaner

Não é de forma alguma um resumo completo, e é de 2008. Mas você pode achar útil.

Matt Solnit
fonte
Esta é uma resposta apenas para link. Você pode adicionar os detalhes pertinentes aqui?
Reintegrar Monica - notmaynard
7

Adicione o validador.nu HTML Parser , uma implementação do algoritmo de análise HTML5 em Java, à sua lista.

No lado positivo, ele foi projetado especificamente para corresponder ao HTML5 e no coração do validador do HTML5, com grande probabilidade de corresponder ao comportamento de análise de futuros navegadores com um grau muito alto de precisão.

No lado negativo, nenhuma análise herdada dos navegadores funciona exatamente assim e, como o HTML5 ainda está em rascunho, está sujeito a alterações.

Na prática, esses problemas afetam apenas casos de canto obscuros e, para todos os efeitos práticos, são um excelente analisador.

Alohci
fonte
7

Eu achei o Jericho HTML Parser muito bem escrito, atualizado (o que muitos dos analisadores não são), sem dependências e fácil de usar.

MJB
fonte
6

Vou acrescentar à resposta do @MJB depois de trabalhar com a maioria das bibliotecas de análise de HTML em Java. Existe um enorme benefício / omissão: analisadores que preservam a formatação e a incorreta do HTML na entrada e na saída.

Essa é a maioria dos analisadores quando você altera o documento, eliminando os espaços em branco, os comentários e as incorretas do DOM, principalmente se eles forem uma biblioteca semelhante a XML.

Jericho é o único analisador que conheço que permite manipular HTML desagradável, preservando a formatação de espaço em branco e a incorreta do HTML (se houver).

Adam Gent
fonte
3

Duas outras opções são HTMLCleaner e HTMLParser .

Eu tentei a maioria dos analisadores aqui para uma estrutura de extração de dados / rastreador que venho desenvolvendo. Eu uso o HTMLCleaner para a maior parte do trabalho de extração de dados. Isso ocorre porque ele suporta um dialeto razoavelmente moderno de HTML, XHTML, HTML 5, com espaços para nome e suporta DOM, portanto, é possível usá-lo com a implementação XPath integrada em Java .

É muito mais fácil fazer isso com o HTMLCleaner do que alguns dos outros analisadores: JSoup, por exemplo, suporta uma interface do tipo DOM, em vez de DOM, portanto, é necessário algum assembly . Jericho tem uma interface de linha SAX, portanto, novamente é necessário algum trabalho, embora Sujit Pal tenha uma boa descrição de como fazer isso mas no final o HTMLCleaner funcionou melhor.

Eu também uso HTMLParser e Jericho para uma tarefa de extração de tabela, que substituiu algum código escrito usando libhtml-tableextract-perl do Perl . Uso HTMLParser para filtrar o HTML da tabela e, em seguida, uso Jericho para analisá-lo. Eu concordo com os comentários de MJB e Adam de que Jericó é bom em alguns casos porque preserva o HTML subjacente. Ele possui um tipo de interface SAX não padrão, portanto, para o processamento XPath, o HTMLCleaner é melhor.

A análise de HTML em Java é um problema surpreendentemente difícil, pois todos os analisadores parecem ter problemas com certos tipos de conteúdo HTML malformado.

Mark Butler
fonte