17

私は、HTMLページをダウンロードし、いくつかの情報を選択して別のファイルに書き込むプログラムに取り組んでいます。HTMLからのテキスト抽出Java

段落タグの間にある情報を抽出したいが、段落の1行しか取得できない。私のコードは以下の通りです。私が言って、ラインが</p>タグを含むまでファイルに書き込みを維持するためのプログラムを言うだろう、別のwhileループを追加しようとしていた

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

しかし、これは機能しません。誰かが助けてくれますか?

+0

SOのHTMLタグのエスケープに間違いがあります。 – Yishai

+0

バッククォートでコードとして引用していますか? – pjp

+0

HTMLパーサーは存在し、それらの多くがあります。 –

答えて

1

てみてください(あなたが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

」と「

」が同じ行にある場合はどうなりますか?この場合、文字列は2回書き出されます。私はそれが本当に入力に依存すると思う。 – 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

最近のヒットは両方向になります:) –

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パーサは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 

1行でファイルに書き出したり、別の行にそれらをしたい場合は、要素を反復処理し、それらを別々に書き出すことができます。

+0

ドキュメントが 'p'タグ(非意味マークアップ)を使用しない場合、私はこれがうまくいかないと仮定します。 –

+1

@sinθQuestionは明示的に' p'要素を求めました。この答えは正しかったです。 –

+0

ありがとう@ダニー、私はこのスープ! –

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