一、scrapy-redis
redis 是高性能的 key-value 数据库。我们知道 MongoDB 将数据保存在了硬盘里,而 Redis 的神奇之处在于它将数据保存在了内存中,因此带来了更高的性能。
二、分布式原理
回顾 scrapy 框架,我们首先给定一些start_urls,spider 最先访问 start_urls 里面的 url,再根据我们的 parse 函数,对里面的元素、或者是其他的二级、三级页面进行抓取。而要实现分布式,只需要在这个starts_urls里面做文章就行了。进一步描述如下:
-
master 产生 starts_urls,url 会被封装成 request 放到 redis 中的 spider:requests,总的 scheduler 会从这里分配 request,当这里的 request 分配完后,会继续分配 start_urls 里的 url。
-
slave 从 master 的 redis 中取出待抓取的 request,下载完网页之后就把网页的内容发送回 master 的 redis,key 是 spider:items。scrapy 可以通过 settings 来让 spider 爬取结束之后不自动关闭,而是不断的去询问队列里有没有新的 url,如果有新的 url,那么继续获取 url 并进行爬取,所以这一过程将不断循环。
-
master 里的 reids 还有一个 key 是 “spider:dupefilter” 用来存储抓取过的 url 的 fingerprint(使用哈希函数将url运算后的结果),防止重复抓取,只要 redis 不清空,就可以进行断点续爬。
三、爬取中国红娘网
爬虫文件(单机操作)
# -*- coding: utf-8 -*-
import scrapy
from ..items import RedishongniangItem
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor
from scrapy_redis.spiders import RedisCrawlSpider
class HongniangSpider(RedisCrawlSpider):
name = 'hongniang'
allowed_domains = ['hongniang.com']
#注意这里和单机爬虫的写法区别
redis_key = 'hongniangspider:start_urls'
page_link = LinkExtractor(allow=r'http://www.hongniang.com/index/search?sort=0&wh=0&sex=2&starage=1&province=%E6%B2%B3%E5%8D%97&city=%E9%83%91%E5%B7%9E&page=1')
person_link = LinkExtractor(allow=r'http://www.hongniang.com/user/member/id/\d+')
rules = (
Rule(page_link,True),
Rule(person_link, callback='get_detail',follow=False)
)
def get_detail(self,response):
name = response.xpath('//div[@class="name nickname"]/text()').get()
print(name)
age = response.xpath('//div[@class="info2"]//ul[1]/li[1]/text()').get()
print(age)
item = RedishongniangItem()
item['name'] = name
item['age'] = age
yield item
- settings文件设置
- items文件修改
-
终端命令
1.开启服务
-
-
2.运行爬虫文件
-
-
3.发出指令
-
-
-
爬虫文件(多机操作)
1.作为服务端的电脑打开终端输入如下命令开启redis服务(这个终端在爬虫过程中需要一直开启,不能关闭)
-
-
2. 服务端打开第二个终端输入如下命令:
-
-
3.然后打开Redis的可视化工具RedisDesktopManager,点击左下角新建连接,然后输入name和host ,其他不用改
-
-
4.把上面单机运行时修好的代码发送到另一台机器,并开启服务,然后再开启第二个终端,输入如图命令
-
-
5.执行命令
-