网络爬虫-url索引

http://www.cnblogs.com/yuandong/archive/2008/08/28/Web_Spider_Url_Index.html

url索引的作用是判断一个url是否被抓取过,采用的算法主要是MD5数字签名。

假设一共要抓取的url不超过1亿条,用一个二进制的位表示一个url是否被抓取过,则至少需要1亿个位,我们管每一个位叫一个“槽”。考虑到MD5的算法是可能出现冲突(即不同的url算出来的MD5可能相同,这种概率很小),槽越少,冲突越明显,所以槽越多越好。但另一方面,还要考虑到占用内存的大小,因为在抓取的过程中,为了保证效率,所有的槽都需要载入内存。目前我使用的是2的28次方,即32M,相当于268435456(2.6亿)个槽。

当要判断一个url是否已经抓取过的时候,只要判断该url经过MD5签名后的值所对应的槽是否标记为1即可。例如给出的url是:http://www.ouc.edu.cn/,经过128位的MD5签名后,得出的1073542761,则需要判断的就是第1073542761个槽是0还是1。同样的道理,当完成一个url的抓取后,要将对应的槽标记为1。

存储槽的32M空间在内存是不连续的,因为操作系统很难划分出32M的连续内存空间,所以将其分为4096个段Segment,每段2048个32位整数,32*2048*4096=268435456。相当于一个整型的二维数组。

我们使用32位的MD5作为签名,表示为一个整数。这个整数分为三部分,分别是段地址、段偏移和值地址。第5-16位表示段地址,17-27位表示段偏移,28-32位(最后5位,取值范围为2的5次方,即0-31)表示在整形值中的位置、即值地址。

当给定一个url的MD5值时,通过以下函数计算出其段地址:

   1:  unsigned short get_segment_index(unsigned int md5) {
   2:      
   3:      //5-16位表示段地址
   4:      
   5:      unsigned short result;
   6:      bzero(&result, sizeof(unsigned short));
   7:      memcpy(&result, ((char*)&md5) + 2, sizeof(unsigned short));
   8:   
   9:      return result & 0x0FFF;
  10:  }

通过以下函数计算出其段偏移:

   1:  unsigned short get_segment_offset(unsigned int md5) {
   2:      
   3:      //17-27位表示段偏移
   4:      
   5:      unsigned short result;
   6:      bzero(&result, sizeof(unsigned short));
   7:      memcpy(&result, ((char*)&md5), sizeof(unsigned short));
   8:   
   9:      return result >> 5;
  10:  }

通过以下函数计算其值偏移:

   1:  unsigned int get_value(unsigned int md5) {
   2:      
   3:      //28-32(最后5位)为表示值
   4:      
   5:      unsigned int result = 1;
   6:      return result << (md5 & 0x0000001F);
   7:  }

再得到段地址、段偏移和值偏移后,就通过一下函数判定该Url是否已被抓取:

   1:  bool is_url_crawled(char* url) {
   2:   
   3:      //将给出的url进行md5运算,取得对应的Value,于储存的Value按位与
   4:      
   5:      unsigned int url_md5 = md5(url);
   6:      unsigned short segment_index = get_segment_index(url_md5);
   7:      unsigned short segment_offset = get_segment_offset(url_md5);
   8:      unsigned int value = get_value(url_md5);
   9:      
  10:      unsigned int result = (unsigned int)
                                 (url_index[segment_index][segment_offset] & value);
  11:   
  12:      return result > 0 ? TRUE : FALSE;
  13:  }

如果未被抓取,在完成抓取后,通过以下函数标记为已抓取:

   1:  int mark_url_as_crawled(char* url) {
   2:   
   3:      //取得段地址、段偏移和url对应的值
   4:      unsigned int url_md5 = md5(url);
   5:      unsigned short segment_index = get_segment_index(url_md5);
   6:      unsigned short segment_offset = get_segment_offset(url_md5);
   7:      unsigned int value = get_value(url_md5);
   8:   
   9:      //通过按位或标记url对应的位为已抓取
  10:      url_index[segment_index][segment_offset] |= value;
  11:      
  12:      //同步写入索引文件
  13:      value = url_index[segment_index][segment_offset];
  14:      long offset = (((long)segment_index) * SEGMENT_LENGTH + segment_offset) 
                            * sizeof(unsigned int);
  15:      if(fseek(index_file, offset, SEEK_SET) != 0)
  16:          return -1;
  17:      
  18:      if(fwrite(&value, sizeof(unsigned int), 1, index_file) != 1)
  19:          return -1;    
  20:      
  21:      fflush(index_file);
  22:      return 0;
  23:  }

