`
liuxinglanyue
  • 浏览: 551209 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

用htmlparser分析并抽取正文

阅读更多

转:http://hannibal730816.iteye.com/blog/149493

我这次要介绍的是如何抽取正文,这部分是最为核心的.因为如果不能很好的提取原有文章的内容和样式,那么搜索出来的东西 
就会惨不忍睹.根本就没有使用价值 

  在做正文抽取模块之前我曾经参考过很多抽取模式,有配置模版的,有搞视觉匹配的.有搞关键字识别的.我挨个做了分析 
首先配置摸版是不太现实的,因为我在搜索技术资讯的时候,根本不知道会搜索到哪个网站,也根本没精力去配置摸版.所以这个行不通 
   
  基于视觉效果的分析,这个难度比较大,而且只适合于规范的网站,而现在很多网站根本不规范,广告链接漫天飞.人家都把最好的 
位置留给广告了.而且我一直怀疑这个模式的可行性,它只是一个善意的推测.所以这方面没做过多尝试 

  我在想,是否有种简单的方法呢?难道就没有什么共性吗? 

  我想所有的正文应该有个共同的特点,那就是正文的长度应该超过其他文字组合的长度.很少会有一句话的正文,很少会有长度 
短于标题的正文.所以这个应该成为一个突破口. 

  接下来,有一个很重要的问题,那段最长的正文在哪里呢? 
  肯定是在一个TABLE,或者DIV,或者ParagraphTag里.那好,那就找到那个包含文字最多的DIV或者TABLE. 

  不过问题又来了,HTML页面,经常是HTML元素的长度超过了正文的长度,有时候混入了不少的JAVASCRIPT.这些元素 
HTMLPARSER经常会误认为是正文加以识别,导致很多正文竟然是一段JAVASCRIPT. 
  祛除杂质是一个关键,这里面要把那些HTML中常用的标签,以及连接中正文去除掉,否则,你搜索出来的很可能是别的什么,尤其 
当正文文字相对较少的时候.我在搜索SOHU页面的时候就经常遇到这个问题,原因是SOHU的页面不是严格按照DIV布局,里面有很多广告 
的JAVASCRIPT。新浪的有些页面也有这个现象,反到是一些中小网站的布局很规范,呵呵,真奇怪了。 

  做完这些工作后,我发现仍然有些网页不能正常抓取,原因是HTMLPARSER对TEXT的认识有问题.例如一段文字在 
ParagraphTag中或者span中包含的,就不能很好的识别.所以要单独做个抽取ParagraphTag内容的函数. 

  做完这些步骤后,有一个问题出来了就是正文中包含的图片,连接,粗体,正常的表格.这些问题一个个的冒出来.既然问题出来了 
那就要一个个的解决.解决了这些难题.我的网站抓取文章的质量就大大的提高了85%的准确率,基本达到实用阶段.我网站上的正文快照基本和原文保持一致. 

    提供几个例子,大家可以看下原文和我抓取的有多少不同 
    1. http://www.itsubway.com/context/20071218/11762.htm 
                这个是单纯获取正文的例子,其中有粗体标签和链接 

    2 http://www.itsubway.com/context/20071218/12041.htm 
     这个是正文里混有图片和表格. 


  我把抽取正文的部分代码和大家共享.这些代码基本解决了我在上面列举出来的问题。包括正文中混有图片,连接,粗体,表格等。 
    大家要是有兴趣可以改造下这些代码 请大家重点看protected List extractHtml(Node nodeP, PageContext context, String siteUrl) 
    这个函数是正文抽取的入口。我的这些函数写的不是很规范,别笑话! 
    /**

    * 收集HTML页面信息 调用抓取函数 按照自己的摸版 生成网页 
    * @param url 
    * @param urlEncode 
    */ 
    public void makeContext(ChannelLinkDO c) { 
        String metakeywords = "<META content={0} name=keywords>"; 
        String metatitle = "<TITLE>{0}</TITLE>"; 
        String metadesc = "<META content={0} name=description>"; 
        String netshap = "<p> 正文快照: 时间{0}</p> "; 

        String tempLeate = "<LI class=active><A href=\"{0}\" target=_blank>{1}</A></LI>"; 
        String crop = "<p><A href=\"{0}\" target=_blank>{1}</A></p> "; 

        try { 
            String siteUrl = getLinkUrl(c.getLink()); 
            Parser parser = new Parser(c.getLink()); 
            parser.setEncoding(c.getEncode()); 

            for (NodeIterator e = parser.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                if (node instanceof Html) { 
                    PageContext context = new PageContext(); 
                    context.setNumber(0); 
                    context.setTextBuffer(new StringBuffer()); 
                    //抓取出内容 
                    extractHtml(node, context, siteUrl); 

                    StringBuffer testContext = context.getTextBuffer(); 
                    //.....生成网页 
                    } 
            } 
        } catch (Exception e) { 
            System.out.println(e); 
        } 
    } 

    private String getLinkUrl(String link) { 
        String urlDomaiPattern = "(http://[^/]*?" + "/)(.*?)"; 

        Pattern pattern = Pattern.compile(urlDomaiPattern, 
                Pattern.CASE_INSENSITIVE + Pattern.DOTALL); 
        Matcher matcher = pattern.matcher(link); 
        String url = ""; 

        while (matcher.find()) { 
            int start = matcher.start(1); 
            int end = matcher.end(1); 

            url = link.substring(start, end - 1).trim(); 
        } 

        return url; 
    } 

    /** 
    * 递归钻取正文信息 
    * @param nodeP 
    * @return 
    */ 
    protected List extractHtml(Node nodeP, PageContext context, String siteUrl) 
        throws Exception { 
        NodeList nodeList = nodeP.getChildren(); 
        boolean bl = false; 

        if ((nodeList == null) || (nodeList.size() == 0)) { 
            if (nodeP instanceof ParagraphTag) { 
                ArrayList tableList = new ArrayList(); 
                StringBuffer temp = new StringBuffer(); 
                temp.append("<p style=\"TEXT-INDENT: 2em\">"); 
                tableList.add(temp); 
                temp = new StringBuffer(); 
                temp.append("</p>").append(lineSign); 
                tableList.add(temp); 

                return tableList; 
            } 

            return null; 
        } 

        if ((nodeP instanceof TableTag) || (nodeP instanceof Div)) { 
            bl = true; 
        } 

        if (nodeP instanceof ParagraphTag) { 
            ArrayList tableList = new ArrayList(); 
            StringBuffer temp = new StringBuffer(); 
            temp.append("<p style=\"TEXT-INDENT: 2em\">"); 
            tableList.add(temp); 
            extractParagraph(nodeP, siteUrl, tableList); 

            temp = new StringBuffer(); 
            temp.append("</p>").append(lineSign); 

            tableList.add(temp); 

            return tableList; 
        } 

        ArrayList tableList = new ArrayList(); 

        try { 
            for (NodeIterator e = nodeList.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                if (node instanceof LinkTag) { 
                    tableList.add(node); 
                    setLinkImg(node, siteUrl); 
                } else if (node instanceof ImageTag) { 
                    ImageTag img = (ImageTag) node; 

                    if (img.getImageURL().toLowerCase().indexOf("http://") < 0) { 
                        img.setImageURL(siteUrl + img.getImageURL()); 
                    } else { 
                        img.setImageURL(img.getImageURL()); 
                    } 

                    tableList.add(node); 
                } else if (node instanceof ScriptTag || 
                        node instanceof StyleTag || node instanceof SelectTag) { 
                } else if (node instanceof TextNode) { 
                    if (node.getText().length() > 0) { 
                        StringBuffer temp = new StringBuffer(); 
                        String text = collapse(node.getText() 
                                                   .replaceAll("&nbsp;", "") 
                                                   .replaceAll(" ", "")); 

                        temp.append(text.trim()); 

                        tableList.add(temp); 
                    } 
                } else { 
                    if (node instanceof TableTag || node instanceof Div) { 
                        TableValid tableValid = new TableValid(); 
                        isValidTable(node, tableValid); 

                        if (tableValid.getTrnum() > 2) { 
                            tableList.add(node); 

                            continue; 
                        } 
                    } 

                    List tempList = extractHtml(node, context, siteUrl); 

                    if ((tempList != null) && (tempList.size() > 0)) { 
                        Iterator ti = tempList.iterator(); 

                        while (ti.hasNext()) { 
                            tableList.add(ti.next()); 
                        } 
                    } 
                } 
            } 
        } catch (Exception e) { 
            return null; 
        } 

        if ((tableList != null) && (tableList.size() > 0)) { 
            if (bl) { 
                StringBuffer temp = new StringBuffer(); 
                Iterator ti = tableList.iterator(); 
                int wordSize = 0; 
                StringBuffer node; 
                int status = 0; 
                StringBuffer lineStart = new StringBuffer( 
                        "<p style=\"TEXT-INDENT: 2em\">"); 
                StringBuffer lineEnd = new StringBuffer("</p>" + lineSign); 

                while (ti.hasNext()) { 
                    Object k = ti.next(); 

                    if (k instanceof LinkTag) { 
                        if (status == 0) { 
                            temp.append(lineStart); 
                            status = 1; 
                        } 

                        node = new StringBuffer(((LinkTag) k).toHtml()); 
                        temp.append(node); 
                    } else if (k instanceof ImageTag) { 
                        if (status == 0) { 
                            temp.append(lineStart); 
                            status = 1; 
                        } 

                        node = new StringBuffer(((ImageTag) k).toHtml()); 
                        temp.append(node); 
                    } else if (k instanceof TableTag) { 
                        if (status == 0) { 
                            temp.append(lineStart); 
                            status = 1; 
                        } 

                        node = new StringBuffer(((TableTag) k).toHtml()); 
                        temp.append(node); 
                    } else if (k instanceof Div) { 
                        if (status == 0) { 
                            temp.append(lineStart); 
                            status = 1; 
                        } 

                        node = new StringBuffer(((Div) k).toHtml()); 
                        temp.append(node); 
                    } else { 
                        node = (StringBuffer) k; 

                        if (status == 0) { 
                            if (node.indexOf("<p") < 0) { 
                                temp.append(lineStart); 
                                temp.append(node); 
                                wordSize = wordSize + node.length(); 
                                status = 1; 
                            } else { 
                                temp.append(node); 
                                status = 1; 
                            } 
                        } else if (status == 1) { 
                            if (node.indexOf("</p") < 0) { 
                                if (node.indexOf("<p") < 0) { 
                                    temp.append(node); 
                                    wordSize = wordSize + node.length(); 
                                } else { 
                                    temp.append(lineEnd); 
                                    temp.append(node); 
                                    status = 1; 
                                } 
                            } else { 
                                temp.append(node); 
                                status = 0; 
                            } 
                        } 
                    } 
                } 

                if (status == 1) { 
                    temp.append(lineEnd); 
                } 

                if (wordSize > context.getNumber()) { 
                    context.setNumber(wordSize); 
                    context.setTextBuffer(temp); 
                } 

                return null; 
            } else { 
                return tableList; 
            } 
        } 

        return null; 
    } 

    /** 
    * 设置图象连接 
    * @param nodeP 
    * @param siteUrl 
    */ 
    private void setLinkImg(Node nodeP, String siteUrl) { 
        NodeList nodeList = nodeP.getChildren(); 

        try { 
            for (NodeIterator e = nodeList.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                if (node instanceof ImageTag) { 
                    ImageTag img = (ImageTag) node; 

                    if (img.getImageURL().toLowerCase().indexOf("http://") < 0) { 
                        img.setImageURL(siteUrl + img.getImageURL()); 
                    } else { 
                        img.setImageURL(img.getImageURL()); 
                    } 
                } 
            } 
        } catch (Exception e) { 
            return; 
        } 

        return; 
    } 

    /** 
    * 钻取段落中的内容 
    * @param nodeP 
    * @param siteUrl 
    * @param tableList 
    * @return 
    */ 
    private List extractParagraph(Node nodeP, String siteUrl, List tableList) { 
        NodeList nodeList = nodeP.getChildren(); 

        if ((nodeList == null) || (nodeList.size() == 0)) { 
            if (nodeP instanceof ParagraphTag) { 
                StringBuffer temp = new StringBuffer(); 
                temp.append("<p style=\"TEXT-INDENT: 2em\">"); 
                tableList.add(temp); 
                temp = new StringBuffer(); 
                temp.append("</p>").append(lineSign); 
                tableList.add(temp); 

                return tableList; 
            } 

            return null; 
        } 

        try { 
            for (NodeIterator e = nodeList.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                if (node instanceof ScriptTag || node instanceof StyleTag || 
                        node instanceof SelectTag) { 
                } else if (node instanceof LinkTag) { 
                    tableList.add(node); 
                    setLinkImg(node, siteUrl); 
                } else if (node instanceof ImageTag) { 
                    ImageTag img = (ImageTag) node; 

                    if (img.getImageURL().toLowerCase().indexOf("http://") < 0) { 
                        img.setImageURL(siteUrl + img.getImageURL()); 
                    } else { 
                        img.setImageURL(img.getImageURL()); 
                    } 

                    tableList.add(node); 
                } else if (node instanceof TextNode) { 
                    if (node.getText().trim().length() > 0) { 
                        String text = collapse(node.getText() 
                                                   .replaceAll("&nbsp;", "") 
                                                   .replaceAll(" ", "")); 
                        StringBuffer temp = new StringBuffer(); 
                        temp.append(text); 
                        tableList.add(temp); 
                    } 
                } else if (node instanceof Span) { 
                    StringBuffer spanWord = new StringBuffer(); 
                    getSpanWord(node, spanWord); 

                    if ((spanWord != null) && (spanWord.length() > 0)) { 
                        String text = collapse(spanWord.toString() 
                                                       .replaceAll("&nbsp;", "") 
                                                       .replaceAll(" ", "")); 

                        StringBuffer temp = new StringBuffer(); 
                        temp.append(text); 
                        tableList.add(temp); 
                    } 
                } else if (node instanceof TagNode) { 
                    String tag = node.toHtml(); 

                    if (tag.length() <= 10) { 
                        tag = tag.toLowerCase(); 

                        if ((tag.indexOf("strong") >= 0) || 
                                (tag.indexOf("b") >= 0)) { 
                            StringBuffer temp = new StringBuffer(); 
                            temp.append(tag); 
                            tableList.add(temp); 
                        } 
                    } else { 
                        if (node instanceof TableTag || node instanceof Div) { 
                            TableValid tableValid = new TableValid(); 
                            isValidTable(node, tableValid); 

                            if (tableValid.getTrnum() > 2) { 
                                tableList.add(node); 

                                continue; 
                            } 
                        } 

                        extractParagraph(node, siteUrl, tableList); 
                    } 
                } 
            } 
        } catch (Exception e) { 
            return null; 
        } 

        return tableList; 
    } 

    protected void getSpanWord(Node nodeP, StringBuffer spanWord) { 
        NodeList nodeList = nodeP.getChildren(); 

        try { 
            for (NodeIterator e = nodeList.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                if (node instanceof ScriptTag || node instanceof StyleTag || 
                        node instanceof SelectTag) { 
                } else if (node instanceof TextNode) { 
                    spanWord.append(node.getText()); 
                } else if (node instanceof Span) { 
                    getSpanWord(node, spanWord); 
                } else if (node instanceof ParagraphTag) { 
                    getSpanWord(node, spanWord); 
                } else if (node instanceof TagNode) { 
                    String tag = node.toHtml().toLowerCase(); 

                    if (tag.length() <= 10) { 
                        if ((tag.indexOf("strong") >= 0) || 
                                (tag.indexOf("b") >= 0)) { 
                            spanWord.append(tag); 
                        } 
                    } 
                } 
            } 
        } catch (Exception e) { 
        } 

        return; 
    } 

    /** 
    * 判断TABLE是否是表单 
    * @param nodeP 
    * @return 
    */ 
    private void isValidTable(Node nodeP, TableValid tableValid) { 
        NodeList nodeList = nodeP.getChildren(); 

        /**如果该表单没有子节点则返回**/ 
        if ((nodeList == null) || (nodeList.size() == 0)) { 
            return; 
        } 

        try { 
            for (NodeIterator e = nodeList.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                /**如果子节点本身也是表单则返回**/ 
                if (node instanceof TableTag || node instanceof Div) { 
                    return; 
                } else if (node instanceof ScriptTag || 
                        node instanceof StyleTag || node instanceof SelectTag) { 
                    return; 
                } else if (node instanceof TableColumn) { 
                    return; 
                } else if (node instanceof TableRow) { 
                    TableColumnValid tcValid = new TableColumnValid(); 
                    tcValid.setValid(true); 
                    findTD(node, tcValid); 

                    if (tcValid.isValid()) { 
                        if (tcValid.getTdNum() < 2) { 
                            if (tableValid.getTdnum() > 0) { 
                                return; 
                            } else { 
                                continue; 
                            } 
                        } else { 
                            if (tableValid.getTdnum() == 0) { 
                                tableValid.setTdnum(tcValid.getTdNum()); 
                                tableValid.setTrnum(tableValid.getTrnum() + 1); 
                            } else { 
                                if (tableValid.getTdnum() == tcValid.getTdNum()) { 
                                    tableValid.setTrnum(tableValid.getTrnum() + 
                                        1); 
                                } else { 
                                    return; 
                                } 
                            } 
                        } 
                    } 
                } else { 
                    isValidTable(node, tableValid); 
                } 
            } 
        } catch (Exception e) { 
            return; 
        } 

        return; 
    } 

    /** 
    * 判断是否有效TR 
    * @param nodeP 
    * @param TcValid 
    * @return 
    */ 
    private void findTD(Node nodeP, TableColumnValid tcValid) { 
        NodeList nodeList = nodeP.getChildren(); 

        /**如果该表单没有子节点则返回**/ 
        if ((nodeList == null) || (nodeList.size() == 0)) { 
            return; 
        } 

        try { 
            for (NodeIterator e = nodeList.elements(); e.hasMoreNodes();) { 
                Node node = (Node) e.nextNode(); 

                /**如果有嵌套表单**/ 
                if (node instanceof TableTag || node instanceof Div || 
                        node instanceof TableRow || 
                        node instanceof TableHeader) { 
                    tcValid.setValid(false); 

                    return; 
                } else if (node instanceof ScriptTag || 
                        node instanceof StyleTag || node instanceof SelectTag) { 
                    tcValid.setValid(false); 

                    return; 
                } else if (node instanceof TableColumn) { 
                    tcValid.setTdNum(tcValid.getTdNum() + 1); 
                } else { 
                    findTD(node, tcValid); 
                } 
            } 
        } catch (Exception e) { 
            tcValid.setValid(false); 

            return; 
        } 

        return; 
    } 

    protected String collapse(String string) { 
        int chars; 
        int length; 
        int state; 
        char character; 
        StringBuffer buffer = new StringBuffer(); 
        chars = string.length(); 

        if (0 != chars) { 
            length = buffer.length(); 
            state = ((0 == length) || (buffer.charAt(length - 1) == ' ') || 
                ((lineSign_size <= length) && 
                buffer.substring(length - lineSign_size, length).equals(lineSign))) 
                ? 0 : 1; 

            for (int i = 0; i < chars; i++) { 
                character = string.charAt(i); 

                switch (character) { 
                case '\u0020': 
                case '\u0009': 
                case '\u000C': 
                case '\u200B': 
                case '\u00a0': 
                case '\r': 
                case '\n': 

                    if (0 != state) { 
                        state = 1; 
                    } 

                    break; 

                default: 

                    if (1 == state) { 
                        buffer.append(' '); 
                    } 

                    state = 2; 
                    buffer.append(character); 
                } 
            } 
        } 

        return buffer.toString(); 
    } 

 
    

 

分享到:
评论
1 楼 hegang126 2011-11-07  
你好啊,最近做网页正文抽取,你的这个完整的源代码能给一份吗?,我邮箱是 hegang_126@126.com,谢谢啊

相关推荐

    基于统计的网页正文信息抽取

    本方法中用到了网页分析器htmlparser,采用Java语言编程,工具是eclipse。可以实现把正文放在table结点的HTML网页的正文信息抽取功能。

    htmlparser.net

    htmlparser.net是一个c#写的html解析的库,主要用于改造或提取html。它能超高速解析html,而且不会出错。 毫不夸张地说,htmlparser就是目前最好的html解析和分析的工具。

    基于Java和Python的爬虫项目实战源码.zip

    使用非极大值抑制法确定镜头边界系数极大值并排序,以实现基于镜头边界系数的关键帧提取 JMF(Java视频处理): 功能 a)在Java Applet和应用程序中播放贵重物品媒体文件,如AVI、MPEG、WAV等; b)可以播放从互联网...

    JAVA上百实例源码以及开源项目源代码

    得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,使用公钥初始化签名对象,用于...

    java开源包8

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包1

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包11

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包2

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包3

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包6

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包5

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包10

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包4

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包7

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包9

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    java开源包101

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    Java资源包01

    JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...

    JAVA上百实例源码以及开源项目

    得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,使用公钥初始化签名对象,用于...

Global site tag (gtag.js) - Google Analytics