Java HTML Parsing [chiuso]
-
04-07-2019 - |
Domanda
Sto lavorando a un'app che raccoglie i dati da un sito Web e mi chiedevo come avrei dovuto fare per ottenere i dati. In particolare, ho bisogno dei dati contenuti in una serie di tag div che utilizzano una specifica classe CSS - Attualmente (a scopo di test) sto solo controllando
div class = "classname"
in ogni riga di HTML - Funziona, ma non posso fare a meno di pensare che ci sia una soluzione migliore là fuori.
Esiste un modo carino in cui dare a una classe una riga di HTML e avere dei metodi piacevoli come:
boolean usesClass(String CSSClassname);
String getText();
String getLink();
Soluzione
Diversi anni fa ho usato JTidy per lo stesso scopo:
" JTidy è una porta Java di HTML Tidy, un correttore di sintassi HTML e una bella stampante. Come il cugino non Java, JTidy può essere utilizzato come strumento per ripulire HTML non valido e difettoso. Inoltre, JTidy fornisce un'interfaccia DOM al documento in fase di elaborazione, il che rende efficace l'utilizzo di JTidy come parser DOM per HTML nel mondo reale.
JTidy è stato scritto da Andy Quick, che in seguito si è dimesso dalla posizione di manutentore. Ora JTidy è gestito da un gruppo di volontari.
Ulteriori informazioni su JTidy sono disponibili sulla pagina del progetto JTidy SourceForge. "
Altri suggerimenti
Un'altra libreria che potrebbe essere utile per l'elaborazione HTML è jsoup. Jsoup tenta di pulire HTML non valido e consente l'analisi html in Java utilizzando jQuery come sintassi del selettore di tag.
Il problema principale, come affermato dai precedenti commenti, è l'HTML non valido, quindi è necessario un html cleaner o un convertitore HTML-XML. Una volta ottenuto il codice XML (XHTML) ci sono molti strumenti per gestirlo. Potresti ottenerlo con un semplice gestore SAX che estrae solo i dati necessari o qualsiasi metodo basato su albero (DOM, JDOM, ecc.) Che ti consenta persino di modificare il codice originale.
Ecco un codice di esempio che utilizza HTML Cleaner per ottenere tutti i DIV che utilizzano una determinata classe e stampare tutto il contenuto del testo al suo interno.
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
/**
* @author Fernando Miguélez Palomo <fernandoDOTmiguelezATgmailDOTcom>
*/
public class TestHtmlParse
{
static final String className = "tags";
static final String url = "http://www.stackoverflow.com";
TagNode rootNode;
public TestHtmlParse(URL htmlPage) throws IOException
{
HtmlCleaner cleaner = new HtmlCleaner();
rootNode = cleaner.clean(htmlPage);
}
List getDivsByClass(String CSSClassname)
{
List divList = new ArrayList();
TagNode divElements[] = rootNode.getElementsByName("div", true);
for (int i = 0; divElements != null && i < divElements.length; i++)
{
String classType = divElements[i].getAttributeByName("class");
if (classType != null && classType.equals(CSSClassname))
{
divList.add(divElements[i]);
}
}
return divList;
}
public static void main(String[] args)
{
try
{
TestHtmlParse thp = new TestHtmlParse(new URL(url));
List divs = thp.getDivsByClass(className);
System.out.println("*** Text of DIVs with class '"+className+"' at '"+url+"' ***");
for (Iterator iterator = divs.iterator(); iterator.hasNext();)
{
TagNode divElement = (TagNode) iterator.next();
System.out.println("Text child nodes of DIV: " + divElement.getText().toString());
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Potresti essere interessato a TagSoup , un Java Parser HTML in grado di gestire HTML non valido. I parser XML funzionerebbero solo su XHTML ben formato.
Il progetto HTMLParser ( http://htmlparser.sourceforge.net/ ) potrebbe essere una possibilità. Sembra essere abbastanza decente nella gestione di HTML non valido. Il frammento seguente dovrebbe fare ciò di cui hai bisogno:
Parser parser = new Parser(htmlInput);
CssSelectorNodeFilter cssFilter =
new CssSelectorNodeFilter("DIV.targetClassName");
NodeList nodes = parser.parse(cssFilter);
Jericho: http://jericho.htmlparser.net/docs/index.html
Facile da usare, supporta HTML non ben formato, molti esempi.
HTMLUnit potrebbe essere di aiuto. Fa anche molte più cose.
Non dimentichiamo Jerry , il suo jQuery in java: una libreria Java veloce e concisa che semplifica l'analisi, l'attraversamento e la manipolazione di documenti HTML; include l'uso dei selettori css3.
Esempio:
Jerry doc = jerry(html);
doc.$("div#jodd p.neat").css("color", "red").addClass("ohmy");
Esempio:
doc.form("#myform", new JerryFormHandler() {
public void onForm(Jerry form, Map<String, String[]> parameters) {
// process form and parameters
}
});
Naturalmente, questi sono solo alcuni esempi rapidi per avere la sensazione di come tutto sembra.
Il progetto nu.validator
è un eccellente HTML ad alte prestazioni parser che non taglia gli angoli in modo corretto.
Il parser HTML Validator.nu è un'implementazione dell'algoritmo di analisi HTML5 in Java. Il parser è progettato per funzionare come sostituto drop-in del parser XML in applicazioni che già supportano il contenuto XHTML 1.x con un parser XML e utilizzano SAX, DOM o XOM per interfacciarsi con il parser. Funzionalità di basso livello viene fornita per le applicazioni che desiderano eseguire il proprio IO e supportare document.write () con script. Il core del parser si compila su Google Web Toolkit e può essere tradotto automaticamente in C ++. (La funzionalità di traduzione C ++ è attualmente utilizzata per il porting del parser per l'uso in Gecko.)
Puoi anche utilizzare XWiki HTML Cleaner :
Utilizza HTMLCleaner e lo estende per generare contenuti XHTML 1.1 validi.
Se il tuo HTML è ben formato, puoi facilmente utilizzare un parser XML per fare il lavoro per te ... Se stai solo leggendo, SAX sarebbe l'ideale.