电商商城定制开发scrapy-redis

1. 简介

流程

scrapy-redis

scrapy电商商城定制开发是一个基于redis的scrapy组件,电商商城定制开发用于快速实现scrapy电商商城定制开发项目的部署和数据爬取。

组件
  • Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Scheduler电商商城定制开发中间的通讯,信号、电商商城定制开发数据传递等。
  • Scheduler(调度器):电商商城定制开发它负责接受引擎发送过来的Request请求,电商商城定制开发并按照一定的方式进行整理排列,入队,电商商城定制开发当引擎需要时,电商商城定制开发交还给引擎。
  • Downloader(下载器):负责下载Scrapy Engine(引擎)电商商城定制开发发送的所有Requests请求,电商商城定制开发并将其获取到的Responses交还给Scrapy Engine(引擎),电商商城定制开发由引擎交给Spider来处理。
  • Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)。
  • Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方。
  • Downloader Middlewares(下载中间件):自定义扩展下载功能的组件。
  • Spider Middlewares(Spider中间件):自定扩展和操作引擎和Spider中间通信的功能组件。
流程

(1) 引擎(Scrapy Engine)向爬虫(Spiders)请求第一个要爬取的URL。

(2) 引擎从爬虫中获取到第一个要爬取的URL,封装成请求(Request)并交给调度器()。

(3) 调度器访问Redis数据库对请求进行判重,如果不重复,就把这个请求添加到Redis中。

(4) 当调度条件满足时,调度器会从Redis中取出Request,交给引擎,引擎将这个Request通过下载中间件转发给下载器。

(5) 一旦页面下载完毕,下载器(Downloader)生成一个该页面的响应(Response),并将其通过下载中间件发送给引擎。

(6) 引擎从下载器中接收到响应,并通过爬虫中间件(Spider Middlewares)发送给爬虫处理。

(7) Spider处理Response,并返回爬取到的Item及新的Request给引擎。

(8) 引擎将爬取到的Item通过Item Pipeline给Redis数据库,将Request给调度器。

从(2) 开始重复,直到调度器中没有更多的Request为止。

2. scrapy-redis对比scrapy

scrapy
  • 调度器、管道不可以被分布式集群共享

  • scrapy使用改造后的collection.deque(双端队列)存放待爬取的request

  • scrapy中跟待爬取队列直接相关的是Scheduler(调度器),scheduler负责对新的requests进行入列操作,把待爬取的队列安装优先级建立字典,根据request中的priority属性做优先级(越小的优先级越高)进行出队列操作(不能共享)。

  • scrapy把已发送的request指纹放到集合中,下一个request指纹拿到集合中对比,存在说明已经爬取过不继续执行操作。

    def request_seen(self, request: Request) -> bool:	fp = self.request_fingerprint(request)	if fp in self.fingerprints:		# self.fingerprints指纹集合		return True	self.fingerprints.add(fp)	if self.file:		self.file.write(fp + '')	return False
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

scrapy-redis
  • scrapy-redis使用redis list存放待爬取的request

  • scrapy-redis在setting配置SCHEDULER = "scrapy_redis.scheduler.Scheduler"替换原本的待爬取队列。使用redis进行任务分发与调度,把所有待爬取的请求都放入redis,所有爬虫都去redis读取请求。

  • Scrapy-Redis中的去重是由Duplication Filter组件实现的,该组件利用Redis中set集合不重复的特性,巧妙地实现了这个功能。首先Scrapy-Redis调度器接收引擎递过来的请求,然后将这个请求指纹存入set集合中检查是否重复,并把不重复的请求加入到Redis的请求队列中。

        def request_seen(self, request):        fp = self.request_fingerprint(request)        # This returns the number of values added, zero if already exists.        added = self.server.sadd(self.key, fp)        return added == 0
    • 1
    • 2
    • 3
    • 4
    • 5

  • scrapy-redis不再使用原有的Spider类,重写RedisSpider继承Spider和RedisMixin类。当我们生成一个Spider继承RedisSpider时,调用setup_redis函数,这个函数会去连接redis数据库,然后会设置signals(信号):一个是当spider空闲时候的signal,会调用spider_idle函数,这个函数调用schedule_next_request函数,保证spider是一直活着的状态,并且抛出DontCloseSpider异常。一个是当抓到一个item时的signal,会调用item_scraped函数,这个函数会调用schedule_next_request函数,获取下一个request。

3. 简述

命令
# 新建项目$ scrapy startproject project_name# 新建爬虫$ scrapy genspider -t basic spider_name www.baidu.combasic 基础crawl 自动爬虫csvfeed 用来处理csv文件xmlfeed 用来处理xml文件# 运行爬虫$ scrapy crawl spider_name# 自动爬虫(做增量爬虫)$ scrapy genspider -t crawl xxx www.xxx.com$ scrapy runspider xxx.py# 交互式终端进入终端:scrapy shell ‘www.baidu.com’查看状态: response显示网页html:response.textxpath匹配数据:response.xpath(‘//div[@class=”head_wrapper”])退出终端:exit()# 帮助$ scrapy -h/--help
  • 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
