从 HTML Java 中提取文本
Posted
技术标签:
【中文标题】从 HTML Java 中提取文本【英文标题】:Text Extraction from HTML Java 【发布时间】:2010-11-26 01:05:54 【问题描述】:我正在开发一个下载 html 页面然后选择一些信息并将其写入另一个文件的程序。
我想提取段落标签之间的信息,但我只能得到段落的一行。我的代码如下;
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)
但这不起作用。有人可以帮忙吗。
【问题讨论】:
我们肯定看到了 SO 转义 HTML 标签的错误。 您是否将它们作为带有反引号的代码引用? HTML 解析器确实存在,而且数量很多。 【参考方案1】:jsoup
另一个我非常喜欢使用的 html 解析器是 jsoup。您可以在 2 行代码中获取所有 <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
或者,如果您希望它们在单独的行中,您可以遍历元素并单独写出它们。
【讨论】:
如果文档不使用p
标签(非语义标记),我认为这不起作用
@sinθ 该问题明确要求p
元素。这个答案是正确的。
谢谢@Danny,我♥这汤!【参考方案2】:
jericho 是几个可能的 html 解析器之一,它可以使这项任务既简单又安全。
【讨论】:
【参考方案3】:JTidy 可以将 HTML 文档(甚至是格式错误的文档)表示为文档模型,这使得提取 <p>
标记内容的过程比手动遍历原始文本更为优雅。
【讨论】:
【参考方案4】:尝试(如果您不想使用 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)
【讨论】:
如果<p>
和</p>
在同一行会怎样?在这种情况下,字符串将被写出两次。我想这真的取决于输入。
你可以添加一些状态,看看你是否已经写出了一行,然后再写出来。【参考方案5】:
我已经成功使用 TagSoup 和 XPath 解析 HTML。
http://home.ccil.org/~cowan/XML/tagsoup/
【讨论】:
【参考方案6】:使用 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() 方法中提取文本。
【讨论】:
【参考方案7】:试试这个。
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();
【讨论】:
这个“元素”和“文档”是什么。这是任何第三方解析器吗?也显示导入行【参考方案8】:您可能只是在工作中使用了错误的工具:
perl -ne "print if m|<p>| .. m|</p>|" infile.txt >outfile.txt
【讨论】:
这是一个公平的警察。不过有点晚了。以上是关于从 HTML Java 中提取文本的主要内容,如果未能解决你的问题,请参考以下文章