引言:网络爬虫让我们高效地从网页获取到信息,但网页的重复率很高,网页需要按内容做文档排重,而判断文档的内容重复有很多种方法,语义指纹是其中比较高效的方法。
本文选自《网络爬虫全解析——技术、原理与实践》。

  现代社会,有效信息对人来说就像氧气一样不可或缺。互联网让有效信息的收集工作变得更容易。当你在网上冲浪时,网络爬虫也在网络中穿梭,自动收集互联网上有用的信息。
  自动收集和筛选信息的网络爬虫让有效信息的流动性增强,让我们更加高效地获取信息。随着越来越多的信息显现于网络,网络爬虫也越来越有用。
  不同的网站间转载内容的情况很常见。即使在同一个网站,有时候不同的URL地址可能对应同一个页面,或者存在同样的内容以多种方式显示出来,所以,网页需要按内容做文档排重。
  例如,一个企业商品搜索。搜商品名,有一家公司发的商品名字都一样,结果这家公司发的商品都显示在前面,但是要求一家企业只显示一条相似的商品在前面,可以把近似重复的文档权重降低,只保留一个文档不降低权重。
  判断文档的内容重复有很多种方法,语义指纹的方法比较高效。语义指纹是直接提取一个文档的二进制数组表示的语义,通过比较相等来判断网页是否重复。语义指纹是一个很大的数组,全部存放在内存会导致内存溢出,普通的数据库效率太低,所以采用内存数据库Berkeley DB。可以通过Berkeley DB判断该语义指纹是否已经存在。另外一种方法是通过布隆过滤器来判断语义指纹是否重复。
  提取网页语义指纹的方法是:从净化后的网页中,选取最有代表性的一组关键词,并使用该关键词组生成一个语义指纹。通过比较两个网页的语义指纹是否相同来判断两个网页是否相似。
  网络上一度出现过很多篇关于“罗玉凤征婚”的新闻报道,其中的两篇新闻内容对比如下表。
  

  对于这两篇内容相同的新闻,有可能提取出同样的关键词:“罗玉凤”“征婚”“北大”“清华”“硕士”,这就表示这两篇文档的语义指纹也相同。
  为了提高语义指纹的准确性,需要考虑到同义词,例如,“北京华联”和“华联商厦”可以看成相同意义的词。最简单的判断方法是做同义词替换。把“开业之初,比这还要多的质疑的声音环绕在北京华联决策者的周围”替换为“开业之初,比这还要多的质疑的声音环绕在华联商厦决策者的周围”。
  设计同义词词典的格式是:每行一个义项,前面是基本词,后面是一个或多个被替换的同义词,请看下面的例子。

华联商厦 北京华联 华联超市

  这样可以把“北京华联”或“华联超市”替换成“华联商厦”。对指定文本,要从前往后查找同义词词库中每个要替换的词,然后实施替换。同义词替换的实现代码分为两步。首先是查找Trie树结构的词典过程。

public void checkPrefix(String sentence,int offset,PrefixRet ret) {if (sentence == null || root == null || "".equals(sentence)) {ret.value = Prefix.MisMatch;ret.data = null;ret.next = offset;return ;}ret.value = Prefix.MisMatch;//初始返回值设为没匹配上任何要替换的词TSTNode currentNode = root;int charIndex = offset;while (true) {if (currentNode == null) {return;}int charComp = sentence.charAt(charIndex) - currentNode.splitchar;    if (charComp == 0) {charIndex++;if(currentNode.data != null){ret.data = currentNode.data;//候选最长匹配词ret.value = Prefix.Match;ret.next = charIndex;}if (charIndex == sentence.length()) {return; //已经匹配完}currentNode = currentNode.eqKID;} else if (charComp < 0) {currentNode = currentNode.loKID;} else {currentNode = currentNode.hiKID;}}
}

  然后是同义词替换过程。

