关闭

网络爬虫之网页排重:语义指纹

标签: 网络爬虫网页排重
1235人阅读 评论(0) 收藏 举报
分类:

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

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

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

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

  这样可以把“北京华联”或“华联超市”替换成“华联商厦”。对指定文本,要从前往后查找同义词词库中每个要替换的词,然后实施替换。同义词替换的实现代码分为两步。首先是查找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》这本书的疑问~
更多好问题,期待你来问!

0
0
查看评论

信息指纹与消重算法

信息指纹:就是提取一个信息的特征,通常是一组词或者一组词+权重,然后根据这组词调用特别的算法,例如MD5,将之转化为一组代码,这组代码就成为标识这个信息的指纹。从理论上讲,每两个不同文本的特征信息是不同的,那么得到的代码也应该是不一样的,就象人的指纹。搜索引擎在建立索引的时候需要对重复内容的网页进行...
  • starxu85
  • starxu85
  • 2008-05-31 08:45
  • 1259

网络爬虫学习笔记———网页源码下载之get方法

请求网页的方式主体有两种,一种是get方法,一种是post方法。正如这两个单词明面上的意思,一个是单纯地从网页中获取源码,另一种需要传递正确的参数后才能返回正确的源码。如图所示,我们可以利用F12观察的方法来查看具体是哪种请求。   下面是post方法。   ...
  • acm2014
  • acm2014
  • 2016-11-17 22:36
  • 326

快速URL排重的方法(一)

我这里介绍一个极适合大量URL快速排重的方法 ,这个算法被称为Bloom filter,基本上,它也只适合这样的场合。这里的大量是指有5000万至1亿的URL,更大的数据量可能也不合适了。一开始我使用了一个最复杂的做法,是有一个单独的daemon程序负责排重,数据和排重结果通过socket...
  • oyd
  • oyd
  • 2007-07-19 18:12
  • 4470

一种海量文章排重的算法

simhash是一种能计算文档相似度的hash算法。通过simhash能将一篇文章映射成64bit,再比较两篇文章的64bit的海明距离,就能知道文章的相似程序。若两篇文章的海明距离<=3,可认为这两篇文章很相近,可认为它们是重复的文章。
  • junjie20082008
  • junjie20082008
  • 2016-11-29 11:35
  • 731

数学之美之信息指纹

读到信息指纹这一章,讲到每个网页链接都生成一个128位的随机数,这样可以方便的存储并且保证不会出现重复的链接。 之后又讲到判定两个集合是否相同,就在这个地方稍微思考了一下,不过对于指纹的原理还不是很清楚的。但是假如要我判断两个字符串是否相同,我会怎么做呢?   对于两个字符串,如果将顺序也...
  • u013006753
  • u013006753
  • 2015-07-16 22:10
  • 281

sql数据排重

*****************************************************************方法一:------------将表Contentpj排重后倒入表shopxp_product------------dim conn,mdbfile mdbfile=s...
  • flynetcn
  • flynetcn
  • 2006-12-16 21:10
  • 4325

list 对象排重

class ListDistinctDemo { static void Main(string[] args) { List personList = new List(){ new Person(3)...
  • lybwwp
  • lybwwp
  • 2015-03-27 12:00
  • 896

数据重删技术概述

1.源端去重 && 宿端去重源端去重(Source Deduplication)首先在客户端计算待传输数据的指纹并通过与服务端进行指纹比对发现和消除重复内容,然后仅向服务端发送非重复数据内容 , 从而达到同时节约网络带宽和存储资源的目标。 宿端去重( Destination Ded...
  • qq_27803491
  • qq_27803491
  • 2016-09-07 19:36
  • 633

SQL 数据排重,去掉重复数据

    最大的错误:    在对数据排重的时候,首先想到的就是Distinct,虽然这很管用,但多数场合下不适用,因为通常排重后还要做进一步处理,比如对编号排重后要按日期统计等。    无法排重的Group b...
  • along1976
  • along1976
  • 2005-04-03 09:55
  • 6822

大数据排重算法-布隆算法(BloomFilter)

前续:网页上已经有很多布隆过滤器很全的资料了,由于博主最近在做网页爬虫,遇到url防重问题,所以认真分析了布隆滤波器原理,也参考了相关博文。旨在给出不同人对其不同的理解,好给大家更全面的参考。BloomFilter算法,是一种大数据排重算法。在一个数据量很大的集合里,能准确断定一个对象不在集合里;判...
  • u014033218
  • u014033218
  • 2017-09-03 14:38
  • 244
    个人资料
    • 访问:3928241次
    • 积分:56532
    • 等级:
    • 排名:第57名
    • 原创:1462篇
    • 转载:83篇
    • 译文:1篇
    • 评论:3786条
    博客专栏
    文章存档
    最新评论