具体的方案参见博客
基于概率的网页正文页抽取方案
代码实现如下:
maven依赖:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.common</groupId> <artifactId>commons-codec</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.10</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.4</version> </dependency>
公共类:
import java.util.HashSet; import java.util.Set; import org.apache.commons.codec.digest.DigestUtils; /** * 训练集封装的value object * @date 2013-10-21 */ public class ItemTrainVo { private ItemTrainVo() { super(); } /**更新实例的same number同时加入text对应的md5值 * @param insance ItemTrainVo实例 * @param xpath xpath * @param text 解析dom树节点对应的文本值 * @date 2013-10-21 */ public static void updateInstance(ItemTrainVo insance, String xpath, String text) { insance.setXpath(xpath); String md5Text = DigestUtils.md5Hex(text); if (insance.getMd5Texts().contains(md5Text)) { insance.setSameNum(insance.getSameNum() + 1L); } insance.getMd5Texts().add(md5Text); } /**创建一个空的实例 * @param xpath xpath * @param text 解析dom树节点对应的文本值 * @return 返回创建的实例 * @date 2013-10-21 */ public static ItemTrainVo getInstance(String xpath, String text) { ItemTrainVo insance = new ItemTrainVo(); insance.setXpath(xpath); String md5Text = DigestUtils.md5Hex(text); if (insance.getMd5Texts().contains(md5Text)) { insance.setSameNum(insance.getSameNum() + 1L); } insance.getMd5Texts().add(md5Text); return insance; } private String xpath; private Set<String> md5Texts = new HashSet<String>(); private long sameNum = 0L; public String getXpath() { return xpath; } public void setXpath(String xpath) { this.xpath = xpath; } public Set<String> getMd5Texts() { return md5Texts; } public void setMd5Texts(Set<String> md5Texts) { this.md5Texts = md5Texts; } public long getSameNum() { return sameNum; } public void setSameNum(long sameNum) { this.sameNum = sameNum; } @Override public String toString() { return xpath + "=>" + md5Texts + ""; } }
抽象训练器,如果以后有获取css path的可以继承此类:
import java.math.BigDecimal; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import com.panguso.techrd.parser.trainer.vo.ItemTrainVo; public abstract class BaseTrainer { /** * 基于概率阀值清理训练结果,保留符合条件的结果,返回最终的标签相对模板集合 * * @param map 训练中间数据传输对象map * @param q 概率阀值 * @throws Exception Exception * @date 2013-10-24 */ protected Set<String> cleanResult(Map<String, ItemTrainVo> map, double q) throws Exception { Iterator<Entry<String, ItemTrainVo>> iterator = map.entrySet().iterator(); Set<String> xpaths = new HashSet<String>(); while (iterator.hasNext()) { Entry<String, ItemTrainVo> entry = iterator.next(); ItemTrainVo itv = entry.getValue(); BigDecimal dif = new BigDecimal(itv.getMd5Texts().size()); BigDecimal all = new BigDecimal(itv.getMd5Texts().size() + itv.getSameNum()); BigDecimal result = dif.divide(all, 3, BigDecimal.ROUND_HALF_DOWN); if (result.doubleValue() < q) { iterator.remove(); } else { xpaths.add(itv.getXpath()); } } return xpaths; } /** * 基于训练集提取其所有的text和需要处理的标签对应的path(css * path或者xpath基于具体的实现)作为key,value为map,其key为标签路径 * ,value为封装结构体,其中包括了相对标签path,所有的text值,以及出现相同次数,依此作为概率计算基数。 * * @param path path为训练集的根目录 * @param map 空的map * @throws Exception Exception * @date 2013-10-24 */ protected abstract void parseInfo(String path, Map<String, ItemTrainVo> map) throws Exception; /** * 对外暴漏的方法,提取最终的训练集合,map的key为标签path,value为其例子 * * @param fileDirPath 训练集根路径 * @return 训练结果 * @date 2013-10-24 */ public abstract Map<String, String> train(String fileDirPath); /** * 获取除了text之外要提取的标签比如<img> * * @return 返回需要提取的标签列表 * @date 2013-10-24 */ protected abstract Set<String> getUsefullTags(); /** * 获取需要过滤的标签比如<HEADE>,训练器当碰到之后就会忽略下层迭代处理 * * @return 返回要过滤的标签列表 * @date 2013-10-24 */ protected abstract Set<String> getUnUsefullTags(); }
基于xpath训练器的实现:
import java.io.File; import java.io.FileInputStream; import java.math.BigDecimal; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.cyberneko.html.parsers.DOMParser; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.DOMReader; import org.xml.sax.InputSource; import com.panguso.techrd.parser.trainer.vo.ItemTrainVo; /** * 基于概率的xpath训练器实现 * * @date 2013-10-24 */ public class XPathTrainer extends BaseTrainer { private Set<String> usefullTags = Collections.emptySet(); private Set<String> unUsefullTags = Collections.emptySet(); public XPathTrainer(Set<String> usefullTags, Set<String> unUsefullTags) { super(); this.unUsefullTags = unUsefullTags; this.usefullTags = usefullTags; } @Override protected Set<String> getUnUsefullTags() { return unUsefullTags; } @Override protected Set<String> getUsefullTags() { return usefullTags; } @Override public Map<String, String> train(String fileDirPath) { Map<String, ItemTrainVo> map = new HashMap<String, ItemTrainVo>(); Map<String, String> result = new HashMap<String, String>(); try { parseInfo(fileDirPath, map); Set<String> xpaths = cleanResult(map, computQ(fileDirPath, true)); getResult(fileDirPath, result, xpaths); } catch (Exception e) { e.printStackTrace(); } return result; } private void getResult(String path, Map<String, String> result, Set<String> xpaths) throws Exception { File file = new File(path); if (!file.isDirectory()) { return; } File[] files = file.listFiles(); for (File file2 : files) { if (file2.isFile()) { DOMParser parser = new DOMParser(); parser.parse(new InputSource(new FileInputStream(file2))); DOMReader domReader = new DOMReader(); Document document = domReader.read(parser.getDocument()); Element root = document.getRootElement(); Iterator<String> xpathIterator = xpaths.iterator(); while (xpathIterator.hasNext()) { String xpath = xpathIterator.next(); Element node = (Element) root.selectSingleNode(xpath); result.put(xpath, node.asXML()); } return; } } } private double computQ(String path, boolean defaultVal) { if (defaultVal) { return 1.0d; } File file = new File(path); int num = 0; File[] files = file.listFiles(); for (File file2 : files) { if (file2.isFile()) { num++; } } BigDecimal dif = new BigDecimal(num - 1); BigDecimal all = new BigDecimal(num); BigDecimal result = dif.divide(all, 3, BigDecimal.ROUND_HALF_DOWN); return result.doubleValue(); } @Override protected void parseInfo(String path, Map<String, ItemTrainVo> map) throws Exception { File file = new File(path); if (!file.isDirectory()) { return; } File[] files = file.listFiles(); for (File file2 : files) { if (file2.isDirectory()) { continue; } DOMParser parser = new DOMParser(); parser.parse(new InputSource(new FileInputStream(file2))); DOMReader domReader = new DOMReader(); Document document = domReader.read(parser.getDocument()); Element root = document.getRootElement(); dom2PathMap(root, map); } } @SuppressWarnings("unchecked") private void dom2PathMap(Element root, Map<String, ItemTrainVo> map) { if (this.getUnUsefullTags().contains(root.getName())) { return; } if (root == null || root.isTextOnly() || this.getUsefullTags().contains(root.getName())) { String text = root.getText(); String uniqXpath = root.getUniquePath(); String xpath = root.getPath(); if (StringUtils.isEmpty(text)) { Iterator<Attribute> iterator = root.attributeIterator(); while (iterator.hasNext()) { Attribute attr = iterator.next(); text = attr.getName() + "." + attr.getValue() + text; } } if (map.containsKey(uniqXpath)) { ItemTrainVo.updateInstance(map.get(uniqXpath), xpath, text); } else { map.put(uniqXpath, ItemTrainVo.getInstance(xpath, text)); } return; } Iterator<Element> iterator = root.elementIterator(); while (iterator.hasNext()) { Element el = iterator.next(); dom2PathMap(el, map); } } }
测试代码:
import java.util.HashSet; import java.util.Set; import org.junit.Test; import com.panguso.techrd.parser.trainer.service.XPathTrainer; public class XPathTrainerTest { @Test public final void testTrain() { Set<String> usefullTags = new HashSet<String>(); Set<String> unUsefullTags = new HashSet<String>(); usefullTags.add("IMG"); unUsefullTags.add("HEAD"); unUsefullTags.add("SCRIPT"); String path = "/dom/163/shehui"; XPathTrainer xt = new XPathTrainer(usefullTags, unUsefullTags); System.out.println(xt.train(path)); } }
测试集如附件:
相关推荐
基于python实现的随机抽取器源码(带GUI界面)+项目说明.zip # 随机抽取器 *一款轻量方便的课堂小工具* ## **1. 功能介绍** - 一键抽取班里的一位同学 - 可选择是否允许重复抽取同一位同学 - 可更改每个同学被抽...
系统流程包括基于左右信息熵扩展的候选领域术语获取、基于词性搭配规则与边界信息出现概率知识库相结合的词语度筛选策略以及基于词频—逆文档频率(TF-IDF)的领域度筛选策略。运用此算法不但能抽取出领域的常见用词...
HTML5转盘抽奖小程序是一种基于网页技术的抽奖游戏,通过转动转盘来随机抽取奖品的一种互动形式。这种小程序通常包括转盘设计、奖品设置、抽奖逻辑等功能,可以在网页上直接运行,无需下载安装任何插件。HTML5转盘...
机器学习项目基于CNN实现布的匹缺陷检测Matlab源代码(准确度达97.79%)+项目详细说明+代码注释.zip 【资源介绍】 该项目是个人毕设项目,答辩评审分达到95分,代码都经过调试测试,确保可以运行!欢迎下载使用,可...
Python2和Python3实现 机器学习接口 API接口 机器学习(考虑Python3处理中文字符编码的优势,先实现Python3版本) 架构图形学习网络 上下文信息存储 图形数据库neo4j存储 语义依存树的neo4j表示与存储 大规模...
首先以缺陷的源代码元素集合生成特征元素集合,抽取代码结构信息,构建分析模型。然后依据各类中间表示(IR,intermediate representation)语句的统计概率计算分析模型,查找满足特征模型的IR代码组,通过IR代码与二...
该考试系统基本实现了考生登录、自动组卷、做题、回收答案等功能,但是没有实现阅卷功能。其中自动组卷是采用了一种算法来打乱每套试题的题目顺序(算法见4.2),而不是将题库中的题目随机组合成一套试卷。虽然采用...
基于python和opencv实现图像拼接并计算PSNR项目源码+项目使用说明.zip 该项目是个人毕设项目,答辩评审分达到95分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。 该资源主要针对计算机...
如果基础还行,可以在此代码基础之上做改动以实现更多功能。 本项目主要实现了疾病自诊和医生推荐两个功能并构建了医生服务指标评价体系。疾病自诊主要通过利用BERT+CRF+BiLSTM的医疗实体识别, 建立医学知识图谱, ...
采集微博营销公众号数据抽取凝聚子群构建网络,建立嵌入凝聚子群因素的信息传播模型SIRC,并以该模型为基础采用MATLAB仿真口碑信息在凝聚子群网络上的传播过程,研究了口碑信息在复杂网络和子群网络的传播效应的不同...
1、猫和狗的数据集下载地址https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/data,只使用其中的train文件。 2、实现对数据集的加载、读取和划分,...随机抽取十张图片的测试结果,概率准确度95%以上。
基于与统计能量的类比,实现 Aslan & Zech 和 Szekely & Rizzo 的检验,当两个样本从相同的父分布中抽取时,该检验被最小化 这种方法的主要参考文献似乎是: , Aslan & Zech (2005) , 塞克利和里佐 (2014) multdist...
将文档集中每篇文档的主题以概率分布的形式给出,从而通过分析一些文档抽取 出它们的主题分布后,便可以根据主题分布进行主题聚类或文本分类。 机器学习的模型分为两种,一种是基于策略,即不能给出明确的数据分布的...
为了实现可伸缩性,推断基于后验分布的(梯度近似)。 分发中的每个抽奖均附有指南分发。 scala-infer概率模型被编写为常规的scala代码。 值是从分布中提取的,用于生成数据。 这种模型被称为生成模型,因为它提供...
基于对理想或非理想抽取下的BP过程的分析,该算法首先估计描述非理想抽取效果的条件概率分布,然后调整先验值以使分布与理想情况相匹配。 如仿真结果所示,该恢复算法可以极大地提高量化性能,将整形损耗降低至0....
提出了一种基于累积差分RGB三通道的火焰闪频特征抽取方法,并用逻辑回归(logistic regression,LR)对火焰的闪频特征进行分析,得到了优化的权重和偏斜率,建立了火焰闪频特征值的概率模型。最后将概率模型应用于...
该实现基于Java,并且只需很少的修改即可用于任何文本语料库(即,对您自己的语料库进行文本处理)。 那么LDA和DCMLDA有什么区别? 下图显示了这两种模型之间的差异。 我们可以看到,区别在于主题词分布\ phi。 在...
特性标配补给,装备补给和精准补给自定义蛋池配置(任意物品及概率)批量抽取配置(可用于验证)几乎和游戏一致的界面风格,拥有保底机制和替代开启。应用地址BAE: Github Pages(备用): 可配置的物品名称全部都...