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){ } }
java版 正文抽取 基于文字连接比的更多相关文章
- 基于opencv将视频转化为字符串Java版
		
基于opencv将视频转化为字符串Java版 opencv java 先上一个效果图吧 首先,弄清一下原理 我们要将视频转化为字符画,那么就需要获取画面的每一帧,也就是每一张图片,然后将图片进行转化 ...
 - java版gRPC实战之七:基于eureka的注册发现
		
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
 - 网页爬虫的设计与实现(Java版)
		
网页爬虫的设计与实现(Java版) 最近为了练手而且对网页爬虫也挺感兴趣,决定自己写一个网页爬虫程序. 首先看看爬虫都应该有哪些功能. 内容来自(http://www.ibm.com/deve ...
 - 编写你的第一个 Java 版 Raft 分布式 KV 存储
		
前言 本文旨在讲述如何使用 Java 语言实现基于 Raft 算法的,分布式的,KV 结构的存储项目.该项目的背景是为了深入理解 Raft 算法,从而深刻理解分布式环境下数据强一致性该如何实现:该项目 ...
 - Java版分布式ID生成器技术介绍
		
分布式全局ID生成器作为分布式架构中重要的组成部分,在高并发场景下承载着分担数据库写瓶颈的压力. 之前实现过PHP+Swoole版,性能和稳定性在生产环境下运行良好.这次使用Java进行重写,目前测试 ...
 - 常见排序算法题(java版)
		
常见排序算法题(java版) //插入排序: package org.rut.util.algorithm.support; import org.rut.util.algorithm.Sor ...
 - 如何做系列(4)-微博URL短网址生成算法原理(java版、php版实现实例)
		
短网址(Short URL),顾名思义就是在形式上比较短的网址.通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流.目前已经有许多类似服务,借助短网址您可以用简短的网址替代 ...
 - 推荐一款自研的Java版开源博客系统OneBlog
		
OneBlog 一款超好用的Java版开源博客 Introduction 简介 OneBlog 一个简洁美观.功能强大并且自适应的Java博客.使用springboot开发,前端使用Boot ...
 - java版gRPC实战之一:用proto生成代码
		
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
 
随机推荐
- Android EventBus
			
https://github.com/greenrobot/EventBus onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也 ...
 - VB学习笔记
			
stack segment stack 'stack' dw dup() ;此处输入堆栈段代码 stack ends data segment ;IBUF OBUF 看成是内存的地址,IBUF+1和I ...
 - 100 high quality blogs from java developers
			
This list collects 100 high quality blogs from Java developers from all over the world. Some of thes ...
 - Double跟double
			
Double 是类 double是基础数据类型.Double类型是double的包装类,在JDK1.5以后,二者可以直接相互赋值,称为自动拆箱和自动装箱.看你的提示,我推测你的jdk版本在1.5以前. ...
 - initMethod 和 afterPropertiesSet  以及 AwareMethod方法的执行时机
			
在spring开发中,我们定义bean 经常会需要用到beanFactory对象,这就需要实现BeanFactoryAware这种类型的接口,它有一个setBeanFactory方法 在xml中配 ...
 - 脱离Xcode,程序在模拟器中无法运行
			
今天在调试项目的时候 突然发现,如果项目不通过Xcode启动而是直接通过模拟器进行启动,程序闪一下马上退出,并且不是闪退,而是跑到后台去了,并且后台的程序同样无法启动.找了好多解决办法,最后的解决方案 ...
 - xcode 最近打开文件列表显示为空或不显示最近打开的项目或(no  recent projects)解决办法
			
如果使用的是10.10 系统,打开系统设置-->进入通用-->在最下面的"最近使用的项目"中将0改为你可以接受的选项 如果不是10.10,那么就从系统偏好设置---&g ...
 - C++中delete和delete[]的使用
			
偶然的机会要使用到动态分配整形数组,怎么删除new出来的东西一时有点模糊(也许一直就不知道),于是在VS上试了试(写代码时经常用这种方法去验证模凌两可的东西),总结出来有两点. 1.基本数据类型new ...
 - C++11中新特性之:lambda 表达式
			
首先摆出Lambda表达式语法 lambda-expression: lambda-introducer lambda-declaratoropt compound-statementlambda-i ...
 - Check Mysql Database Size
			
SELECT ROUND( SUM(data_length + index_length) / 1024 / 1024 ) TOTAL_MB, ROUND(SUM(data_length) / 102 ...