public class CopyOfContentExtractor {
private static final int MIN_NODE_TEXT_LENGTH = 20; // //正文的最小长度
private static final int MIN_K = 30; // //有了链接分析,可以设置高一些,粗放一些
private static final double MAX_LINK_RATE = 0.5; // ///最小链接率
private double TEMP_MAX_LENGTH = 0;
private Node targetNode = null;
public String title = "";
public List<String> imgSrcList = new ArrayList<String>();
public String address;
/**
* 解析本地html文件
*
* @param address
*/
public void parseHTM(String location, String address) {
this.address = address;
try {
parse(new FileInputStream(new File(location)));
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解析传入的url地址
*
* @param address
*/
public void parseURL(String address) {
this.address = address;
try {
URL url = new URL(address);
parse(url.openConnection().getInputStream());
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void parse(InputStream ips) throws SAXException, IOException {
DOMParser parser = new DOMParser();
parser.setProperty("http://cyberneko.org/html/properties/default-encoding", "utf-8");
parser.parse(new InputSource(ips));
Document doc = parser.getDocument();
Node body = doc.getElementsByTagName("body").item(0); // 抽取内容
if (body != null) {
NodeList list = body.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
loop(node); // //////递归调用
}
// //////此时已对targetNode赋值
if (targetNode != null) {
linkNodeFilter(targetNode);
// //////进行链接分析继续对目标node的dom过滤
// refixTargetNodeByLinkAnalysis(this.targetNode);
// //////抽取目标node内的图片地址
imgExtractor(targetNode);
} else {
System.out.println("extractor is NULL!!! ");
}
}
}
public void loop(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element elmt = (Element) node;
if (!elmt.getTagName().equals("STYLE") && !elmt.getTagName().equals("SCRIPT")) {
NodeList list = node.getChildNodes();
if (list.getLength() == 1) {
loop(list.item(0));
} else {
double[] lengthArr = new double[list.getLength()];
for (int i = 0; i < list.getLength(); i++) { /////计算每个子节点的文本长度
String text = textExtractor(list.item(i));
///System.out.println("text: " + text);
lengthArr[i] = text.length();
}
// ////////遍历每一个长度,判断走向
double sum = 0.0;
for (double d : lengthArr) {
sum += d;
}
if (sum > MIN_NODE_TEXT_LENGTH) {
double mean = sum / lengthArr.length;
double varianceSum = 0.0;
for (double d : lengthArr) {
varianceSum += (d - mean) * (d - mean);
}
double variance = varianceSum / lengthArr.length; // /////方差
double k = variance / sum;
////System.out.println("k:" + k);
if (k < MIN_K) {
////System.out.println(k + " " + textExtractor(node));
////抽取正文node
if (sum > TEMP_MAX_LENGTH) {
TEMP_MAX_LENGTH = sum;
targetNode = node;
}
} else {
////重新采用链接分析的办法筛选
for (int i = 0; i < list.getLength(); i++) { /////计算每个子节点的文本长度
lengthArr[i] = lengthArr[i] - linkAnalysis(list.item(i)); ///减去链接文本长度
}
int maxIndex = getMaxIndex(lengthArr);
loop(list.item(maxIndex));
}
}
}
}
}
}
// 抽取节点文本递归部分
public String textExtractor(Node root) {
// 若是文本节点的话,直接返回
if (root.getNodeType() == Node.TEXT_NODE) {
return root.getNodeValue().trim();
}
if (root.getNodeType() == Node.ELEMENT_NODE) {
Element elmt = (Element) root;
// 去除脚本
if (elmt.getTagName().equals("STYLE") || elmt.getTagName().equals("SCRIPT"))
return "";
NodeList children = elmt.getChildNodes();
StringBuilder text = new StringBuilder();
for (int i = 0; i < children.getLength(); i++) {
String innerText = textExtractor(children.item(i));
if (innerText.length() > 5) {
text.append(innerText + " ");
}
}
return text.toString();
}
// 对其它类型的节点,返回空值
return "";
}
// 抽取图片地址递归部分
private void imgExtractor(Node root) {
if (root.getNodeType() == Node.ELEMENT_NODE) {
Element elmt = (Element) root;
if (elmt.getTagName().equals("IMG") || elmt.getTagName().equals("img")) {
String src = elmt.getAttribute("real_src").isEmpty() ? elmt.getAttribute("src") : elmt.getAttribute("real_src");
if (!src.startsWith("http://")) { // //////如果图片地址是相对地址
String sub = address.substring(7);
int index = sub.indexOf("/");
src = "http://" + sub.substring(0, index) + src;
}
imgSrcList.add(src);
}
NodeList children = elmt.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
imgExtractor(children.item(i));
}
}
}
/**
* 计算节点链接文本长度,非破坏性
* @param root
* @return
*/
private double linkAnalysis(Node root) {
// 若是文本节点的话,直接返回
if (root.getNodeType() == Node.TEXT_NODE
&& (root.getParentNode().getNodeName().endsWith("a") || root.getParentNode().getNodeName().endsWith("A"))) {
return root.getNodeValue().trim().length();
}
if (root.getNodeType() == Node.ELEMENT_NODE) {
Element elmt = (Element) root;
// 去除脚本
if (elmt.getTagName().equals("STYLE") || elmt.getTagName().equals("SCRIPT"))
return 0.0;
NodeList children = elmt.getChildNodes();
double temp = 0.0;
for (int i = 0; i < children.getLength(); i++) {
double innerTemp = linkAnalysis(children.item(i));
temp += innerTemp;
}
return temp;
}
// 对其它类型的节点,返回空值
return 0.0;
}
private int getMaxIndex(double[] input) {
int index = 0;
double temp = 0.0;
for (int i = 0; i < input.length; i++) {
if (temp < input[i]) {
temp = input[i];
index = i;
}
}
return index;
}
/**
* 采用remove风格处理targetNode:链接分析
*/
private void linkNodeFilter(Node node) {
if (node != null) {
NodeList children = node.getChildNodes();
// //拼接网页正文
for (int i = 0; i < children.getLength(); i++) {
Node subNode = children.item(i);
// ///链接分析
String text = textExtractor(subNode);
double textLength = text.length();
if (textLength > 0) {
// System.out.println("Text:" + text);
// System.out.println(subNode.getNodeName());
double linkLen = linkAnalysis(subNode);
double linkRate = linkLen / textLength;
// System.out.println("linkLen: " + linkLen + "; textLen: "
// + textLength + "; linkRate: " + linkRate);
// System.out.println(100 * linkRate / (linkLen +
// textLength));
if (linkRate < MAX_LINK_RATE) {
linkNodeFilter(subNode);
} else {
node.removeChild(subNode);
}
}
}
}
}
/**
*
* @return
*/
private String getContent() {
if(targetNode != null){
return textExtractor(targetNode);
}else{
return "NULL";
}
}
// //////////
public static void main(String[] argv) throws IOException {
int count = 0;
for (File f : new File("D:/fxreader/data/2012-09-29-00-13").listFiles()) {
CopyOfContentExtractor extractor = new CopyOfContentExtractor();
extractor.parseHTM(f.getAbsolutePath(), Options.rules_startsWith);
String content = extractor.getContent();
if(content.length() > 200 ){
count++;
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File("D:/fxreader/content/2012-09-29-00-13/" + f.getName()+ "_" + content.length() + "_" + ".txt")), "utf-8"));
pw.append(content);
//FileUtils.writeStringToFile(new File("D:/fxreader/content/" + f.getName()+ "_" + content.length() + "_" + ".txt"), content, "utf-8");
pw.flush();
pw.close();
System.out.println("missing: " + f.getName());
}
System.out.println(count);
};
}
}
实验测试,错误率:42/500.其中,42篇中大多为原网页不含有“正文”的网页。
分享到:
相关推荐
标题中的“3500基于k-均值的正文抽取”指的是一个使用k-均值算法来实现的文本摘要系统,可能是一个Java编程项目。k-均值算法是一种常见的无监督学习方法,常用于数据聚类,这里被应用于正文抽取,即从文本中找出关键...
机器学习是人工智能的一个分支,主要研究如何通过算法让计算机模拟人类的学习行为,对数据进行分析和学习。机器学习算法通常可以分为生成模型和判别模型,其中生成模型关注于生成数据的过程,而判别模型则关注于根据...
选择合适的特征抽取策略取决于具体的应用场景和数据特性,如图像分析、文本分类或语音识别等。通过深入理解各种特征类型和抽取方法,我们可以更有效地构建和优化机器学习模型,提高预测和识别的准确性。
在当今信息化时代,数据挖掘作为一种利用算法发现数据背后隐藏的知识的技术,已成为数据分析和决策支持的重要手段。本文主要探讨了数据挖掘的任务和方法,并对数据挖掘算法的并行模式进行了深入研究。 首先,数据...
SAS软件可以处理各种数据格式,包括文本文件、数据库中的数据、网页数据等。它提供了多种数据步骤(Data step)语句用于数据的导入、清洗、转换和准备,以及实现数据的集成功能。 3. 数据分析和统计 SAS提供了一...
这些数据源可以非常多样化,既包括传统的结构化数据来源(如关系型数据库中的表格数据),也包括半结构化数据(例如Web服务器的日志文件)和非结构化数据(比如社交媒体上的文本、图片或视频数据)。 - **重要性**...
该算法通过降维技术,从高维空间变换到低维空间,寻找具有最大方差和最小标准差的最优特征值,以此来优化文本分类的效果。 此外,文章还介绍了如何建立网络舆情热点词库,这涉及到对聚类后的文本数据进行特征提取。...
【支持向量机(SVM)】支持向量机是一种监督学习模型,主要用于分类和回归分析。它的核心思想是通过构造最大边距超平面来分割数据,使得两类样本在超平面两侧保持最大的间隔。SVM在处理小样本和高维空间问题时表现出...
- **特征抽取**:通过`sklearn.feature_extraction`模块,可以将非结构化的数据(如文本或图像)转换成数值特征,便于算法处理。例如,字典特征提取将键值对转换为向量,而文本特征提取如Jieba分词和TF-IDF可以帮助...
Python提供了多种统计方法,如相关性分析、方差分析和卡方检验来评估特征的重要性。此外,机器学习算法,如决策树、随机森林和逻辑回归,也能根据特征对目标变量的影响进行排序,帮助选择关键特征。 特征转换是将...
这包括描述性统计(如均值、中位数、方差等)和推断性统计(如假设检验、回归分析等),以及预测模型的建立。统计分析法借助于数学和计算机科学,已经成为科学研究和决策制定不可或缺的工具。 最后,数据挖掘和模型...
该算法通过构建多个决策树并结合它们的预测结果来提高整体预测准确性和防止过拟合。下面我们将深入探讨随机森林的基本原理、工作流程以及其在实际应用中的优势。 一、随机森林的基本概念 1. 决策树:随机森林中的...
9. **TF-IDF**:TF-IDF是一种衡量词语在文档中重要性的方法,常用于文本分析和信息检索,有助于识别文档的主题。 10. **数据挖掘与统计**:数据挖掘侧重于自动发现知识,而统计更关注推断和验证假设。两者都使用...
- **情感分析**: 一种自然语言处理任务,旨在识别和提取文本中的主观信息,如情绪、态度和观点等。 - **Transformer**: 一种革命性的神经网络架构,使用自注意力机制替代了传统的循环神经网络,大大提高了训练速度和...
数据挖掘是一种从海量数据中发现有...这些知识点涵盖了数据挖掘的核心概念和技术,它们在现代数据分析和决策支持中起着关键作用。随着大数据和人工智能的发展,数据挖掘的未来将更加注重实时性、智能化和模型解释能力。
- **解析**: K-means是一种基于距离的聚类算法,它需要预先指定聚类的数量K。初始中心点通常是随机选取的。因此,正确选项是**C. 不能自动识别类的个数,随即挑选初始点为中心点计算**。 **3. 时间序列算法模型** ...
- **情绪分析与情感识别:** 通过情感分析和情感识别技术,深入了解借款人的情绪倾向和风险偏好。 **社交关系与互动:** - 分析借款人在社交网络上的社交关系、互动频率和参与度,以反映其社会资本和信用状况。 - ...