17

Estoy trabajando en un programa que descarga páginas HTML y luego selecciona parte de la información y la escribe en otro archivo.Extracción de texto de HTML Java

Quiero extraer la información que está entre las etiquetas de párrafo, pero solo puedo obtener una línea del párrafo. Mi código es el siguiente;

FileReader fileReader = new FileReader(file); 
BufferedReader buffRd = new BufferedReader(fileReader); 
BufferedWriter out = new BufferedWriter(new FileWriter(newFile.txt)); 
String s; 

while ((s = br.readLine()) !=null) { 
    if(s.contains("<p>")) { 
     try { 
      out.write(s); 
     } catch (IOException e) { 
     } 
    } 
} 

yo estaba tratando de añadir otro bucle while, que decirle al programa para escribir en el archivo hasta que la línea contiene la etiqueta </p>, diciendo;

while ((s = br.readLine()) !=null) { 
    if(s.contains("<p>")) { 
     while(!s.contains("</p>") { 
      try { 
       out.write(s); 
      } catch (IOException e) { 
      } 
     } 
    } 
} 

Pero esto no funciona. ¿Podría alguien ayudarme por favor?

+0

Definitivamente estamos viendo un error en el escape de SO de las etiquetas HTML. – Yishai

+0

¿Los está citando como código con palos de retroceso? – pjp

+0

Los analizadores HTML existen y hay muchos de ellos. –

Respuesta

1

Try (si no desea utilizar una biblioteca analizador HTML):


     FileReader fileReader = new FileReader(file); 
     BufferedReader buffRd = new BufferedReader(fileReader); 
     BufferedWriter out = new BufferedWriter(new FileWriter(newFile.txt)); 
     String s; 
     int writeTo = 0; 
     while ((s = br.readLine()) !=null) 
     { 
       if(s.contains("<p>")) 
       { 
         writeTo = 1; 

         try 
         { 
          out.write(s); 
        } 
         catch (IOException e) 
         { 

        } 
       } 
       if(s.contains("</p>")) 
       { 
         writeTo = 0; 

         try 
         { 
          out.write(s); 
        } 
         catch (IOException e) 
         { 

        } 
       } 
       else if(writeTo==1) 
       { 
         try 
         { 
          out.write(s); 
        } 
         catch (IOException e) 
         { 

        } 
       } 
} 
+1

¿Qué sucede si '

' y '

' están en la misma línea? En este caso, la cadena se escribirá dos veces.Supongo que realmente depende de la entrada. – pjp

+0

Puede agregar un estado para ver si ya ha escrito la línea antes de volver a escribirla. – pjp

9

jericho es uno de varios analizadores html Posible que podrían hacer que esta tarea sea fácil y seguro.

4

JTidy puede representar un documento HTML (incluso uno incorrecto) como un modelo de documento, por lo que el proceso de extracción del contenido de una etiqueta <p> es un proceso bastante más elegante que el uso manual del texto sin formato.

+0

Sí, es mejor evitar intentar analizar HTML manualmente – pjp

-2

Es posible que sólo esté utilizando la herramienta equivocada para el trabajo:

perl -ne "print if m|<p>| .. m|</p>|" infile.txt >outfile.txt 
+0

-1: respuesta incorrecta para la pregunta –

+0

Ese es un policía rubio. Aunque es un golpe tardío. – brianary

+2

Impactos finales en ambos sentidos :) –

0

Utilice un ParserCallback. Es una clase simple que se incluye con el JDK. Le notifica cada vez que se encuentra una nueva etiqueta y luego puede extraer el texto de la etiqueta. Ejemplo simple:

import java.io.*; 
import java.net.*; 
import javax.swing.text.*; 
import javax.swing.text.html.*; 
import javax.swing.text.html.parser.*; 

public class ParserCallbackTest extends HTMLEditorKit.ParserCallback 
{ 
    private int tabLevel = 1; 
    private int line = 1; 

    public void handleComment(char[] data, int pos) 
    { 
     displayData(new String(data)); 
    } 

    public void handleEndOfLineString(String eol) 
    { 
     System.out.println(line++); 
    } 

    public void handleEndTag(HTML.Tag tag, int pos) 
    { 
     tabLevel--; 
     displayData("/" + tag); 
    } 

    public void handleError(String errorMsg, int pos) 
    { 
     displayData(pos + ":" + errorMsg); 
    } 

    public void handleMutableTag(HTML.Tag tag, MutableAttributeSet a, int pos) 
    { 
     displayData("mutable:" + tag + ": " + pos + ": " + a); 
    } 

    public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet a, int pos) 
    { 
     displayData(tag + "::" + a); 
//  tabLevel++; 
    } 

    public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos) 
    { 
     displayData(tag + ":" + a); 
     tabLevel++; 
    } 

    public void handleText(char[] data, int pos) 
    { 
     displayData(new String(data)); 
    } 

    private void displayData(String text) 
    { 
     for (int i = 0; i < tabLevel; i++) 
      System.out.print("\t"); 

     System.out.println(text); 
    } 

    public static void main(String[] args) 
    throws IOException 
    { 
     ParserCallbackTest parser = new ParserCallbackTest(); 

     // args[0] is the file to parse 

     Reader reader = new FileReader(args[0]); 
//  URLConnection conn = new URL(args[0]).openConnection(); 
//  Reader reader = new InputStreamReader(conn.getInputStream()); 

     try 
     { 
      new ParserDelegator().parse(reader, parser, true); 
     } 
     catch (IOException e) 
     { 
      System.out.println(e); 
     } 
    } 
} 

Así que todo lo que necesita hacer es establecer una bandera booleana cuando se encuentre la etiqueta del párrafo. Luego, en el método handleText() extrae el texto.

19

jsoup

Otro analizador HTML Me gustó mucho el uso era jsoup. Puede obtener todos los elementos <p> en 2 líneas de código.

Document doc = Jsoup.connect("http://en.wikipedia.org/").get(); 
Elements ps = doc.select("p"); 

Luego, escriba en un archivo en una línea más

out.write(ps.text()); //it will append all of the p elements together in one long string 

o si los quieres en líneas separadas que se pueden recorrer los elementos y escribir a cabo por separado.

+0

Si un documento no utiliza etiquetas 'p' (marca no semántica), supongo que esto no funcionará –

+1

@ sinθ La pregunta solicitó explícitamente elementos' p'. Esta respuesta es acertada. –

+0

Gracias @Danny, I ♥ esta sopa! –

0

Pruebe esto.

public static void main(String[] args) 
{ 
    String url = "http://en.wikipedia.org/wiki/Big_data"; 

    Document document; 
    try { 
     document = Jsoup.connect(url).get(); 
     Elements paragraphs = document.select("p"); 

     Element firstParagraph = paragraphs.first(); 
     Element lastParagraph = paragraphs.last(); 
     Element p; 
     int i=1; 
     p=firstParagraph; 
     System.out.println("* " +p.text()); 
     while (p!=lastParagraph){ 
      p=paragraphs.get(i); 
      System.out.println("* " +p.text()); 
      i++; 
     } 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
} 
+0

¿Qué es este 'Elemento' y 'Documento'? ¿Es esto un analizador de terceros? Mostrar las líneas de importación también – James

Cuestiones relacionadas