爬虫去重策略
1.将访问过的url保存到数据库中(简单,效率低,数据库虽然有缓存,但每个url都要从数据库查询)
2.将访问过的url保存到set(内存)中。只需要o(1)的代价就可以查询url(内存占用越来越大)
1000000002byte50个字符 /1024/1024/1024 = 9G(100byte一个)
3.url经过md5等方法哈希后保存到set(内存)中(MD5可以把字符缩减到固定的长度)
一般128bit 等于16byte一个(将任意长度的url压缩到同样长度的MD5字符串中,而且不会重复,节省了内存)(scrapy一般才去类似方法)
4.用bitmap方法,将访问过的url通过hash函数映射到某一位
(申请一个8bit,一个位代表一个url,压缩内存,但是冲突非常高,多个url映射到一个位,继续向下寻址)100000000/8(byte)/1024(KB)/1024(MB)
5.bloomfilter方法对bitmap进行改进,多重hash函数降低冲突
(通过多个hash函数减少发生冲突的可能性)
字符串编码
1.计算机只能处理数字,文本转换成数字(0和1)才能处理。计算机中8bit作为一个字节,所以一个字节最大能表示的数字为255
2.一个字节就能表示所有的字符,所以ASCII码(1字节)编码就成为了美国人的标准编码。
3.但是ASCII处理中文明显是不够的,中文不止255个汉字,所以中国制定了GB2312编码,用两个字节表示一个汉字,GB2312还把ASCII包含进去,同理各个国家都发展除了一套字节的编码,出现多种语言混合就一定会出现乱码
4.unicode出现了(2个字节),将所有语言统一到一套编码,unicode足够大,足够存储所有字符
(解决了ASCII本身的编码问题,也解决了超出了ASCII码的字符的各国语言的统一)
5.对比ASCII和unicode
字母A 用ASCII码表示为十进制为65 二进制0100 0001
汉字中ASCII没有 用unicode编码为20013 二进制位01001110 00101101
A用unicode编码只需要前面不0 二进制为00000000 0100 000(除了变长了 数值没变)
6.乱码问题解决了,如果全是英文,unicode编码比ASCII需要多一倍的空间,如果传输需要多一倍的传输
7.utf-8 把一个unicode转化,把英文变成1个字节,汉字三个字节,特别生僻的变成4-6字节。纯英文则会较少内存。(出于空间考虑)
unicode utf-8
0000 0000-0000 007F | 0xxxxxxx #UTF-8规定,若1字符=1字节,首位须为‘0’
0000 0080-0000 07FF | 110xxxxx 10xxxxxx #UTF-8规定,若1字符=2字节,高位字节前3位为‘110’,低位前2位为‘10’
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx #UTF-8规定,若1字符=3字节,高位字节前3位为‘110’,后面低位前2位一律为‘10’
8.utf-8储存,从文件中读数据,再把utf-8转化成unicode utf-8读内存不确定是一个还是两个字节,不方便读取,所以采用unicode(读取用unicode存储用utf-8)
->保存:转化为utf-8(文件保存,网络传输)
unicode(内存) utf-8(文件:data.txt)
<-读取:转换为unicode编码(指明原始编码。自动转换成unicode)
要使用encode要保证前面是unicode
windows使用gb2312:s.decode(“gb2312”).encode(“utf-8”)让其他类型字符串变成unicode字符
linux使用utf-8:s.decode(“utf-8”).encode(“utf-8”)
两步转化
python3 中不用考虑 万物内置unicode
s.encode(“utf-8”)即可