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

내가 선 말함으로써 </p> 태그를 포함 할 때까지 파일에 기록 유지하기 위해 프로그램을 말할 것 또 다른 while 루프를 추가하려고했다;

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

'

'과 '

'이 같은 줄에 있으면 어떻게됩니까? 이 경우 문자열은 두 번 출력됩니다.나는 그것이 입력에 정말로 달려 있다고 생각한다. – pjp

+0

다시 쓰려면 먼저 상태를 추가하여 이미 작성했는지 확인할 수 있습니다. – pjp

9

jericho이 작업이 쉽고 안전을 모두 할 수있는 몇 가지 가망 HTML 파서 중 하나입니다.

4

JTidy은 문서 모델로 HTML 문서 (심지어 형식이 잘못된 것)를 나타낼 수 있으므로 <p> 태그의 내용을 추출하는 프로세스가 원시 텍스트를 수동으로 썽킹하는 것보다 훨씬 세련된 프로세스를 만듭니다. 나는 HTML을 구문 분석하는 XPath를 TagSoup &를 사용하여 성공을 거두었습니다

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

예 수동으로 HTML 구문을 분석하지 않는 것이 가장 좋습니다. – pjp

-2

당신은 작업에 대한 잘못된 도구를 사용 할 수있다.

http://home.ccil.org/~cowan/XML/tagsoup/

+0

-1 : 질문에 대한 대답이 잘못되었습니다. –

+0

그건 공정한 경찰입니다. 늦은 히트의 종류. – brianary

+2

늦은 히트는 두 가지가 있습니다 :) –

0

:

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> 요소를 얻을 수 있습니다.

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

감사합니다 @ 대니, ♥이 수프! –

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

'요소'및 '문서'는 무엇입니까? 이것은 제 3 자 파서입니까? 가져 오기 행 표시 – James