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

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

(2)基本使用数据来源

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

(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

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

redis-server

2)创建start文件

from scrapy import cmdline

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

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

redis-cli.exe

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

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

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

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

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,
}

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

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

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是关于如何基于PythonScrapy、Redis和Rule组件实现分布式爬虫爬取京东华为笔记本的。首先,您需要安装Scrapy和Redis,并在Scrapy的配置文件中添加Redis相关的配置: ```python # 在settings.py中添加以下配置 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" SCHEDULER = "scrapy_redis.scheduler.Scheduler" SCHEDULER_PERSIST = True REDIS_URL = 'redis://localhost:6379' ``` 然后,您需要编写Spider和Item Pipeline,其中Spider负责解析并抓取网页,Item Pipeline负责处理抓取到的数据。下面是一个示例的Spider代码: ```python from scrapy_redis.spiders import RedisSpider from scrapy.selector import Selector from ..items import ProductItem class JdSpider(RedisSpider): name = 'jd' redis_key = 'jd:start_urls' def parse(self, response): sel = Selector(response) products = sel.xpath('//div[@class="gl-i-wrap"]') for product in products: item = ProductItem() item['name'] = product.xpath('div[@class="p-name"]/a/em/text()').extract_first() item['price'] = product.xpath('div[@class="p-price"]/strong/i/text()').extract_first() item['url'] = product.xpath('div[@class="p-name"]/a/@href').extract_first() yield item ``` 在Item Pipeline中,您可以对抓取到的数据进行清洗和存储,下面是一个示例的Item Pipeline代码: ```python import pymongo class JdPipeline(object): def __init__(self, mongo_uri, mongo_db): self.mongo_uri = mongo_uri self.mongo_db = mongo_db @classmethod def from_crawler(cls, crawler): return cls( mongo_uri=crawler.settings.get('MONGO_URI'), mongo_db=crawler.settings.get('MONGO_DATABASE', 'items') ) def open_spider(self, spider): self.client = pymongo.MongoClient(self.mongo_uri) self.db = self.client[self.mongo_db] def close_spider(self, spider): self.client.close() def process_item(self, item, spider): self.db['products'].insert(dict(item)) return item ``` 最后,您需要创建一个Redis队列,并向队列中添加起始URL,如下所示: ```python import redis r = redis.Redis(host='localhost', port=6379) r.lpush('jd:start_urls', 'https://search.jd.com/Search?keyword=%E5%8D%8E%E4%B8%BA%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8') ``` 最终,您就可以运行分布式爬虫并抓取京东华为笔记本的数据了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值