@概述
- 对于比较庞大的爬虫项目,可以考虑分工在多台服务器上进行分布式爬取
- master端安装redis内存数据库,实现高速写入和转存(必须要转存,否则断电或程序崩溃,则数据将不复存在)
- slave端爬虫程序运行起来后,会监听master端发送的指令并开始爬取,数据在scrapy_redis框架作用下,会源源不断地存储到master端redis数据库
- master端redis的安装以及slave端scrapy_redis的安装请参考《分布式爬虫环境配置》
- 除了环境配置以外,代码与scrapy基本是一致的
- 代码很好理解,难点主要在于环境的配置和调试
@环境的安装
- master端redis的安装请参考:blog.csdn.net/xiangwanpen…
- slave端安装scrapy_redis:sudo pip install scrapy_redis
@项目代码
-
项目代码的框架来自于scrapy_redis官方提供的示例代码:github.com/rmax/scrapy…
-
item类
# 数据模型类
class MscrapyredisItem(scrapy.Item):
crawled = scrapy.Field()
spider = scrapy.Field()
url = scrapy.Field()
# 定义一下打印样式
def __str__(self) -> str:
return "MscrapyredisItem{crawled:%s,spider:%s,url:%s}"%(self.get("crawled"),self.get("spider"),self["url"])
- 爬虫类
# 必须继承于RedisCrawlSpider,RedisSpider二者之一
# 其功能是在scrapy框架的Spider和CrawlSpider基础上增加了分布式功能
class BizhiSpider(RedisCrawlSpider):
# 爬虫名称
name = 'bizhi'
# 在redis-cli中:lpush bizhi_key http://desk.zol.com.cn/
# start_urls = ['http://desk.zol.com.cn/']
redis_key = 'bizhi_key'
# 允许爬取的子链接
bizhi_link = LinkExtractor(allow=r'/bizhi/.*html$')
# 深度爬取合规子链接,交由download_img方法处理
rules = (
Rule(bizhi_link, callback='download_img', follow=True),
)
# 处理页面
def download_img(self, response):
item = MscrapyredisItem()
# 提取图片下载链接
img_url = response.xpath("//img[@id='bigImg']/@src").extract()[0]
item['url'] = img_url
print(img_url)
yield item
- 设置类核心代码
# 指定使用scrapy-redis的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 指定使用scrapy-redis的去重
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
# 在redis中保持scrapy-redis用到的各个队列,从而允许暂停和暂停后恢复,也就是不清理redis queues
SCHEDULER_PERSIST = True
# 指定redis数据库的连接参数
# REDIS_PASS是我自己加上的redis连接密码(默认不做)
REDIS_HOST = '192.168.187.133'
REDIS_PORT = 6379
#REDIS_PASS = 'redisP@ssw0rd'
# LOG等级
LOG_LEVEL = 'DEBUG'
# 覆盖默认请求头,可以自己编写Downloader Middlewares设置代理和UserAgent
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8',
'Connection': 'keep-alive',
'Accept-Encoding': 'gzip, deflate, sdch'
}
# Obey robots.txt rules
ROBOTSTXT_OBEY = True
# Disable cookies (enabled by default)
COOKIES_ENABLED = False
# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
# 'mScrapyRedis.middlewares.MscrapyredisDownloaderMiddleware': 543,
'mScrapyRedis.middlewares.HeadersProxyMiddleware': 543,
}
# 通过配置RedisPipeline将item写入key为 spider.name : items 的redis的list中,供后面的分布式处理item
# 这个已经由 scrapy-redis 实现,不需要我们写代码
ITEM_PIPELINES = {
'mScrapyRedis.pipelines.MscrapyredisPipeline': 300,
'scrapy_redis.pipelines.RedisPipeline': 400
}
- 下载中间件
# 为请求添加随机请求头
class HeadersProxyMiddleware(object):
# 对请求进行预处理
def process_request(self, request, spider):
# print("\n" * 5, "ProxyMiddleware process_request")
# 随机选择USER_AGENTS
# 设置 request 对象的头部信息
user_agent = random.choice(USER_AGENTS)
# request.headers.setdefault("User-Agent", user_agent)
request.headers["User-Agent"] = user_agent
- 数据处理类
class MscrapyredisPipeline(object):
def process_item(self, item, spider):
#utcnow() 是获取UTC时间
item["crawled"] = datetime.utcnow()
# 爬虫名
item["spider"] = spider.name
print("\n"*5,item,"returned!!!")
return item
@运行程序:
- master端redis服务器跑起:redis-server /etc/redis/redis.conf
- slave端爬虫程序跑起待命:scrapy crawl bizhi
- master端打开redis客户端:redis-cli
- master端通过redis-cli发送开始启动命令:push bizhi_key desk.zol.com.cn/