您的位置:首页 > Web前端 > HTML

利用HtmlParse抽取网页正文内容

2012-03-03 13:23 477 查看
  最近在做有关自然语言抽取方面的研究,接触到了很多相关的工具包,尤其是关于html中格式文本的抽取,虽然网上有很多相关高效算法,但我只想尽量简单快捷地将我需要的内容从html中抽取出来。因此,我只需要一个轻量级的工具,满足我的需求就行了。之前在网上搜索了一下,主要有Jtidy和HtmlParser这两个工具,都是java的。Jtidy的主页是:http://jtidy.sourceforge.net/。我最早尝试使用的就是Jtidt,由于相关文档较少,中文文档就更少了,我感觉很难上手。于是,我转向了HtmlParse,虽然同样有文档较少的问题,但我发现,这是一个比较容易上手的工具,用了HtmlParse很快就达到了我的需求。HtmlParse的主页地址是:http://htmlparser.sourceforge.net/,最后更新是2006年9月17日,虽然很老,但是应付一般的需求还是可以的。

在这里,我以我抽取某网站上GRE作文为例子,写了一点东西,希望能对正在使用HtmlParse的朋友有所帮助。

  


  这是抽取之前的页面,我抽取的便是它的正文部分。

  下面是抽取后的截图:

  



  第一步 首先要实例化一个Parser

  HTMLParser的核心模块是org.htmlparser.Parser类,这个类实际完成了对于HTML页面的分析工作。这个类有下面几个构造函数:

public Parser ();
public Parser (Lexer lexer, ParserFeedback fb);
public Parser (URLConnection connection, ParserFeedback fb) throws ParserException;
public Parser (String resource, ParserFeedback feedback) throws ParserException;
public Parser (String resource) throws ParserException;
public Parser (Lexer lexer);
public Parser (URLConnection connection) throws ParserException;
//一个静态类
public static Parser createParser (String html, String charset);
  其中用的较多的应该是使用最多的是通过一个URLConnection或者一个保存有网页内容的字符串来初始化Parser,显然用得最多的是最后两个构造函数。在我的例子中,由于我是把几十个网页一起打包下载了下来,因此,在此处我使用的是最后一种静态类的构造方法:

Parser parser = Parser.createParser(str, "utf-8");


  其中str是页面内容的字符串,”utf-8”是编码方式。


  第二步 观察你需要抽取的内容,建立过滤器

  HtmlParse分析和抽取的html文档的原理是将整个html文档解析成一个DOM(Document Object Mode)树,通过遍历树上的所有节点,实现文本的抽取。因此,在使用了filter后,Parser返回的是满足filter条件的节点类(Node)实例的一个集合。在HtmlParse中Node是信息保存的数据类型基础。Node中包含了许多对树的操作的方法,对于具体问题可以去官网上看文档,此处就不再赘述了。

Filter就是对于结果进行过滤,取得需要的内容。HTMLParser在org.htmlparser.filters包之内一共定义了16个不同的Filter,也可以分为几类。

  判断类Filter:
TagNameFilter;
HasAttributeFilter;
HasChildFilter;
HasParentFilter;
HasSiblingFilter;
IsEqualFilter;
  逻辑运算Filter:
AndFilter;
NotFilter;
OrFilter;
XorFilter;
  其他Filter:
NodeClassFilter;
StringFilter;
LinkStringFilter;
LinkRegexFilter;
RegexFilter;
CssSelectorNodeFilter;

所有的Filter类都实现了org.htmlparser.NodeFilter接口。这个接口只有一个主要函数:

boolean accept (Node node);


  各个子类分别实现这个函数,用于判断输入的Node是否符合这个Filter的过滤条件,如果符合,返回true,否则返回false。

现在回到我们的例子中,以下是我的代码:
try{
    Parser parser = Parser.createParser(str, "utf-8");
    NodeFilter filter = new TagNameFilter("p");
    NodeList nodes = parser.extractAllNodesThatMatch(filter);
    //判断文件是否存在
    File file = new File(outpaths);
    if(file.exists())
    {
      file.delete();
    }
    if(nodes!=null)
    {
      for(int j = 0;j < nodes.size();j++)
      {
        if(j < 7)
        {
          continue;
        }
        //返回出一个p节点
        Node TextNode = (Node)nodes.elementAt(j);
        //取出Node的取得纯文本信息。
        tmp =TextNode.toPlainTextString();
        //此处使用了正则表达式,目的是去除取出的文本中的html的一些空白标记
        //如 等
        Pattern pattern =Pattern.compile(" {2,}");
        Matcher m =pattern.matcher(tmp);
        tmp=m.replaceAll("");
        Pattern patterns = Pattern.compile(" ");
        Matcher mm = patterns.matcher(tmp);
        tmp = mm.replaceAll("");
        WriteFile(tmp,outpaths);
        WriteFile("\r\n",outpaths);
      }
    }
  } catch( Exception e ) {
  }
  最后写到文件中的字符串tmp就是抽取后的内容了。
  作者博客:http://www.flyaway-blog.com/%E5%88%A9%E7%94%A8htmlparse%E6%8A%BD%E5%8F%96%E7%BD%91%E9%A1%B5%E6%AD%A3%E6%96%87%E5%86%85%E5%AE%B9.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息