17

Я работаю над программой, которая загружает HTML-страницы, а затем выбирает часть информации и записывает ее в другой файл.Извлечение текста из HTML Java

Я хочу извлечь информацию, которая находится между тегами абзаца, но я могу получить только одну строку абзаца. Мой код выглядит следующим образом.

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) { 
     } 
    } 
} 

я пытался добавить еще один цикл WHILE, который бы сказать программу, чтобы сохранить записи в файл, пока строка не содержит </p> тега, говоря;

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

Но это не сработает. Может кто-то помочь.

+0

Мы определенно видим ошибку в экранировании HTML-тегов HTML. – Yishai

+0

Вы цитируете их как код с обратными окнами? – pjp

+0

HTML-парсеры существуют и их много. – 2009-09-06 18:09:42

ответ

1

Try (если вы не хотите использовать 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

Что произойдет, если '

' и'

'находятся в одной строке? В этом случае строка будет выписана дважды.Я думаю, это действительно зависит от ввода. – pjp

+0

Вы можете добавить какое-то состояние, чтобы узнать, вы уже выписали строку, прежде чем записывать ее снова. – pjp

9

jericho является одним из нескольких HTML анализаторами Возможное, которые могли бы сделать эту задачу легко и безопасно.

4

JTidy может представлять собой документ HTML (даже некорректный) в качестве модели документа, что делает процесс извлечения содержимого тега <p> более элегантным процессом, чем ручное разглаживание исходного текста.

+0

Да, лучше не пытаться разобрать HTML вручную – pjp

-2

Вы можете просто использовать неправильный инструмент для работы:

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

-1: неправильный ответ на вопрос –

+0

Это честный полицейский. Тем не менее, вид позднего хита. – brianary

+2

Late hits go both ways :) –

0

Используйте ParserCallback. Его простой класс, который включен в JDK. Он уведомляет вас каждый раз, когда найден новый тег, а затем вы можете извлечь текст тега. Простой пример:

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); 
     } 
    } 
} 

Итак, все, что вам нужно сделать, это установить булевский флаг при обнаружении тега абзаца. Затем в методе handleText() вы извлекаете текст.

19

jsoup

Другой HTML Parser Мне очень понравилось, используя был jsoup. Вы можете получить все элементы <p> в 2 строках кода.

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

Затем записать его в файл более одной строки

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

или если вы хотите их на отдельных строках вы можете перебирать элементы и записать их отдельно.

+0

Если в документе не используются теги 'p' (не семантическая разметка вверх), я предполагаю, что это не сработает –

+1

@ sinθ Вопрос явно задан для элементов' p'. Этот ответ правильный. –

+0

Спасибо @ Danny, я ♥ этот суп! –

0

Попробуйте это.

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

Что это за «Элемент» и «Документ». Это какой-то сторонний парсер? Показать строки импорта тоже – James

 Смежные вопросы

  • Нет связанных вопросов^_^