具体的方案参见博客
基于概率的网页正文页抽取方案
代码实现如下:
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. 功能介绍** - 一键抽取班里的一位同学 - 可选择是否允许重复抽取同一位同学 - 可更改每个同学被抽...
**代码实现** 项目提供的`main.py`文件应该是模型的主入口,负责设置超参数、加载数据、构建模型、训练模型以及保存模型。而`predict.py`则是模型的预测脚本,用于对未标注的文本进行预测并输出结果。 在使用这个...
自然语言处理(NLP)是计算机科学领域的一个...在这个开源资料中,可能包含了实现这些步骤的具体代码、模型参数和实验结果。学习和理解这些内容可以帮助我们深入掌握短语抽取的原理和技术,并能应用于实际的NLP项目中。
前者适用于特定领域的共性代码复用,通过抽取代码片段和功能模块的模板,支持两个层次的复用推荐,较少依赖相似代码副本。后者适用于领域无关的通用代码复用,利用大量的训练数据,推荐单行或多行API调用代码。 ...
系统流程包括基于左右信息熵扩展的候选领域术语获取、基于词性搭配规则与边界信息出现概率知识库相结合的词语度筛选策略以及基于词频—逆文档频率(TF-IDF)的领域度筛选策略。运用此算法不但能抽取出领域的常见用词...
开发者通过编写JavaScript代码,实现了用户与网页的交互,动态地生成满足条件的随机数序列,满足了不同用户的个性化需求。对于初学者和专业人士来说,了解并掌握这样的工具及其工作原理,对于提升编程技能和解决实际...
0 引言 信道化接收机是在并行多通道接收机基础上提出的全概率频分信道化...基于多相滤波的信道化接收机抽取在滤波之前,运算量小,且输出速率低,便于FPGA实现,这使得在 一片FPGA中实现数字信道化成为可能。本文
4. **答案排序与过滤**:找到多个可能的答案后,需要通过排序算法(如基于评分的排序或基于概率的排序)确定最有可能正确的一个或几个答案。同时,还需要过滤掉不相关或者不准确的信息。 5. **后处理**:对找到的...
权重控制随机抽取率的实现通常基于概率质量函数(Probability Mass Function, PMF)的概念。PMF定义了随机变量取每个可能值的概率。在我们的场景中,每个元素都有一个与之关联的权重,这个权重代表了它被选中的概率...
在提供的压缩包文件"基于JavaScript的抽奖程序设计与实现"中,很可能会包含相关的源代码示例,包括HTML、CSS和JavaScript文件。通过分析这些代码,你可以更深入地学习如何将上述理论知识应用到实际项目中。 总的来...
FACTORIE,全称为"Factorie: A Deployable Probabilistic Modeling Toolkit",是一个基于Scala编程语言的强大软件库,专门用于构建和部署概率模型。它为数据科学家、机器学习工程师和自然语言处理专家提供了一个高效...
【优化算法】基于Thompson 采样实现多目标优化问题附matlab代码.zip这个压缩包包含了一套使用Matlab实现的多目标优化解决方案,重点在于Thompson采样策略的应用。Thompson采样是一种在贝叶斯决策理论下进行随机抽样...
本文将深入探讨如何使用jieba库来实现高效、精准的关键字抽取,帮助你更好地理解和应用这一强大的技术。 jieba库的核心功能是中文分词,它基于大量语料库训练出的模型,能够将连续的汉字序列拆分成具有实际意义的...
3. **权重选择**:为了实现基于概率的抽取,可以使用累积权重法。将所有奖项的概率相加得到总权重,然后生成一个介于0到总权重之间的随机数。通过遍历奖项,比较随机数与每个奖项的累计概率,当随机数小于某个累计...
全连接层将特征图转化为分类概率;激活函数如ReLU引入非线性,使模型具有更强的表达能力。 在车牌识别中,CNN通常经过以下步骤训练和应用: 1. 数据预处理:收集大量车牌图像,包括不同角度、光照、背景等条件下的...
这个程序的设计基于概率事件的理论,这意味着它能够模拟真实世界中的随机抽选过程,确保每个参与者都有公平的中奖机会。在深入探讨这个项目之前,我们首先需要了解C#编程语言以及VS2005开发环境。 C#(读作"C Sharp...
本项目基于Microsoft Visual Studio 2005(简称VS2005)进行开发,利用C#语言的强大功能,实现了从一组预设的数字中随机抽取中奖号码的功能。下面将详细阐述该程序的关键知识点。 首先,程序的核心在于生成随机数。...
Delphi是Embarcadero Technologies开发的一款集成开发环境(IDE),基于Object Pascal语言,以其高效、简洁的代码和丰富的组件库著称。在创建抽奖系统时,我们可以利用Delphi的VCL(Visual Component Library)组件...
HTML5转盘抽奖小程序是一种基于网页技术的抽奖游戏,通过转动转盘来随机抽取奖品的一种互动形式。这种小程序通常包括转盘设计、奖品设置、抽奖逻辑等功能,可以在网页上直接运行,无需下载安装任何插件。HTML5转盘...