Archive for July 28th, 2007

You are currently browsing the archives of Enabling Technology .

HTMLParser的两种使用方法 -forward

 

因为论文的关系,要用到HTMLParser这个项目(使用的HTMLParser版本是1.6)

一,数据组织分析:

HtmlParser主要靠Node、AbstractNode和Tag来表达Html,因为Remark和Text相对简单,此处就将其忽略了。

  • Node是形成树结构表示HTML的基础,所有的数据表示都是接口Node的实现,Node定义了与页面树结构所表达的页面Page对象,定义了获取父、子、兄弟节点的方法,定义了节点到对应html文本的方法,定义了该节点对应的起止位置,定义了过滤方法,定义了Visitor访问机制。
  • AbstractNode是Node的一种具体的类实现,起到构成树形结构的作用,除了同具体Node相关的accetp方法,toString,toHtml,toPlainTextString方法以外,AbstractNode实现了大多基本的方法,使得它的子类,不用理会具体的树操作。
  • Tag是具体分析的主要内容。Tag分成composite的Tag和不能包含其他Tag的简单Tag两类,其中前者的基类是CompositeTag,其子类包含BodyTag,Div,FrameSetTag,OptionTag,等27个子类;而简单Tag有BaseHrefTag、DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag这八类。

Node分成三类:

  • RemarkNode:代表Html中的注释
  • TagNode:标签节点,是种类最多的节点类型,上述Tag的具体节点类都是TagNode的实现。
  • TextNode:文本节点

二,Visitor方式访问Html:

1,整体解析过程

  • 用一个URL或页面String做一个Parser
  • 用这个Parser做一个Visitor
  • 使用Parser.visitAllNodeWith(Visitor)来遍历节点
  • 获取Visitor遍历后得到的数据

2,Visit过程

  • 做解析之前做的事情:visitor.beginParsing();
  • 每次取到一个节点Node,让该Node接受accept该Visitor
  • 做解析后做的事情:visitor.finishedParsing();

3,获取节点的过程:逐步遍历Html,分析出Node。此部分较为复杂,且对于我们应用来说无需很多了解,暂跳过。

4,节点访问

节点访问采用Visitor模式,Node的accept方法和具体Visitor的visit方法是关键。

首先三类Node来accept的方式各不相同:

  • 对于所有TagNode都使用一个accept方法,即TagNode的accept方法。首先判断是否是标签结尾,如果是就visitor.visitEndTag (this);否则visitor.visitTag (this);
  • 如果是TextNode,那就visitor.visitStringNode (this);就可以了。
  • 如果是RemarkNode,那就visitor.visitRemarkNode (this);就可以了。

实际上NodeVisitor里边这四种visit方法都是空的,因为在不同的Visitor中对于这三类节点的处理是不同的;对于需要处理的节点,只要重载对应的visit方法就行了,如果不处理那就不理会就可以了;另外,如果用户用自己的Visitor,那么还可以灵活的处理不同类型的节点了。

系统为我们实现了下面我要介绍的8种Visitor,实际上可以看作是系统给我们演示了如何做各种各样的Visitor来访问Html,因为实际上我们要真正来用HtmlParser的话,还需要特定的Visitor,而通过简单的这些系统提供的Visitor组合是难以做成什么事情的。

三,系统Visitor功能简介:

  • ObjectFindingVisitor:用来找出所有指定类型的节点,采用getTags()来获取结果。
  • StringBean:用来从一个指定的URL获取移除了<SCRIPT></SCRIPT>和<PRE></PRE>之间代码的Html代码,也可以用做Visitor,用来移除这两种标签内部的代码,采用StringBean.getStrings()来获取结果。
  • HtmlPage:提取Title,body中的节点和页面中的TableTag节点。
  • LinkFindingVisitor:找出节点中包含某个链接的总个数。
  • StringFindingVisitor:找出遍历的TextNode中含有指定字符串的个数。
  • TagFindingVisitor:找出指定Tag的所有节点,可以指定多种类型。
  • TextExtractingVisitor:从网页中把所有标签去掉来提取文本,这个提取文本的Visitor有时是很实用的,只是注意在提取文本时将标签的属性也去掉了,也就是说只剩下标签之间的文本,例如<a>中的链接也去掉了。
  • UrlModifyingVisitor:用来修改网页中的链接。

