Menu

viernes, 10 de septiembre de 2010

HTML Parser en Java

Bueno ahora traigo un problema y una solución. Los pongo en contexto, hace un tiempo necesitaba analizar el HTML de una pagina web desde un web service dejemos hasta hay después les hablo de mi odisea jboss web service eclipse, jejjeje, como hacerlo?, como analizar el HTML de una pagina web, bueno al parecer cuando escucho analizar texto se me ocurren muchas cosas pero cual de estas ¨cosas¨ es la mas eficiente?.

La primera posible solución fue analizar el HTML como una cadena de texto y extraer las etiquetas y atributos que necesitaba mediante un algoritmo de búsqueda bruta de pronto con alguna heurística, pero de todas formas no me pareció debía encontrar otra forma para no manejar funciones de cadena.

Sin salir de la idea de analizar la cadena HTML pensé luego, por que no utilizar regular expressions (regex).?, puede servir es mas este es un ejemplo que utilice http://www.javamex.com/tutorials/regular_expressions/example_scraping_html.shtml


import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;

public class MainClass {
private static void parse(URL url, String encoding) throws IOException {
ParserGetter kit = new ParserGetter();
HTMLEditorKit.Parser parser = kit.getParser();
InputStream in = url.openStream();
InputStreamReader r = new InputStreamReader(in, encoding);
HTMLEditorKit.ParserCallback callback = new Outliner(new OutputStreamWriter(System.out));
parser.parse(r, callback, true);
}

public static void main(String[] args) throws Exception {

ParserGetter kit = new ParserGetter();
HTMLEditorKit.Parser parser = kit.getParser();

String encoding = "ISO-8859-1";
URL url = new URL("http://www.java2s.com");
InputStream in = url.openStream();
InputStreamReader r = new InputStreamReader(in, encoding);
// parse once just to detect the encoding
HTMLEditorKit.ParserCallback doNothing = new HTMLEditorKit.ParserCallback();
parser.parse(r, doNothing, false);

parse(url, encoding);
}

}

class Outliner extends HTMLEditorKit.ParserCallback {

private Writer out;

private int level = 0;

private boolean inHeader = false;

private static String lineSeparator = System.getProperty("line.separator", "\r\n");

public Outliner(Writer out) {
this.out = out;
}

public void handleStartTag(HTML.Tag tag, MutableAttributeSet attributes, int position) {

int newLevel = 0;
if (tag == HTML.Tag.H1)
newLevel = 1;
else if (tag == HTML.Tag.H2)
newLevel = 2;
else if (tag == HTML.Tag.H3)
newLevel = 3;
else if (tag == HTML.Tag.H4)
newLevel = 4;
else if (tag == HTML.Tag.H5)
newLevel = 5;
else if (tag == HTML.Tag.H6)
newLevel = 6;
else
return;

this.inHeader = true;
try {
if (newLevel > this.level) {
for (int i = 0; i < newLevel - this.level; i++) {
out.write("
    " + lineSeparator + "
  • ");
    }
    } else if (newLevel < this.level) {
    for (int i = 0; i < this.level - newLevel; i++) {
    out.write(lineSeparator + "
" + lineSeparator);
}
out.write(lineSeparator + "
  • ");
    } else {
    out.write(lineSeparator + "
  • ");
    }
    this.level = newLevel;
    out.flush();
    } catch (IOException ex) {
    System.err.println(ex);
    }

    }

    public void handleEndTag(HTML.Tag tag, int position) {

    if (tag == HTML.Tag.H1 || tag == HTML.Tag.H2 || tag == HTML.Tag.H3 || tag == HTML.Tag.H4
    || tag == HTML.Tag.H5 || tag == HTML.Tag.H6) {
    inHeader = false;
    }

    // work around bug in the parser that fails to call flush
    if (tag == HTML.Tag.HTML)
    this.flush();

    }

    public void handleText(char[] text, int position) {

    if (inHeader) {
    try {
    out.write(text);
    out.flush();
    } catch (IOException ex) {
    System.err.println(ex);
    }
    }

    }

    public void flush() {
    try {
    while (this.level-- > 0) {
    out.write(lineSeparator + "");
    }
    out.flush();
    } catch (IOException e) {
    System.err.println(e);
    }
    }

    private static void parse(URL url, String encoding) throws IOException {
    ParserGetter kit = new ParserGetter();
    HTMLEditorKit.Parser parser = kit.getParser();
    InputStream in = url.openStream();
    InputStreamReader r = new InputStreamReader(in, encoding);
    HTMLEditorKit.ParserCallback callback = new Outliner(new OutputStreamWriter(System.out));
    parser.parse(r, callback, true);
    }

    }

    class ParserGetter extends HTMLEditorKit {
    public HTMLEditorKit.Parser getParser() {
    return super.getParser();
    }
    }
  • No hay comentarios.: