scrapy框架+scrapy_redis组件的分布式爬虫:爬取某小说网站的所有小说!

本人上一篇博客写到 使用scrapy框架 + redis数据库增量式爬虫 :爬取某小说网站里面的所有小说!在查看小说网站的全部小说可以知道,该小说网站起码有100+本小说,每本小说起码有1000+的章节,要是使用单台电脑抓取的话是比较慢的!

这里写下在scrapy框架里面:使用scrapy_redis组件,给原生的scrapy框架,提供可以共享的管道和调度器,让分布式电脑机群执行同一组程序,对同一组资源进行联合且分布的数据爬取,实现scrapy框架+scrapy_redis组件的分布式爬虫。

1、安装scrapy_redis组件:pip install scrapy_redis

这里使用: scrapy startproject ProName > cd ProName > scrapy genspider spiderName www.xxx.com 创建scrapy工程和爬虫文件

创建好scrapy工程后,在配置文件settings.py里面设置USER_AGENT和ROBOTSTXT_OBEY,不要设置LOG_LEVEL = 'ERROR'(分布式爬虫需要看全部的日志):

USER_AGENT = '自己设置User_Agent'
ROBOTSTXT_OBEY = False #不遵从robots协议

** spiderName.py 爬虫文件的代码: **


import scrapy
from xsbookfbsPro.items import XsbookfbsproItem
from scrapy_redis.spiders import RedisCrawlSpider #导包
#from scrapy_redis.spiders import RedisSpider要是上面的用不了,用这个试试(用这个记得下面的class(用这个RedisSpider))


# class XsbookSpider(scrapy.Spider):#之前的类不要
class XsbookSpider(RedisCrawlSpider):#改成这个

    name = 'xsbook'
    # allowed_domains = ['www.xxx.com']
    # start_urls = ['https://www.xsbooktxt.com/xiaoshuodaquan/'] == redis_key
    redis_key = 'sunxsbook' #可以被共享的调度器队列的名称(可以自己定义名称)
    #最后是需要在redis数据库里面手动添加一个起始url到redis_key表示的队列里面,数据解析的url要补充完整
    def parse(self, response):

        href_list = response.xpath('//div[@class="novellist"]/ul/li')
        for href in href_list:
            xs_url = href.xpath('./a/@href').extract_first()

            item = XsbookfbsproItem()
            item['xs_url'] = xs_url
            yield scrapy.Request(url=xs_url, callback=self.parse_detail, meta={'item': item})


    def parse_detail(self, response):

        item = response.meta['item']
        xs_name = response.xpath('//*[@id="info"]/h1/text()').extract_first()
        href_list = response.xpath('//*[@id="list"]/dl/dd')[6:]
        item['xs_name'] = xs_name
        for href in href_list:
            href_url = item['xs_url'] + href.xpath('./a/@href').extract_first()
            yield scrapy.Request(url=href_url, callback=self.requests_data, meta={'item': item})

    def requests_data(self, response):
        item = response.meta['item']
        href_title = response.xpath('//div[@class="bookname"]/h1/text()').extract_first()

        #trans = href_title.maketrans('/:*?"<?|', '         ')
        #href_title = href_title.translate(trans)
        #href_title = href_title.replace(' ', '')  # 处理windows系统特殊符号导致无法保存数据文件(保存数据命名出错的问题)

        content = '
'.join(response.xpath('//div[@id="content"]/text()').extract())
        content = content.replace('请记住本书首发域名:xsbooktxt.com。顶点小说手机版阅读网址:m.xsbooktxt.com', '')

        content = '

'.join(content.split())  # 处理下载小说章节文字排版问题
        item['href_title'] = href_title  # 在小说章节内容里面找小说章节标题,在小说章节url里面找的话 和小说的章节内容对不上
        item['content'] = content

        yield item


ok,这样spiderName.py 爬虫文件就写好了,接下来对 settings.py 项目的配置文件设置:

#在settings.py 项目的配置文件加入下面的

# 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
SCHEDULER_PERSIST = True

ITEM_PIPELINES = {
   'scrapy_redis.pipelines.RedisPipeline': 400
}#使用scrapy_redis组件的管道,该管道只可以将item写入redis

REDIS_HOST = 'redis服务器ip地址'
REDIS_PORT = 6379

#有redis密码,打开下面的
#REDIS_ENCODING = 'utf-8'
#REDIS_PARAMS = {'pasword':'123456'}

ok,这样 settings.py 项目的配置文件就设置好了,接下来配置redis的配置文件(redis.window.conf):

1、解除默认绑定:把56行的 bind 127.0.0.1 注释掉,变成(#bind 127.0.0.1)

2、关闭 保护模式:把75行的 protected-mode yes 改成 protected-mode no

启动redis服务 : redis-server.exe redis.windows.conf
启动redis客户端:redis-cli

执行scrapy工程:scrapy crawl spiderName 执行后工程程序就会监听本地的redis服务

向调度器的队列中扔入一个起始的url: 在 redis-cli:lpush > redis_key自己定义的 > start_urls

爬取的数据保存在redis proName:items(requests)命名的数据结构中

原文地址:https://www.cnblogs.com/YYQ-4414/p/14453528.html