四,Filter

如果说visitor是遍历提取信息,当然这个信息可以包括某些节点或者从节点分析出来的更有效的信息,这都取决于我们的Visitor做成什么样子,那么Filter则目标很明确,就是用来提取节点的。所以说要想用HtmlParser,首先要熟悉上面讲到的数据组织。

系统定义了17种具体的Filter,包括依据节点父子关系的Filter,连接Filter组合的Filter,依据网页内容匹配情况的filter,等等。我们也可以implement Filter来做自己的Filter来提取节点。

Filter的调用是同Visitor独立的,因为也无需先filter出一些NodeList,再用Visitor来访问。调用Filter的方法是:

NodeList nodeList = myParser.parse(someFilter);

解析之后,我们可以采用:

Node[] nodes = nodeList.toNodeArray();

来获取节点数组,也可以直接访问:

Node node = nodeList.elementAt(i)来获取Node。

另外,在Filter后得到NodeList以后,我们仍然可以使用NodeList的 extractAllNodesThatMatch(someFilter)来进一步过滤,同时又可以用NodeList的 isitAllNodesWith(someVisitor)来做进一步的访问。

这样,我们可以看到HtmlParser为我们提供了非常方便的Html解析方式,针对不同的应用可以采用 visitor来遍历Html节点提取数据,也可以用Filter来过滤节点,提取出我们所关注的节点,再对节点进行处理。通过这样的组合,一定能够找出我们所需要的信息。

我的代码

package com.eric.Html.htmlparser;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.HasChildFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.TextExtractingVisitor;

/** *//**
 * @author 作者 Eric yang E-mail:yjboy1982@126.com
 * @version 创建时间:2007-7-16 下午02:49:55
 * 类说明
*/
public class AstroExtractorTest …{

/** *//**
     * @param args
     * @throws ParserException 
*/
public static void main(String[] args) throws ParserException …{
// TODO Auto-generated method stub
        String title ;
        String constellation ;
        String body ;
        String summary ;

        Parser parser = new Parser(”http://astro.sina.com.cn/sagittarius.html”);
        parser.setEncoding(”GB2312″) ;

        NodeFilter filter_constellation_summart = new AndFilter((new TagNameFilter(”td”)),(new HasChildFilter(new TagNameFilter(”b”)))) ;

        NodeFilter filter_title = new AndFilter(new TagNameFilter(”font”), new HasAttributeFilter(”class”, ”f1491″)) ;

        NodeFilter filter_body = new AndFilter( new TagNameFilter(”td”), new HasAttributeFilter(”width”, ”30%”)) ;

        NodeList nodelist = parser.parse(filter_constellation_summart) ;
        Node node_constellation = nodelist.elementAt(0) ;        
        constellation = node_constellation.getFirstChild().getNextSibling().toHtml() ;

        Node node_summary = nodelist.elementAt(1) ;
        NodeList summary_nodelist = node_summary.getChildren() ;
        summary = summary_nodelist.elementAt(3).toHtml()+summary_nodelist.elementAt(5).toHtml()  ;

        parser.reset() ;

        nodelist = parser.parse(filter_title) ;
        Node node_title = nodelist.elementAt(0) ;
        title = node_title.getNextSibling().getNextSibling().toHtml() ;
//title = node_title.getNextSibling().getNextSibling().toHtml() ;

        parser.reset() ;

        nodelist = parser.parse(filter_body) ;
        Node node_body = nodelist.elementAt(0) ;
        Parser body_parser = new Parser(node_body.toHtml()) ;
        TextExtractingVisitor visitor = new TextExtractingVisitor() ;
        body_parser.visitAllNodesWith(visitor) ;
        body = visitor.getExtractedText() ;

//System.out.println(node_summary.getChildren().toHtml()) ;
//System.out.println(node_body.toHtml()) ;
//System.out.println(title.trim()) ;
//System.out.println(constellation.trim()) ;
//System.out.println(body.trim()) ;
        System.out.println(summary.trim()) ;

    }

}

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

HtmlParser初步研究 -forwad

 

 
这两天准备做一些网站编程的工作,于是对HtmlParse小研究了一下,目的是快速入手,而不是深入研究,做了一下整理,和大家共同讨论一下。

一,数据组织分析:

HtmlParser主要靠Node、AbstractNode和Tag来表达Html,因为Remark和Text相对简单,此处就将其忽略了。