//输入待替换的文本,返回替换后的文本
public static String replace(String content) throws Exception{int len = content.length();StringBuilder ret = new StringBuilder(len);SynonymDic.PrefixRet matchRet = new SynonymDic.PrefixRet(null,null);  for(int i=0;i<len;){//检查是否存在从当前位置开始的同义词synonymDic.checkPrefix(content,i,matchRet);if(matchRet.value == SynonymDic.Prefix.Match) //如果匹配上,则替换同义词{ret.append(matchRet.data);//把替换词输出到结果i=matchRet.next;//下一个匹配位置}else //如果没有匹配上,则从下一个字符开始匹配{ret.append(content.charAt(i));++i;}}   return ret.toString();
}

  语义指纹生成算法如下所示。

  • 第1步:将每个网页分词表示成基于词的特征项,使用TF*IDF作为每个特征项的权值。地名、专有名词等,名词性的词汇往往有更高的语义权重。

  • 第2步:将特征项按照词权值排序。

  • 第3步:选取前n个特征项,然后重新按照字符排序。如果不排序,关键词就找不到对应关系。

  • 第4步:调用MD5算法,将每个特征项串转化为一个128位的串,作为该网页的指纹。

调用fseg.result.FingerPrint中的方法。

String fingerPrint = getFingerPrint("","昨日,省城渊明北路一名17岁的少年在6楼晾毛巾时失足坠楼,摔在楼下的一辆面包车上。面包车受冲击变形时吸收了巨大的反作用力能量,从而“救”了少年一命。目前,伤者尚无生命危险。据一位目击者介绍,事故发生在下午2时40分许,当时这名在某美发店工作的少年正站在阳台上晾毛巾,因雨天阳台湿滑而不小心摔下。 记者来到抢救伤者的医院了解到,这名少年名叫李嘉诚,今年17岁,系丰城市人。李嘉诚受伤后,他表姐已赶到医院陪护。据医生介绍,伤者主要伤在头部,具体伤情还有待进一步检查。");
String md5Value = showBytes(getMD5(fingerPrint));
System.out.println("FingerPrint:"+fingerPrint+" md5:"+md5Value);

  MD5可以将字符串转化成几乎无冲突的hash值,但是MD5速度比较慢,MurmurHash或者JenkinsHash也可以生成冲突很少的hash值,在Lucene的企业搜索软件Solr1.4版本中提供了JenkinsHash实现的语义指纹,叫作Lookup3Signature。调用MurmurHash生成64位的Hash值的代码如下所示。

public static long stringHash64(String str, int initial) {byte[] bytes = str.getBytes();return MurmurHash.hash64(bytes, initial);
}

  本文选自《网络爬虫全解析——技术、原理与实践》,点此链接可在博文视点官网查看此书。
                    
  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                       

此外,本周正在进行一项热门活动——《尽在双11》阿里专家问答!
《尽在双11》的作者乐田、仁重正通过开源问答来答复读者有关《尽在双11》这本书的疑问~
更多好问题,期待你来问!

网络爬虫之网页排重:语义指纹相关推荐

  1. 网络爬虫之网页数据解析(XPath)

    文章目录 引入 什么是XML XML的节点关系 XPath定义 XPath表达式 最常用的路径表达式 常用路径表达式以及表达式的结果 谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号 ...

  2. 网络爬虫:网页信息获取

    第1关:利用网页地址获取超文本文件 任务描述 本关我们将使用 Python 程序,实现通过打开网站的 URL,来获得服务器返回的超文本文件,并打印出来. 相关知识 打开一个网页,需要我们在浏览器中输入 ...

  3. 网络爬虫-获取网页中的数据加伪装头,伪装成浏览器多次访问,避免单次访问导致ip被封

    User-Agent:用户代理.是一种向访问网站提供你所使用的浏览器类型.操作系统及版本.CPU 类型.浏览器渲染引擎.浏览器语言.浏览器插件等信息的标识.UA字符串在每次浏览器 HTTP 请求时发送 ...

  4. 网络爬虫之网页数据解析(bs4)

    文章目录 定义 实例数据 遍历文档树 搜索文档树 CSS选择器 bs4实例 定义 和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HT ...

  5. php爬虫邮箱邮件,简单网络爬虫实现爬取网页邮箱

    网络爬虫(又被称为网页蜘蛛,网络机器人,在 FOAF 社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取 万维网 信息的程序或者 脚本 . 今天我们就以JAVA抓取网站一个页面上的全 ...

  6. 网络爬虫全解析(JAVA)--目录

    第1章技术基础1 1.1第一个程序1 1.2准备开发环境2 1.2.1JDK2 1.2.2Eclipse3 1.3类和对象4 1.4常量5 1.5命名规范6 1.6基本语法6 1.7条件判断7 1.8 ...

  7. seo和python_python网络爬虫与SEO搜索引擎优化介绍

    1. 什么是爬虫? 首先应该弄明白一件事,就是什么是爬虫,为什么要爬虫,博主百度了一下,是这样解释的: 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照 ...

  8. [Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  9. c#使用正则表达式获取TR中的多个TD_[Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例...

    首先祝大家中秋节和国庆节快乐,欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都 ...

最新文章

  1. oracle11g ora00838,管理oracle11g內存設置 解決ora-02097 ora-00838 ora-00845報錯問題
  2. 美团点评:基于Druid的Kylin存储引擎实践
  3. 第一次项目之后...
  4. java cpu过高排查_涨薪秘籍:JAVA项目排查cpu负载过高
  5. 专业音频如何把电平转换成dbu_谭俊峰|录课、买麦,你应该了解的音频常识
  6. Hibernate-04-实体编写规范
  7. 【Python成长之路】从零做网站开发 -- 下拉选择项的实现
  8. 如何恢复手机通讯录号码呢?该怎么恢复呢
  9. 网易严选搜索推荐实践之:“全能选手”召回表征算法实践
  10. 关于linux开机自启
  11. python卸载_技术 | Python 包安装和卸载的几种方式
  12. JQuery Lightbox -- 一个简单而又谦恭的用来把图片覆盖在当前页面上的脚本
  13. (绪论和参考文献)基于深度强化学习的复杂作业车间调度问题研究
  14. 什么是网络基础设施?
  15. python不定积分教学_python使用sympy不定积分入门及求解
  16. [Docker入门-2] Docker Containers 的创建和使用
  17. 利用四位共阳数码管显示小数
  18. 本地图片转为网络链接(URL/HTML/Markdown/BBCode...)
  19. Matlab符号数学Symbolic Math Toolbox™帮助文档(全)
  20. [故事]只会写自己名字的港大院士(图)

热门文章

  1. MATLAB | 趣味编程——三维彭罗斯三角形可视化
  2. 京东旗下一电商公司注销 刘强东为该公司经理
  3. 5个身份和访问管理的最佳实践
  4. Java8 Optional解决NPE问题
  5. strongSwan:ipsec.secrets - 用于IKE/IPsec身份验证的机密
  6. 【JS实战】添加元素(开头添加)
  7. 分享一个如何从电脑上彻底删除WPS的操作
  8. Virbox深思考盾So文件保护
  9. Java导出Excel表格文件名乱码问题
  10. 300内哪款蓝牙耳机比较好?国产高性价比蓝牙耳机推荐