最近写了一个爬虫,想对它优化一下,就想到了可以使用scrapy + redis实现一个分布式爬虫,今天就学习学习redis。
一 Redis简介
redis是一个高性能的key-value数据库,它是将数据存储在内存当中,因此相对而言比较快速,且性能极高。
与其它的key-value数据库相同的是:
1.支持数据的持久化,重启的时候数据可以再次加载使用;
2.不仅仅支持key-value类型的数据,还支持list,set,zset,hash等数据结构;
3.支持数据备份
不同点:
1.redis有着更为复杂的数据结构并且提供对它们的原子性操作;
1.redis运行在内存中但是可以持久化到磁盘所以说数据量不能大于硬件内存;相比在磁盘上相同的复杂的数据结构,在内存中操作起来相对简单。
Redis数据类型
支持五种数据类型:string(字符串),hash(哈希),list,set,zset(有序集合)
string类型是二进制安全的,也就是string可以包含任何数据;
hash是一个键值对集合,是一个string类型的field和value的映射表,hash特别适合用于存储对象;
list是一个简单的字符串列表,按照插入顺序排序;
set是string类型的无序集合集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。使用sadd命令添加一个string元素到key,对应的set集合中,成功则返回1,如果元素已经在集合中则返回0;
zset和set不同的是每个元素都会关联一个double类型的分数,redis通过分数来为集合中的成员进行从小到大的排序。添加元素的命令是zadd命令。
Redis键(key)
redis键命令的基本语法是:COMMAND KEY_NAME
Redis HyperLogLog
用来做基数统计的算法,优点是当输入元素的数量或提及非常非常大时,计算基数所需的空间很小。
基数?对于数据集{1,3,5,7,5,7,8}的基数集是{1,3,5,7,8},基数为5。技术就是在误差可接受的范围内,快速计算基数。
所用到的命令如下:
PFADD:添加指定元素到HyperLogLog中
PFCOUNT:返回给定HyperLogLog的技术估算值
PFMERGE:将多个HyperLogLog合并为一个
二 关于分布式爬虫
redis如何实现爬虫分布式的中心:将所有爬虫获取到的url都放到一个redis queue中,并且所有的爬虫都从单个的redis queue中获取request。爬虫默认的是广度优先搜索,假定现在有两个爬虫,那么是如何实现分布式,具体的步骤如下:
首先运行爬虫A,爬虫引擎请求spider A中的start_urls中的链接并交割给调度器,进而引擎向调度器请求爬取的url并交给下载器下载,下载后的response交给spider,spider根据定义的rules得到链接,继续通过引擎交给调度器。
进而启动B,B的start_urls首先交给和A中的调度器相同的,而B的引擎请求爬取url时,调度器调度给B下载的url还是A中没下载完的url,这时A和同时下载A中未完成的链接,待完成后,同时下载B的要求链接。
在scrapy-redis中默认使用的是SpiderPriorityQueue方式,这是由sorted set实现的一种非FIFO,LIFO方式。
每次执行重新爬取时,应该将redis中存储的数据清空,否则会影响爬虫现象。
request和url的区别:request是由spider完成,spider会返回request给scrapy引擎进而交割调度器.url也是在spider中定义或由spider获取
在scrapy中crawler是包含spider的,scrapy的架构就是spider,spider的作用是提供start_url,根据下载到的response分析获取想要的内容继续提取url。
如果使用Python+redis+其它数据库实现分布式爬虫存储数据,其中的redis只用作url的存储,不关乎爬虫得到的具体数据,设置slave上的scrapy-redis获取url的地址为master地址,尽管有多个slave,然而获取url只能从服务器上的redis数据库。并且,由于scrapy-redis自身的队列机制,slave获取的链接不会相互冲突。各个slave在完成抓取任务之后,将结果汇总到服务器上(这时的存储不再是redis,可以是mongodb或者mysql等)
对于已有的scrapy程序,扩展分布式程序步骤如下:
1.找一台高性能服务器,用于redis队列的维护以及数据的存储;
2.扩展scrapy程序,让其通过服务器的redis来获取start_urls,并改写pipeline里数据存储部分,把存储地址改为服务器地址。
3。在服务器上写一些生成url的脚本,并定期执行。
防抓取屏蔽的方法
1.设置download_delay,但会降低爬虫效率;
2.随机生成user_agent,或者重写middleware,让程序每次运行都可以随机获取user_agent;
3.设置代理ip池;
4.设置好header里的domian和host
关于使用随机user-agent的方法
在settings.py中添加如下代码:
DOWNLOADER_MIDDLEWARES = {
‘scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware‘ : None,
‘Crawler.comm.rotate_useragent.RotateUserAgentMiddleware‘ :400
}
相应的在对应的爬虫代码中添加一个user-agent的列表如下:
user_agent_list = [\
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"\
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",\
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",\
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",\
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",\
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",\
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",\
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",\
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",\
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",\
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",\
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",\
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",\
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",\
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",\
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",\
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",\
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]