  • Node是形成树结构表示HTML的基础,所有的数据表示都是接口Node的实现,Node定义了与页面树结构所表达的页面Page对象,定义了获取父、子、兄弟节点的方法,定义了节点到对应html文本的方法,定义了该节点对应的起止位置,定义了过滤方法,定义了Visitor访问机制。
  • AbstractNode是Node的一种具体的类实现,起到构成树形结构的作用,除了同具体Node相关的accetp方法,toString,toHtml,toPlainTextString方法以外,AbstractNode实现了大多基本的方法,使得它的子类,不用理会具体的树操作。
  • Tag是具体分析的主要内容。Tag分成composite的Tag和不能包含其他Tag的简单Tag两类,其中前者的基类是CompositeTag,其子类包含BodyTag,Div,FrameSetTag,OptionTag,等27个子类;而简单Tag有BaseHrefTag、DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag这八类。

Node分成三类:

  • RemarkNode:代表Html中的注释
  • TagNode:标签节点,是种类最多的节点类型,上述Tag的具体节点类都是TagNode的实现。
  • TextNode:文本节点

二,Visitor方式访问Html:

1,整体解析过程

  • 用一个URL或页面String做一个Parser
  • 用这个Parser做一个Visitor
  • 使用Parser.visitAllNodeWith(Visitor)来遍历节点
  • 获取Visitor遍历后得到的数据

2,Visit过程

  • 做解析之前做的事情:visitor.beginParsing();
  • 每次取到一个节点Node,让该Node接受accept该Visitor
  • 做解析后做的事情:visitor.finishedParsing();

3,获取节点的过程:逐步遍历Html,分析出Node。此部分较为复杂,且对于我们应用来说无需很多了解,暂跳过。

4,节点访问

节点访问采用Visitor模式,Node的accept方法和具体Visitor的visit方法是关键。

首先三类Node来accept的方式各不相同:

  • 对于所有TagNode都使用一个accept方法,即TagNode的accept方法。首先判断是否是标签结尾,如果是就visitor.visitEndTag (this);否则visitor.visitTag (this);
  • 如果是TextNode,那就visitor.visitStringNode (this);就可以了。
  • 如果是RemarkNode,那就visitor.visitRemarkNode (this);就可以了。

实际上NodeVisitor里边这四种visit方法都是空的,因为在不同的Visitor中对于这三类节点的处理是不同的;对于需要处理的节点,只要重载对应的visit方法就行了,如果不处理那就不理会就可以了;另外,如果用户用自己的Visitor,那么还可以灵活的处理不同类型的节点了。

系统为我们实现了下面我要介绍的8种Visitor,实际上可以看作是系统给我们演示了如何做各种各样的Visitor来访问Html,因为实际上我们要真正来用HtmlParser的话,还需要特定的Visitor,而通过简单的这些系统提供的Visitor组合是难以做成什么事情的。

三,系统Visitor功能简介:

  • ObjectFindingVisitor:用来找出所有指定类型的节点,采用getTags()来获取结果。
  • StringBean:用来从一个指定的URL获取移除了<SCRIPT></SCRIPT>和<PRE></PRE>之间代码的Html代码,也可以用做Visitor,用来移除这两种标签内部的代码,采用StringBean.getStrings()来获取结果。
  • HtmlPage:提取Title,body中的节点和页面中的TableTag节点。
  • LinkFindingVisitor:找出节点中包含某个链接的总个数。
  • StringFindingVisitor:找出遍历的TextNode中含有指定字符串的个数。
  • TagFindingVisitor:找出指定Tag的所有节点,可以指定多种类型。
  • TextExtractingVisitor:从网页中把所有标签去掉来提取文本,这个提取文本的Visitor有时是很实用的,只是注意在提取文本时将标签的属性也去掉了,也就是说只剩下标签之间的文本,例如<a>中的链接也去掉了。
  • UrlModifyingVisitor:用来修改网页中的链接。

四,Filter

如果说visitor是遍历提取信息,当然这个信息可以包括某些节点或者从节点分析出来的更有效的信息,这都取决于我们的Visitor做成什么样子,那么Filter则目标很明确,就是用来提取节点的。所以说要想用HtmlParser,首先要熟悉上面讲到的数据组织。

系统定义了17种具体的Filter,包括依据节点父子关系的Filter,连接Filter组合的Filter,依据网页内容匹配情况的filter,等等。我们也可以implement Filter来做自己的Filter来提取节点。

Filter的调用是同Visitor独立的,因为也无需先filter出一些NodeList,再用Visitor来访问。调用Filter的方法是:

NodeList nodeList = myParser.parse(someFilter);

解析之后,我们可以采用:

Node[] nodes = nodeList.toNodeArray();

来获取节点数组,也可以直接访问:

Node node = nodeList.elementAt(i)来获取Node。

另外,在Filter后得到NodeList以后,我们仍然可以使用NodeList的extractAllNodesThatMatch (someFilter)来进一步过滤,同时又可以用NodeList的isitAllNodesWith(someVisitor)来做进一步的访问。

这样,我们可以看到HtmlParser为我们提供了非常方便的Html解析方式,针对不同的应用可以采用visitor来遍历Html节点提取数据,也可以用Filter来过滤节点,提取出我们所关注的节点,再对节点进行处理。通过这样的组合,一定能够找出我们所需要的信息。

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

Userful API Reference for Projects

APIs:

  1. JDOM: http://www.jdom.org/docs/apidocs/
  2. HtmlParser:http://htmlparser.sourceforge.net/javadoc/

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

utf-8 JSP 文本文件读写的例子(原创)

<%@ page import=”java.util.Date” %>
<%@ page import=”java.io.*” %>
<%–
  Created by IntelliJ IDEA.
  User: Yang Yuan
  Date: Oct 29, 2005
  Time: 6:00:32 PM
  To change this template use File | Settings | File Templates.
–%>
<%@ page contentType=”text/html;charset=UTF-8″ language=”java” %>
<html>
<head><title>Simple jsp page</title></head>

<body>

<%
    try {
        request.setCharacterEncoding(”utf-8″);
        String path = request.getSession().getServletContext().getRealPath(”/~micas/WorkExperience.txt”);
        FileOutputStream os = new FileOutputStream(path, true);
        OutputStreamWriter osw = new OutputStreamWriter(os, “utf-8″);

        String newPost = request.getParameter(”newPost”);
        if (null != newPost && !”".equalsIgnoreCase(newPost)) {
            osw.append(new Date() + “\r\n\t” + newPost + “\r\n—————–\r\n\r\n”);
        }
        osw.close();

        FileInputStream fis = new FileInputStream(path);
        InputStreamReader isr = new InputStreamReader(fis, “UTF8″);
        BufferedReader bf = new BufferedReader(isr);
        String string = null;
        out.println(”<pre>”);

        while ((string = bf.readLine()) != null) {
            out.println(string);
        }
        out.println(”</pre>”);
        bf.close();
    } catch (Exception ex) {
        out.println(ex);
    }
%>

<FORM METHOD=POST>
    New Post: <br>
    <TEXTAREA NAME=”newPost” ROWS=”20″ COLS=”100″></TEXTAREA><br>
    <input type=submit value=”Submit”>
</FORM>

</body>
</html>

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

用JDOM创建XML

package com.shanghai.waimai.xml.prototype;

//用jdom创建xml文档:CreateXML.java
import java.io.FileWriter;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class CreateXML {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CreateXML createXML = new CreateXML();
    }

    Element customer, name, age, sex, address, city, district, street;