目录文件说明
scrapy.cfg :项目的配置文件Spider/ :项目的Python模块,将会从这里引用代码Spider/items.py :项目的目标文件Spider/pipelines.py :项目的管道文件Spider/middlewares.py : 爬虫、下载中间件Spider/settings.py :项目的设置文件Spider/spiders/ :存储爬虫代码目录
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
代码修改
# setting.py# 1.启用调度将请求存储进redisSCHEDULER = "scrapy_redis.scheduler.Scheduler"# 2.确保所有spider通过redis共享相同的重复过滤。DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"# 3.指定连接到Redis时要使用的主机和端口。REDIS_HOST = '47.97.102.116'REDIS_PORT = 6379# 默认的scrapy-redis请求队列形式(按优先级)SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"# 队列形式,请求先进先出#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"# 栈形式,请求先进后出#SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"# 设置为True不清理redis队列,允许暂停/恢复抓取。多个爬虫读取url会造成重复抓取SCHEDULER_PERSIST = True# spider修改from scrapy_redis.spiders import RedisSpiderclass Spider(RedisSpider):      name = 'spider_name'    # allowed_domains = ['movie.douban.com']  # 爬取边界    redis_key = 'db:start_urls'   # 开启爬虫钥匙# redis$ lpush db:start_urls www.baidu.com
  • 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
调度算法

爬虫请求调度算法有三种:

  1. 队列(默认)

    SCHEDULER_QUEUE_CLASS=‘scrapy_redis.queue.SpiderQueue’

    先进先出队列,先放进Redis的请求会优先爬取。

  2. SCHEDULER_QUEUE_CLASS=‘scrapy_redis.queue.SpiderStack’

    后进先出,后放入redis的请求会优先爬取。

  3. 优先级队列

    SCHEDULER_QUEUE_CLASS=‘scrapy_redis.queue.SpiderPriorityQueue’

    根据优先级算法计算出请求爬取先后。

Redis存放内容
  • spidername:items(不建议用,爬取内容多时会很占用内存,一般把数据保存到mongodb)

    list类型,保存爬虫获取到的数据item内容是json字符串。

  • spidername:dupefilter

    set类型,用于爬虫访问的URL去重内容,是40个字符的url的hash字符串

  • spidername:start_urls

    list类型,用于接收redis spider启动时的第一个url

  • spidername:requests

    zset类型,用于存放requests等待调度。内容是requests对象的序列化字符串

4. 分布式策略

​ Slaver获取Master待爬取Request进行数据爬取,在爬取过程中处理生成新的任务抛给Master。Master只有一个Redis数据库复制对Slave任务进行去重、加入待爬取队列。

注意:Master和Slaver交互的信息并不单单是url而是包含许多信息的Request

{'url': 'https://book.qidian.com/info/1010868264/', 'callback': 'parse_detail', 'errback': None, 'headers': {b'Referer': [b'https://www.qidian.com/all/page2/'], b'Accept': [b'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'], b'Accept-Language': [b'en'], b'User-Agent': [b'Scrapy/2.6.1 (+https://scrapy.org)'], b'Accept-Encoding': [b'gzip, deflate'], b'Cookie': [b'_csrfToken=Y4KP9vSv2X6XuWvDyVeke5o0jlyUazCqrrosBGrJ; newstatisticUUID=1652946272_1559582696; fu=762226548']}, 'method': 'GET', 'body': b'', 'cookies': {}, 'meta': {'item': {'detail_url': 'https://book.qidian.com/info/1010868264/', 'img_url': 'https://bookcover.yuewen.com/qdbimg/349573/1010868264/150', 'name': '诡秘之主'}, 'depth': 2, 'download_timeout': 180.0, 'download_slot': 'book.qidian.com', 'download_latency': 0.5939218997955322, 'retry_times': 1}, 'encoding': 'utf-8', 'priority': -1, 'dont_filter': True, 'flags': [], 'cb_kwargs': {}}
  • 1
  • 2
  • 3

5.进阶

中间件使用

下载中间件(Downloader Middleware)核心方法有3个:

  • process_request(request, spider)

    设置headers,proxy

  • process_response(request, response, spider)

    设置response编码等信息

  • process_exception(request, exception, spider)

    异常报错(曾它做过重试,但后来发现直接在setting设置更方便)

crawl 爬虫

基于CrawlSpider可以很方便地进行全站数据爬取

class QidianCrawlSpider(CrawlSpider):	# 继承CrawlSpider类    name = 'qidian_crawl'    allowed_domains = ['www.qidian.com', 'book.qidian.com']    start_urls = ['http://www.qidian.com/']    rules = (        Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),    )# rules规则解析器内包含链接提取器LinkExtractor(allow=r'Items/'),callback指定解析方法,follow指定爬取页面内可见部分还是全部(True把链接提取器继续作用到链接提取器对应的页面,False爬取页面内可见部分页面)。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用CrawlSpider生成爬虫文件时,在规则解析器rules里面添加正则表达式进而发起请求,如果要一个请求内需要再次发起请求,就需要在rules中添加链接请求并指定对应的解析方法

6. 优缺点

优点:广泛多域爬取大量url,节约时间,去重简单,可以启动尽可能爬虫去进行数据爬取。

内包含链接提取器LinkExtractor(allow=r’Items/'),callback指定解析方法,follow指定爬取页面内可见部分还是全部(True把链接提取器继续作用到链接提取器对应的页面,False爬取页面内可见部分页面)。

使用`CrawlSpider`生成爬虫文件时,在规则解析器`rules`里面添加正则表达式进而发起请求,如果要一个请求内需要再次发起请求,就需要在`rules`中添加链接请求并指定对应的解析方法### 6. 优缺点优点:广泛多域爬取大量url,节约时间,去重简单,可以启动尽可能爬虫去进行数据爬取。缺点:相对于单个爬虫不便于管理。Request对象里面信息量较大,降低爬虫速度、占用Redis存储空间。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发