信息检索快结课了,于是开始琢磨着做个什么东西,应用一下所学到的知识。做什么呢?
搭一个完整的搜索引擎?虽然有luence和nutch等开源工具包的支持,可是时间上似乎不够。做网络爬虫?做网页去重?好像算法都挺复杂的。思来想去,最后我选定了“正文提取”,主要是觉得这个挺简单,应该很快就能做出来。
然而实际情况与想法总是差距甚远,从星期五到星期天下午,断断续续的,我一直在不停做这个东西。最后以也没做出什么成果,只有一些零星的思路,NND,以后等时机成熟了一定要搞出来!!
- JTidy:HTML->XML 要分析源文件,就得先将其规范化。老师课件上讲的工具是JTidy,我用的就是这个。据说它可以方便的对HTML进行清理,生成XHTML或XML文件。网络上有关JTidy的资料少得可怜,遇到了问题连资料都没的查,只有非常简洁的API和源代码可供参考。也难怪,最新版本的JTidy竟然是2001年8月发布的,都已经快8年了,莫非这工具已经终止开发了? 典型的代码类似于下面,输入文件为1001.htm,输出文件为output.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
package test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.w3c.tidy.Configuration; import org.w3c.tidy.Tidy; public class JTidyTest { public static void main(String[] args) { Tidy tidy = new Tidy(); // obtain a new Tidy instance tidy.setXmlOut(true); // set desired config options using tidy setters tidy.setQuoteNbsp(false); tidy.setQuoteMarks(false); tidy.setQuoteAmpersand(false); tidy.setCharEncoding(Configuration.RAW); try { FileInputStream in = new FileInputStream(new File("1001.htm")); FileOutputStream out = new FileOutputStream(new File("output.xml")); tidy.parseDOM(in, out); // run tidy, providing an input and output stream } catch (IOException e) { e.printStackTrace(); } } }
转换完以后,我用firefox打开生成的XML文件来检验转换是否正确,发现它对很多网页都不能生成正确的结果。比如HTML源文件中有这样一段代码
1 2 3
<script type="text/javascript"> document.write('| <a href="https://passport.baidu.com/?login&tpl=sp&tpl_reg=sp&u=http://hi.baidu.com' + encodeURIComponent('/icycandy') + '">登录</a>'); </script>
转换后的XML仍然有这段代码。用firefox打开,报错说“XML解析错误:未组织好”,大概是指&tpl中的tpl没有定义。这样的情况大多数都出现在链接中,那么可以把HTML中的所有链接用HTML Parser先去掉,然后再用JTidy处理。然而很可惜的是,HTML Parser对于不规范的HTML文档也是无能为力。也许用正则表达式来过虑掉链接是一种方法。后来我又担心如果正文中出现&tpl这种情况该怎么办?实际上这种担心是多余的,正文中的&一般会被替换为&,就像双引号一般被替换为"一样。
另 外一个头疼的问题是中文编码,中文转换后在XML中显示为乱码。网上很多贴子说中文乱码可 以通过设置tidy的编码解决:tidy.setCharEncoding(Configuration.RAW);或 tidy.setCharEncoding(Configuration.ISO2022);。这样生成的XML文件编码格式是GB2312,用 UltraEdit打开确实能显示出中文了,可是用firefox打开仍然是乱码。而下一步从XML中提取信息时,DOM4J只接受UTF-8的编码格 式。我的解决办法是另外写一个类,按字节从XML中读入字符,然后用UTF-8写回到文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
package test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class GB2UTF { String fileName; public GB2UTF(String fileName) { this.fileName = fileName; } public void convert() { try { File f = new File(fileName); FileInputStream in = new FileInputStream(f); InputStreamReader reader = new InputStreamReader(in, "GB2312");// 以GB2312编码读入文件 File tmpFile = File.createTempFile("GB2312", ".xml");// 创建临时文件,以"GB2312"为前缀,".html"为后缀 FileOutputStream out = new FileOutputStream(tmpFile);// 将文件转化为字符流 OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8");// 目标编码为UTF-8 writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); char[] buffer = new char[10240]; // 文件缓冲区 int len = 0; // 使用字符读取方式,循环读取源文件内容 while ((len = reader.read(buffer)) != -1) // 转换后写入目标文件中 { writer.write(buffer, 0, len); } writer.close(); reader.close(); out.close(); in.close(); f.delete(); // 删除原文件 tmpFile.renameTo(f); // 用原文件名保存转换后的文件 } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new GB2UTF("output.xml").convert(); } }
- DOM4J:XML->TXT因为上一步的XML不能正确生成,所以这一步我没有具体实践。如果上一步能生成规范的XML,那么可以利用DOM4J从XML文件创建出一棵DOM树。然后遍历树中的节点,判断该节点是否包含了正文。如果不是,就删掉该节点。从而最后树中剩下的节点就包含了网页的正文,直接从中抽取出信息即可。非正文信息一般是广告、链接群、字体样式等。












你代码外面的边框是怎么弄的?百度空间有吗?
回复ByteChen:新写了一篇日志,关于代码边框的