网络爬虫-url索引的更多相关文章

  1. 网络爬虫url跳转代码

    from bs4 import BeautifulSoup from urllib.request import urlopen import re import random base_url = ...

  2. python网络爬虫(一):网络爬虫科普与URL含义

    1. 科普     通用搜索引擎处理的对象是互联网的网页,目前网页的数量数以亿计,所以搜索引擎面临的第一个问题是如何设计出高效的下载系统,已将海量的网页下载到本地,在本地形成互联网网页的镜像.网络爬虫 ...

  3. Python 网络爬虫 008 (编程) 通过ID索引号遍历目标网页里链接的所有网页

    通过 ID索引号 遍历目标网页里链接的所有网页 使用的系统:Windows 10 64位 Python 语言版本:Python 2.7.10 V 使用的编程 Python 的集成开发环境:PyChar ...

  4. 【Python网络爬虫一】爬虫原理和URL基本构成

    1.爬虫定义 网络爬虫,即Web Spider,是一个很形象的名字.把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛.网络蜘蛛是通过网页的链接地址来寻找网页的.从网站某一个页面(通常 ...

  5. [Python]网络爬虫(一):抓取网页的含义和URL基本构成

    一.网络爬虫的定义 网络爬虫,即Web Spider,是一个很形象的名字. 把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛.网络蜘蛛是通过网页的链接地址来寻找网页的. 从网站某一个 ...

  6. python 网络爬虫(二) BFS不断抓URL并放到文件中

    上一篇的python 网络爬虫(一) 简单demo 还不能叫爬虫,只能说基础吧,因为它没有自动化抓链接的功能. 本篇追加如下功能: [1]广度优先搜索不断抓URL,直到队列为空 [2]把所有的URL写 ...

  7. [原创]手把手教你写网络爬虫(7):URL去重

    手把手教你写网络爬虫(7) 作者:拓海 摘要:从零开始写爬虫,初学者的速成指南! 封面: 本期我们来聊聊URL去重那些事儿.以前我们曾使用Python的字典来保存抓取过的URL,目的是将重复抓取的UR ...

  8. Python 网络爬虫 009 (编程) 通过正则表达式来获取一个网页中的所有的URL链接,并下载这些URL链接的源代码

    通过 正则表达式 来获取一个网页中的所有的 URL链接,并下载这些 URL链接 的源代码 使用的系统:Windows 10 64位 Python 语言版本:Python 2.7.10 V 使用的编程 ...

  9. 开源的49款Java 网络爬虫软件

    参考地址 搜索引擎 Nutch Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting, ...

随机推荐

  1. MyEclipse自动提示

    MyEclipse自动提示 Eclipse中默认是输入"."后出现自动提示,用于类成员的自动提示,可是有时候我们希望它能在我们输入类的. 首字母后就出现自动提示,可以节省大量的输入 ...

  2. Cocos2d-x如何控制动作速度

    基本动作和组合动作实现了针对精灵的各种运动和动画效果的改变.但这样的改变速度匀速的.线性的.通过ActionEase及其的派生类和Speed 类我们可以使精灵以非匀速或非线性速度运动,这样看起了效果更 ...

  3. jQuery-ui treegird 使用

    在实际应用中可能会碰到不同的需求,比如会根据每行不同的参数或属性设置来设置同列不同的editor类型,这时原有的例子就显的有点太过简单,不能实现我们的需求,现在应用我在项目中的操作为例,显示下实现同列 ...

  4. [GeekBand] 面向对象的设计模式(C++)(1)

    一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心. 这样,你就能一次又一次 地使用该方案而不必做重复劳动. 0. 从面向对象谈起 底层思维与抽象思维: 底层思维要求程序员&q ...

  5. 算法 replace,replace_copy,back_inserter

    replace (list.begin(), list.end(), , ); // replace any elements with value of 0 by 42 replace算法对输入序列 ...

  6. 链接中 href='#' 和 href='###' 的区别以及优缺点

    首先,<a> 标签 + onclick='{jscode}' 是很常用的一种 js 运用方式,而不使用 href='javascript:{jscode}' 是为了兼容多种浏览器对 < ...

  7. linux之cat命令

    1. cat 接普通文件名,会把文件内容打印到屏幕:2. cat > file,这个可以向文件“file”写入内容,最后按 Ctrl + D 结束输入,会将你输入的数据保存到文件. cat主要有 ...

  8. aix 安装redis

    下载最新rpm安装包 http://www.perzl.org/aix/index.php?n=Main.Redis # uname -aAIX rhjf 1 6 00C5CC964C00# pwd/ ...

  9. Python串行运算、并行运算、多线程、多进程对比实验

    转自:http://www.redicecn.com/html/Python/20111223/355.html Python发挥不了多核处理器的性能(据说是受限于GIL,被锁住只能用一个CPU核心, ...

  10. 关于B/S系统在移动端应用的一些注意的地方(不断更新)

    1.不要直接把PC端的页面直接搬到移动端来用.这里举个例子:有个活动页面,在PC端和手机端的Safari里展现都好,但是当用手机APP(如手机淘宝)扫码打开后,却没法顺畅的异步获取到jsonp的信息. ...