关键词:
引言:网络爬虫让我们高效地从网页获取到信息,但网页的重复率很高,网页需要按内容做文档排重,而判断文档的内容重复有很多种方法,语义指纹是其中比较高效的方法。
本文选自《网络爬虫全解析——技术、原理与实践》。
现代社会,有效信息对人来说就像氧气一样不可或缺。互联网让有效信息的收集工作变得更容易。当你在网上冲浪时,网络爬虫也在网络中穿梭,自动收集互联网上有用的信息。
自动收集和筛选信息的网络爬虫让有效信息的流动性增强,让我们更加高效地获取信息。随着越来越多的信息显现于网络,网络爬虫也越来越有用。
不同的网站间转载内容的情况很常见。即使在同一个网站,有时候不同的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》这本书的疑问~
更多好问题,期待你来问!
本文出自 “博文视点官方博客” 博客,请务必保留此出处http://bvbroadview.blog.51cto.com/3227029/1922360
网络爬虫的盗之有道
‘‘‘一爬虫网络的尺寸:1小规模,数据量小,爬取速度不敏感;利用Request库爬取网页和玩转网页2中规模:数据规模较大,爬取速度敏感;可以利用scrapy库爬取网站或者爬取系列网站3大规模,搜索引擎爬取速度关键,主要是... 查看详情
python项目实战之网络爬虫详解(代码片段)
...述二、原理三、爬虫分类1、传统爬虫2、聚焦爬虫3、通用网络爬虫(全网爬虫)四、网页抓取策略1、宽度优先搜索:2、深度优先搜索:3、最佳优先搜索:4、反向链接数策略:5、PartialPageRank策略:五... 查看详情
1,爬虫入门之爬虫基础了解
1.什么是爬虫爬虫,即网络爬虫,大家可以理解为在网络上爬行的一只蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来。想抓取什么?这个由你来控制它咯。比如... 查看详情
python之爬虫技术
概述近年来,随着网络应用的逐渐扩展和深入,如何高效的获取网上数据成为了无数公司和个人的追求,在大数据时代,谁掌握了更多的数据,谁就可以获得更高的利益,而网络爬虫是其中最为常用的一种从网上爬取数据的手段... 查看详情
学习笔记之爬虫篇
网络爬虫(又被称为网页蜘蛛,网络机器人,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫。模块:scrapy req... 查看详情
爬虫之requests模块(代码片段)
概述近年来,随着网络应用的逐渐扩展和深入,如何高效的获取网上数据成为了无数公司和个人的追求,在大数据时代,谁掌握了更多的数据,谁就可以获得更高的利益,而网络爬虫是其中最为常用的一种从网上爬取数据的手段... 查看详情
网络爬虫之动态内容爬取(代码片段)
根据联合国网站可访问性审计报告,73%的主流网站都在其重要功能中依赖JavaScript。和单页面应用的简单表单事件不通,使用JavaScript时,不再是加载后立即下载所有页面内容。这样会造成许多网页在浏览其中展示的内容不会... 查看详情
0基础学爬虫爬虫基础之网页解析库的使用(代码片段)
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学爬虫... 查看详情
python爬虫入门一之综述
...Python版本:2.7,Python3请另寻其他博文。首先爬虫是什么?网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者 查看详情
爬虫之scrapy框架(代码片段)
...等一系列的程序中。其最初是为了页面抓取(更确切来说,网络抓取)所设计的,也可以应用在获取API所返回的数据(例如AmazonAssociatesWebServices)或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。Scrapy使用... 查看详情
爬虫初探之requests
关于请求网络,requests这个库是爬虫经常用到的一个第三方库。importrequestsurl=‘http://www.baidu.com‘#这里用get方法用来请求网页,其他还有post等方法来请求网页data=requests.get(url)print(data)#<Response[200]>print(data.text)#这里的.text就等... 查看详情
python开发爬虫之动态网页抓取篇:爬取博客评论数据
以爬取《Python网络爬虫:从入门到实践》一书作者的个人博客评论为例。网址:http://www.santostang.com/2017/03/02/hello-world/1)“抓包”:找到真实的数据地址 右键点击“检查”,点击“network”,选择“js”。刷新一下页面,选中... 查看详情
爬虫系列之第1章-简介&requests模块(代码片段)
概述近年来,随着网络应用的逐渐扩展和深入,如何高效的获取网上数据成为了无数公司和个人的追求,在大数据时代,谁掌握了更多的数据,谁就可以获得更高的利益,而网络爬虫是其中最为常用的一种从网上爬取数据的手段... 查看详情
网络爬虫:使用多线程爬取网页链接
前言: 经过前面两篇文章,你想大家应该已经知道网络爬虫是怎么一回事了。这篇文章会在之前做过的事情上做一些改进,以及说明之前的做法的不足之处。思路分析:1.逻辑结构图 上图中展示的就是我们网络... 查看详情
什么是语义化的html?有何意义?为什么要做到语义化?
...事情,能够便于开发者阅读和写出更优雅的代码的同时让网络爬虫很好地解析。二、为什么要做到语义化?1、有利于SEO,有利于搜索引擎爬虫更好的理解我们的网页,从而获取更多的有效信息,提升网页的权重。2、在没有CSS的... 查看详情
第一次了解爬虫(代码片段)
基于想自己下载网络小说的念头,认识到了python.使用过后真是觉得是一门适合网络的语言,加上数不清的第三方库可以使用。适合快速开发。当然python也在数据分析,自然语义方面也有很多优势。这里主要介绍在网络方面的应... 查看详情
爬虫之urllib2库的基本使用
...rllib2库的基本使用所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。在Python中有很多库可以用来抓取网页,我们先学习urllib2。urllib2是Python2.7自带的模块(不需要下载,导入即可使用)urllib2官方文... 查看详情
爬虫技术之数据采集?
...,人们的生活与互联网的联系也越来越密切,许多工作与网络也是分不开联系,而信息收集则成为网络生活最基础也最必不可少的部分。因此,诞生了一大批被称为“网络爬虫”的工作者,他们每天的工作就是利用程序脚本来收... 查看详情