    public CreateXML() {
        // 创建customer元素,并设置为xml根节点
        customer = new Element(”customer”);
        Document myDocument = new Document(customer);
        // 创建xml文档其它元素,并初始化元素名
        name = new Element(”name”);
        age = new Element(”age”);
        sex = new Element(”sex”);
        address = new Element(”address”);
        city = new Element(”city”);
        district = new Element(”district”);
        street = new Element(”street”);
        // 给xml每个元素添加内容值
        district.addContent(”hai dan qu”);
        name.addContent(”luojing”);
        age.addContent(”23″);
        sex.addContent(”female”);
        street.addContent(”bupt”);
        city.addContent(”beijing”);
        // 后者添加为前者的子元素
        address.addContent(street);
        address.addContent(district);
        address.addContent(city);
        //
        customer.addContent(name);
        customer.addContent(age);
        customer.addContent(sex);
        customer.addContent(address);
        //
        try {
            // 创建xml输出流
            XMLOutputter fmt = new XMLOutputter();
            // 创建文件输出流
            FileWriter writer = new FileWriter(”e:\\customer.xml”);
            // 设置xml文档格式
            Format f = Format.getPrettyFormat();
            fmt.setFormat(f);
            // 将生成的xml文档myDocument写入到writer里
            fmt.output(myDocument, writer);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

解决网站内容的抓取,分析,添加的流程。

解析html,得到每一条的数据

数据要分类:分类的规则和标志

每个entry在每个分类的标志要明

用以上规则生成xml,附加类别和tag等附加信息

xml to db

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

提取HTML中的文本信息

我们拿到一个HTML文本的时候我们并不在意它的格式,而只是想提取其中包含的文本信息。例如说为了在手机上显示一个超文本,如果直接显示的话那肯定会收到一大堆的错误,很多手机根本没有能力显示HTML信息,因此我们需要把存在于HTML中的文本提取出来并使用WML来重新组合以便手机可以正确的查看,这样做虽然丢失了格式,但是毕竟这种情况下更关心的是数据。下面给出一段程序完成这个功能,很简单!
/*
 * Created on 2004-7-11
 */
package com.clickcom.wcp.util;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.util.NodeList;

/**
 * 用于处理HTML信息的工具集合
 * @author liudong
 */
public class HtmlUtils {

 /**
  * 抽取纯文本信息
  * @param inputHtml
  * @return
  */
 public static String extractText(String inputHtml) throws Exception{
  StringBuffer text = new StringBuffer();
  Parser parser = Parser.createParser(new String(inputHtml.getBytes(),”8859_1″));
  //遍历所有的节点
  NodeList nodes = parser.extractAllNodesThatMatch(new NodeFilter(){
   public boolean accept(Node node) {
    return true;
   }});
  Node node = nodes.elementAt(0);
  text.append(new String(node.toPlainTextString().getBytes(”8859_1″)));
  return text.toString();
 }

 public static void main(String[] args) throws Exception{
  String text = extractText(”<td>点击<b><a href=index.jsp>这里</a></b>回到首页</td>”);
  System.out.println(text);
 }

}

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

使用正则表达式提取网页中的有用内容

东方细雨 发表于 2006-6-23 10:40:54

使用正则表达式提取网页中的有用内容,提取网页中的URL地址,提取网页中的电子邮件E-mail地址
在网上查了很多很多,都没有找到一个例子,
只有一些什么把网页内的某些字替换成红色之类的垃圾源代码,
VB代码
Function RegExpTest(patrn, strng) ‘patrn:需要查找的字符 strng:被查找的字符串
  Dim regEx, Match, Matches     ‘ 创建变量。
  Set regEx = New RegExp            ‘ 创建正则表达式。
  regEx.Pattern = patrn         ‘ 设置模式。’”\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*”‘
  regEx.IgnoreCase = True           ‘ 设置是否区分大小写。
  regEx.Global = True           ‘ 设置全程匹配。
  Set Matches = regEx.Execute(strng)    ‘ 执行搜索。
  For Each Match In Matches     ‘ 循环遍历Matches集合。
    RetStr = RetStr & Match.Value & “|”
  Next
  RegExpTest = RetStr
End Function
‘函数返回所有的查找的内容,以“|”号隔开,用户只需使用split将其转化为数组即可使用
    URLRegExp = “http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?” ‘URL正则表达式
    MailRegExp = “\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*” ‘电子邮件正则表达式

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

解析Html页面:HTML Parser的试用(fwd)

最近在研究lucene的全文检索,在很多地方需要解析或者说分析Html内容或者Html页面,Lucene本身的演示程序中也提供了一个Html Parser,但是不是纯Java的解决方案.于是到处搜索,在网上找到了一个”HTMLParser”.
网址是: http://htmlparser.sourceforge.net ,当前版本为1.5.
下载下来,试用一番,感觉不错,完全能满足lucene解析Html的需求.
过几天贴出lucene进行全文检索的代码.(检索本站的文章等).
试用代码如下,供大家参考:
package com.jscud.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.OrFilter;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.HtmlPage;
import org.htmlparser.visitors.TextExtractingVisitor;

import com.jscud.util.LogMan; //一个日志记录类

/**
 * 演示了Html Parse的应用.
 *
 * @author scud http://www.jscud.com
 */

public class ParseHtmlTest
{

    public static void main(String[] args) throws Exception
    {
        String aFile = “e:/jscud/temp/test.htm”;

        String content = readTextFile(aFile, “GBK”);

        test1(content);
        System.out.println(”====================================”);

        test2(content);
        System.out.println(”====================================”);

        test3(content);
        System.out.println(”====================================”);

        test4(content);
        System.out.println(”====================================”);

        test5(aFile);
        System.out.println(”====================================”);

        //访问外部资源,相对慢
        test5(”http://www.jscud.com”);
        System.out.println(”====================================”);

    }

    /**
     * 读取文件的方式来分析内容.
     * filePath也可以是一个Url.
     *
     * @param resource 文件/Url
     */
    public static void test5(String resource) throws Exception
    {
        Parser myParser = new Parser(resource);

        //设置编码
        myParser.setEncoding(”GBK”);

        HtmlPage visitor = new HtmlPage(myParser);

        myParser.visitAllNodesWith(visitor);

        String textInPage = visitor.getTitle();

        System.out.println(textInPage);
    }

    /**
     * 按页面方式处理.对一个标准的Html页面,推荐使用此种方式.
     */
    public static void test4(String content) throws Exception
    {
        Parser myParser;
        myParser = Parser.createParser(content, “GBK”);

        HtmlPage visitor = new HtmlPage(myParser);

        myParser.visitAllNodesWith(visitor);

        String textInPage = visitor.getTitle();

        System.out.println(textInPage);
    }

    /**
     * 利用Visitor模式解析html页面.
     *
     * 小优点:翻译了<>等符号
     * 缺点:好多空格,无法提取link
     * 
     */
    public static void test3(String content) throws Exception
    {
        Parser myParser;
        myParser = Parser.createParser(content, “GBK”);

        TextExtractingVisitor visitor = new TextExtractingVisitor();

        myParser.visitAllNodesWith(visitor);

        String textInPage = visitor.getExtractedText();

        System.out.println(textInPage);
    }

    /**
     * 得到普通文本和链接的内容.
     *
     * 使用了过滤条件.
     */
    public static void test2(String content) throws ParserException
    {
        Parser myParser;
        NodeList nodeList = null;

        myParser = Parser.createParser(content, “GBK”);

        NodeFilter textFilter = new NodeClassFilter(TextNode.class);
        NodeFilter linkFilter = new NodeClassFilter(LinkTag.class);

        //暂时不处理 meta
        //NodeFilter metaFilter = new NodeClassFilter(MetaTag.class);

        OrFilter lastFilter = new OrFilter();
        lastFilter.setPredicates(new NodeFilter[] { textFilter, linkFilter });

        nodeList = myParser.parse(lastFilter);

        Node[] nodes = nodeList.toNodeArray();

        for (int i = 0; i < nodes.length; i++)
        {
            Node anode = (Node) nodes[i];

            String line = “”;
            if (anode instanceof TextNode)
            {
                TextNode textnode = (TextNode) anode;
                //line = textnode.toPlainTextString().trim();
                line = textnode.getText();
            }
            else if (anode instanceof LinkTag)
            {
                LinkTag linknode = (LinkTag) anode;

                line = linknode.getLink();
                //@todo 过滤jsp标签:可以自己实现这个函数
                //line = StringFunc.replace(line, “<%.*%>”, “”);
            }

            if (isTrimEmpty(line))
                continue;

            System.out.println(line);
        }
    }

    /**
     * 解析普通文本节点.
     *
     * @param content
     * @throws ParserException
     */
    public static void test1(String content) throws ParserException
    {
        Parser myParser;
        Node[] nodes = null;

        myParser = Parser.createParser(content, null);

        nodes = myParser.extractAllNodesThatAre(TextNode.class); //exception could be thrown here

        for (int i = 0; i < nodes.length; i++)
        {
            TextNode textnode = (TextNode) nodes[i];
            String line = textnode.toPlainTextString().trim();
            if (line.equals(”"))
                continue;
            System.out.println(line);
        }

    }

    /**
     * 读取一个文件到字符串里.
     *
     * @param sFileName  文件名
     * @param sEncode   String
     * @return 文件内容
     */
    public static String readTextFile(String sFileName, String sEncode)
    {
        StringBuffer sbStr = new StringBuffer();

        try
        {
            File ff = new File(sFileName);
            InputStreamReader read = new InputStreamReader(new FileInputStream(ff),
                    sEncode);
            BufferedReader ins = new BufferedReader(read);

            String dataLine = “”;
            while (null != (dataLine = ins.readLine()))
            {
                sbStr.append(dataLine);
                sbStr.append(”\r\n”);
            }

            ins.close();
        }
        catch (Exception e)
        {
            LogMan.error(”read Text File Error”, e);
        }

        return sbStr.toString();
    }

    /**
     * 去掉左右空格后字符串是否为空
     * @param astr String
     * @return boolean
     */
    public static boolean isTrimEmpty(String astr)
    {
        if ((null == astr) || (astr.length() == 0))
        {
            return true;
        }
        if (isBlank(astr.trim()))
        {
            return true;
        }
        return false;
    }

    /**
     * 字符串是否为空:null或者长度为0.
     * @param astr 源字符串.
     * @return boolean
     */
    public static boolean isBlank(String astr)
    {
        if ((null == astr) || (astr.length() == 0))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

}

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

抓取html中的链接文字(fwd)

这里面共有两个类第一个是ParserGetter
package bot;

import javax.swing.text.html.HTMLEditorKit;

/**
 * @author lyz
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class ParserGetter extends HTMLEditorKit{
 public HTMLEditorKit.Parser getParser(){
  return super.getParser();
 }

 public static void main(String[] args) {
 }
}

第二个类是SwingHTMLParser

/*
 * Created on 2005-6-21
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package bot;

/**
 * @author lyz
 *
 * TODO To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Style - Code Templates
 */
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import java.io.*;
import java.net.*;

public class SwingHTMLParser extends HTMLEditorKit.ParserCallback {
 private boolean inHeader = false;

 private HTML.Tag tag; // 建構式

 public SwingHTMLParser(HTML.Tag tag) {
  this.tag = tag;
 }

 public void handleText(char[] text, int position) {
  if (inHeader) {
   System.out.println(text);
  }
 }

 public void handleStartTag(HTML.Tag tag, MutableAttributeSet attributes,
   int position) {
  if (this.tag == tag) {
   this.inHeader = true;
  }
 }

 public void handleEndTag(HTML.Tag tag, int position) {
  if (this.tag == tag) {
   inHeader = false;
  }
 }

 public static void main(String[] args) {
  ParserGetter kit = new ParserGetter();
  HTMLEditorKit.Parser parser = kit.getParser();
  HTMLEditorKit.ParserCallback callback = new SwingHTMLParser(HTML.Tag.A);
  try {
   URL u = new URL(”http://www.ahu.edu.cn”);
   InputStream in = u.openStream();
   InputStreamReader reader = new InputStreamReader(in);
   parser.parse(reader, callback, true);
  } catch (IOException e) {
   System.err.println(e);
  }
 }
}

Posted by micas on Jul 28th 2007 | Filed in SEO | Comments (0)

Next »