当前位置:   article > 正文

python爬虫之Scrapy介绍八——Scrapy-分布式(以爬取京东读书为示例)_京东读书校园版 python

京东读书校园版 python

1 Scrapy-分布式介绍

1.1 Scrapy-redis工作原理

首先回顾一下Scrapy的工作流程,然后进一步介绍Srapy-分布式的工作流程和原理。
(1)Scrapy的工作流程
详见:python爬虫之Scrapy入门介绍——安装、工作流程、模块介绍
在这里插入图片描述
首先,调度器(Scheduler)存放着目标urls或者是存放引擎发过来的request请求。
然后,引擎(Scrapy engine)协调调度器(Scheduler)把请求发给下载器(Downloader),让下载器下载请求,并返回给引擎。
接着,引擎(Scrapy engine)把获得的响应发给爬虫(Spider),爬虫处理引擎发来的response,提取数据,提取url,并交给引擎‘
最后,引擎(Scrapy engine)把响应内容发给管道(Item Pipline),管道处理引擎传过来的数据,比如存储。

(2)而Scrapy-分布式是为了弥补Scrapy的一些不足而发展起来。主要是起到去重url和更好实现多线程爬取。

那Scrapy-分布式是如何实现去重?它借助了redis快速读取功能来实现去重。具体而言:1)利用redis数据库分别存储待爬取的request对象;2)存储爬取过了的request对象,即指纹集合。3)在1)和2)存储的内容进行对比,进而实现去重。
除此之外,redis也可以存储爬取了的数据
在这里插入图片描述
在这里插入图片描述

1.2 Scrapy-redis 安装和基本使用

1.2.1 安装

(1)python 安装

pip install scrapy_redis
  • 1

(2)基本使用数据来源

clone github scrapy_redis源码文件
git clone https://github.com/rolando/scrapy-redis.git
  • 1
  • 2

(3)打开example示例项目
在这里插入图片描述

1.2.2 基本使用

(1)了解example项目里的setting文件

SPIDER_MODULES = ['example.spiders']
NEWSPIDER_MODULE = 'example.spiders'

USER_AGENT = 'scrapy-redis (+https://github.com/rolando/scrapy-redis)'

# 指定去重方法给request对象去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 指定Scheduler队列
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 队列中的内容是否持久保存,为false的时候在关闭Redis的时候,清空Redis
SCHEDULER_PERSIST = True
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"

# 打开scrapy里面的pipeline和scrapy_redis.pipelines
ITEM_PIPELINES = {
    'example.pipelines.ExamplePipeline': 300,
    # scrapy_redis实现的items保存到redis的pipline
    'scrapy_redis.pipelines.RedisPipeline': 400,
}

LOG_LEVEL = 'DEBUG'

# Introduce an artifical delay to make use of parallelism. to speed up the
# crawl.
DOWNLOAD_DELAY = 1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

(2)运行example-project里面的dmoz.py
1)先要启动radis服务端
在这里插入图片描述

redis-server
  • 1

2)创建start文件

from scrapy import cmdline

cmdline.execute(['scrapy','crawl','dmoz'])

  • 1
  • 2
  • 3
  • 4

3)启动redis服务端,了解数据库存储数据情况

redis-cli.exe
  • 1

4)运行结果
在这里插入图片描述
在这里插入图片描述
5)结果解释

dmoz:requests   存放的是待爬取的requests对象 
dmoz:item       爬取到的信息
dmoz:dupefilter 爬取的requests的指纹
  • 1
  • 2
  • 3

6)总结
在这里插入图片描述
在这里插入图片描述

2 Scrapy转为Scrapy-分布式

步骤:
普通爬虫改成分布式爬虫
1.改造爬虫
1.1 导入类
1.2 继承类
1.3 注释start_url
2.改写配置文件

2.1 scrapy爬取京东读书

按常规创建jdspider项目,下面仅展示爬虫文件逻辑

import scrapy
from copy import deepcopy

''''
需求:抓取京东图书的信息
目标:抓取京东图书包含图书的名字、
封面图片地址、图书url地址、
作者、出版社、出版时间、价格、图书所属大分类、图书所属小的分类、分类的url地址
'''

class JdSpider(scrapy.Spider):
    name = 'jd'
    allowed_domains = ['jd.com']
    start_urls = ['https://book.jd.com/booksort.html']

    def parse(self, response):
        # 获取图书大类(小说、文学、青春文学等),存储在 //div[@class="mc"]/dl/dt/a
        dt_list = response.xpath('//div[@class="mc"]/dl/dt')
        for dt in dt_list:
            item = {}
            item['b_cate'] = dt.xpath('./a/text()').extract_first()
            # 获取图书小类(中国近当代小说中国近现代小说中国古典小说),存储在//div[@class="mc"]/dl/dd/em
            em_list = dt.xpath("./following-sibling::dd[1]/em")
            for em in em_list:
                item['s_cate'] = em.xpath("./a/text()").extract_first()
                item['s_href'] = em.xpath("./a/@href").extract_first()
                if item['s_href'] is not None:
                    item['s_href'] = "https:" + item['s_href']
                # 目前已获取到图书的大类和小类,现在要进入列表页获取图书的价格、出版社等信息
                    yield scrapy.Request(
                        url=item['s_href'],
                        callback=self.parse_book_list,
                        meta={'item': deepcopy(item)}
                    )

    def parse_book_list(self,response):
        item = response.meta.get('item')
        li_list = response.xpath("//div[@id='J_goodsList']/ul/li")
        for li in li_list:
            # 在列表页获取书名、书的图片、价格和出版社
            item['book_name'] = li.xpath('.//div[@class="p-img"]/a/em/text()').extract_first()
            item['book_img'] = li.xpath('.//div[@class="p-img"]/a/img/@src').extract_first()
            item['book_price'] = li.xpath('.//div[@class="p-price"]/strong/i/text()').extract_first()
            item["book_press"] = li.xpath(".//span[@class='p-bi-store']/a/text()").extract_first()
            # print(item)
            yield item
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

2.2 改为Scrapy-分布式

1.改造爬虫
1.1 导入类
1.2 继承类
1.3 注释start_url

import scrapy
from copy import deepcopy
from scrapy_redis.spiders import RedisSpider # 导入类

''''
需求:抓取京东图书的信息
目标:抓取京东图书包含图书的名字、
封面图片地址、图书url地址、
作者、出版社、出版时间、价格、图书所属大分类、图书所属小的分类、分类的url地址
'''

class JdSpider(RedisSpider):  # 继承类
    name = 'jd'
    allowed_domains = ['jd.com']
    # start_urls = ['https://book.jd.com/booksort.html']
    redis_key = "jd
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.改写seting配置文件

# 指定那个去重的方法给requests对象去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 指定Scheduler队列
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# Redis中的数据是否保存持久 如果是false 关闭Redis的时候 数据会被清空
SCHEDULER_PERSIST = True
ITEM_PIPELINES = {
   'JDSpideer.pipelines.JdspideerPipeline': 300,
    'scrapy_redis.pipelines.RedisPipeline': 400,
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.启动radis服务端和客户端
在客户端中输入,以为设置初始url

LPUSH jd https://book.jd.com/booksort.html
  • 1

结果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/208658
推荐阅读
相关标签
  

闽ICP备14008679号