java版 正文抽取 基于文字连接比



package cn.tdt.crawl.jdbc;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class HtmlExtract {
    private static double linkTextRadio = 0.25; // 链接文字比

    // 过滤不必要的数据
    public static String filterContent(String str) {
        if (str == "") {
            return "";
        }
        str = str.replaceAll("(?is)<!DOCTYPE.*?>", "");
        str = str.replaceAll("(?is)<!--.*?-->", "");
        str = str.replaceAll("(?is)<script.*?>.*?</script>", "");
        str = str.replaceAll("(?is)<style.*?>.*?</style>", "");
        // str=str.replaceAll("&.{2,5};|&#.{2,5};", " ");
        return str;
    }

    // 计算链接数
    public static int calcLinks(Element node) {
        Elements links = node.select("a[href]");
        return links.size();
    }

    // 计算内容长度
    public static double calcWords(Element node) {
        String con = node.text();
        if (con.length() == 0) {
            return 1 + linkTextRadio;
        } else {
            return con.length();
        }
    }

    // 计算标点符号的个数
    public static int calcSign(Element node) {
        String[] sign = { ",", ";", ".", "\"", "'", "\\?", "。", ":", "," };
        int i = 0;
        for (String ch : sign) {
            int count = 0;
            count = node.text().split(ch).length - 1;
            i = +count;
        }
        return i;
    }

    // 将所有的空节点全部删除
    public static Element drawCon(Element node) {
        if (node.tagName() == "a") {
            // 这个就不用进去深入了
            return node;
        }
        int links; // 链接数
        double words; // 文字长度
        double cellRatio;
        int signs; // 符号出现的情况

        Elements nodes = node.children();
        for (Element cnode : nodes) {
            if (!cnode.hasText()) {
                // System.out.println("删除"+cnode);
                cnode.remove();
            } else {
                links = calcLinks(cnode);
                words = calcWords(cnode);
                cellRatio = links / words;
                signs = calcSign(cnode);
                if (signs < 1) {
                    // 删除没有标点符号的节点
                    cnode.remove();
                } else if (cellRatio > linkTextRadio) {
                    cnode.remove();
                } else {
                    drawCon(cnode);
                }
            }
        }
        return node;
    }

    // 提取标题
    private String drawTitle(String str) {
        // TODO Auto-generated method stub
        // 先取页面的title部分的值
        if (str.length() < 1) {
            return null;
        }
        String tit = "";
        int xhpos = -1; // 下划线的位置
        int zhpos = -1; // 中横线的位置
        Pattern pt = Pattern.compile("<title>(.*)</title>",
                Pattern.CASE_INSENSITIVE);
        Matcher mc = pt.matcher(str);
        if (mc.find()) {
            tit = mc.group(1).trim();
            // 下面需要过滤一下,有些标题会加上下划线或者中横线
            xhpos = tit.indexOf("_");
            zhpos = tit.indexOf("|");
            if (xhpos > 0) {
                tit = tit.substring(0, xhpos);
            }
            if (zhpos > 0) {
                tit = tit.substring(0, zhpos);
            }
        }

        return tit;
    }

    // 提取作者
    private String[] drawAuthor(String str) {
        if (str.length() < 1) {
            return null;
        }
        // 这种信息一般就是直接用正则就好
        String[] author = new String[2];
        int tPos = 0; // 日期所在的位置
        Pattern pt = Pattern.compile(
                "作者.+(\\d{4}[-|年]\\d{1,2}[-|月]\\d{1,2}[日]?)",
                Pattern.CASE_INSENSITIVE);
        Matcher mc = pt.matcher(str);
        if (mc.find()) {
            // System.out.println("123");
            author[0] = mc.group(1); // 存储日期信息
            tPos = mc.group().trim().indexOf(author[0]);
            author[1] = mc.group().trim().substring(0, tPos);
            return author;
        }
        return null;
    }

    // 核心处理函数
    public String[] extract(String str) {
        String title; // 标题
        //String author = ""; // 作者
        //String uptime = ""; // 发布时间
        String content; // 正文
        //String[] authors = new String[2];

        str = filterContent(str);
        Document doc = Jsoup.parse(str);
        // 取body
        Element bodynode = doc.select("body").first();
        title = drawTitle(str);
        //authors = drawAuthor(str);
        // 开始遍历节点,进行去噪处理,抽取正文
        content = drawCon(bodynode).text();
        // 防止溢出
//        if (authors.length > 1) {
//            author = authors[1];
//            uptime = authors[0];
//        }
//        System.out.println(title);
//        System.out.println(author);
//        System.out.println(uptime);
//        System.out.println(content);
        String[] arr = new String[2];
        arr[0] = title;
        arr[1] = content;
        return arr;
    }

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

 

posted on 2013-08-16 13:46  雨渐渐  阅读(1648)  评论(0编辑  收藏  举报

导航