您的位置:首页 > 编程语言 > Python开发

python实现bitmap原理

2008-10-03 11:33 501 查看
简单说明一下,这篇文章要说的bitmap不是大家google上检索出来的做图片的东东,而是对于爬虫而言,需要实现的一种不抓取重复页面的技术,大致说一下(具体可以去看相关的搜索引擎的书籍),一个url使用md5生成一个4个字节的md5码,然后存放入bitmap中,当然是要保证只存放一个,判断后面的找到的url是否已经存放在这个bitmap中了。

补充一下,http://www.imperialviolet.org/pybloom.html 里面说的bloom,pybloom(也是不抓取重复页面的技术),完全是一个垃圾,不信的话可以用一个整形1811395773试试,说是已经放在bloom中了,还有好多这种情况,这个比较让人受不了。

# -*- coding: utf-8 -*-
import array
'''''
author: malaka
mail:wengxiaojun1979@gmail.com
city:ShangHai
目的是为了记录url地址,保证不重复抓取url地址;技术实现的概念主要是参考了梁斌的<<走进搜索引擎>>,使用python实现了bitmap
'''
class intBitmap:
'''''
说明:保存int大小(4 * 1byte = 4* 8 单位bit)的数据到bitmap中
len :是指在每个array对象中要有多少个元素(最好是使用默认的值)

'''
def __init__(self,len=8):
self.len = len
self.map = array.array ('L', '/x00' * self.len * 4)

def __getitem__(self,id):
if id > self.len or id < 0 :
print 'error! id must >0 and <%i'%self.len
else : return self.map[id]

def insert(self,integerI):
index_Hash = integerI / 32 % self.len
index_int = integerI % 32
self.map[index_Hash] = (self.map[index_Hash] | (1<<index_int) )

def __contains__ (self, integerI,id=0):
index_Hash = integerI / 32 % self.len
index_int = integerI % 32
if(self.map[index_Hash] & (1<<index_int)):
return 1
else :
return 0

class MD5BitMap():
'''''
说明:保存一个md5码到bitmap中 md5码大小(4 * 4byte = 4* 4 * 8 单位bit)的数据到bitmap中,也就是说128个bit
size :是指需要生成多少个array对象(最好是使用默认的值)
len :是指在每个array对象中要有多少个元素(最好是使用默认的值)

'''
def __init__(self, size=4,len=8):
self.size = size
self.len = len
self.collection = []
self.makeCollection()

def makeCollection(self):
for i in range(0,self.size):
self.collection.append(array.array ('L', '/x00' * self.len * 4))

def __getitem__(self,id):
if id > self.size or id < 0:
print 'error! id must >0 and <%i'%self.size
else : return self.collection[id]

def getMd5(self,strURL):
import md5
m1 = md5.new()
m1.update(strURL)
dest1 = m1.hexdigest()
print (int(dest1[0:8],16),int(dest1[8:16],16),int(dest1[16:24],16),int(dest1[24:32],16))
return (int(dest1[0:8],16),int(dest1[8:16],16),int(dest1[16:24],16),int(dest1[24:32],16))

def insert(self,url):
splitUrls = self.getMd5(url)
for i in range(0,4):
index_Hash = splitUrls[i] / 32 % 8
index_int = splitUrls[i] % 32
self.collection[i][index_Hash] = (self.collection[i][index_Hash] | (1<<index_int) )

def __contains__ (self, url):
splitUrls = self.getMd5(url)
for i in range(0,4):
index_Hash = splitUrls[i] / 32 % 8
index_int = splitUrls[i] % 32
if not (self.collection[i][index_Hash] & (1<<index_int)):
return 0
return 1

t = intBitmap()
t.insert(1234)
assert 1234 in t

urlf = 'http://www.gbtai.com/radio369.htm'
test = MD5BitMap()
test.insert(urlf)
assert urlf in test
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: