Analizar HTML en Android


83

Estoy tratando de analizar HTML en Android desde una página web, y como la página web no está bien formada, obtengo SAXException.

¿Hay alguna forma de analizar HTML en Android?


Sospecho que la dependencia de Rhino hará que htmlunit sea un infierno para compilar en Android, pero podrías intentarlo ... Además, algún otro analizador HTML no estricto como soup podría funcionar.
alex

Me pregunto si aquí se puede utilizar webkit.
ziya

Respuestas:


71

Acabo de encontrar este problema. Probé algunas cosas, pero me decidí por usar JSoup . El frasco tiene aproximadamente 132k, lo cual es un poco grande, pero si descarga la fuente y elimina algunos de los métodos que no utilizará, entonces no es tan grande.
=> Lo bueno de esto es que manejará HTML mal formado

Aquí hay un buen ejemplo de su sitio.

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

//http://jsoup.org/cookbook/input/load-document-from-url
//Document doc = Jsoup.connect("http://example.com/").get();

Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
  String linkHref = link.attr("href");
  String linkText = link.text();
}

1
Puede intentar incluir el jar completo y ejecutar ProGuard en su aplicación en su versión de producción para eliminar el código no utilizado.
Andrew Mackenzie

3
PRECAUCIÓN: JSoup es muy, muy lento.
Kevin

@kevin una fuente para esa afirmación? Es posible que tenga habilitada la depuración.
goetzc

¿Qué pasa con el contenido cargado dinámicamente usando un script java durante la representación de la página html en el lado del cliente? ¿Jsoup también mostrará este contenido?
MikeL

56

¿Ha intentado usar Html.fromHtml (fuente) ?

Creo que la clase es bastante liberal con respecto a la calidad de la fuente (usa TagSoup internamente, que fue diseñado teniendo en cuenta el HTML malo de la vida real). Sin embargo, no admite todas las etiquetas HTML, pero viene con un controlador que puede implementar para reaccionar en las etiquetas que no comprende.


1
Esto es muy simple, no puedo buscar cosas exactas (como XPATH)

atención por favor. esto será "Suspendiendo todos los hilos". Me enfrento a que cuando obtengo un json con texto en formato html. No hubo ningún problema para mostrar el texto html correctamente, pero después de usar html.fromhtml () me enfrento a esto.
David

23
String tmpHtml = "<html>a whole bunch of html stuff</html>";
String htmlTextStr = Html.fromHtml(tmpHtml).toString();

agradable y simple, sin complementos, ¡me encanta! tnxs
RonEskinder

1
Como nota: llamar toString()al Spannedobjeto devuelto Html.fromHtml(str)hará que muchas de las HTMLetiquetas no funcionen (incluidas <i> <u> <b>). Entonces, si está configurando una vista de texto, simplemente haga:myTextView.setText(Html.fromHtml(str))
Sakiboy

@Sakiboy Tienes razón. Además de esto, hay muchas otras etiquetas con las que no funciona Html.fromHtml(). Mira esto stackoverflow.com/a/3150456/1987045
Rahul Raveendran

increíble, exactamente lo que quería, mi desarrollador del lado del servidor me estaba enviando html, ahora puedo convertirlo fácilmente en una cadena sin procesar gracias
Zulqurnain Jutt

3

Todos sabemos que la programación tiene infinitas posibilidades. Hay varias soluciones disponibles para un solo problema, así que creo que todas las soluciones anteriores son perfectas y pueden ser útiles para alguien, pero para mí esta me salvó el día.

Entonces el código es así

  private void getWebsite() {
    new Thread(new Runnable() {
      @Override
      public void run() {
        final StringBuilder builder = new StringBuilder();

        try {
          Document doc = Jsoup.connect("http://www.ssaurel.com/blog").get();
          String title = doc.title();
          Elements links = doc.select("a[href]");

          builder.append(title).append("\n");

          for (Element link : links) {
            builder.append("\n").append("Link : ").append(link.attr("href"))
            .append("\n").append("Text : ").append(link.text());
          }
        } catch (IOException e) {
          builder.append("Error : ").append(e.getMessage()).append("\n");
        }

        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            result.setText(builder.toString());
          }
        });
      }
    }).start();
  }

Solo tiene que llamar a la función anterior en onCreate MethodsuMainActivity

Espero que este también sea útil para ustedes.

Lea también el blog original en Medium


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.