赞
踩
首先回顾一下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)python 安装
pip install scrapy_redis
(2)基本使用数据来源
clone github scrapy_redis源码文件
git clone https://github.com/rolando/scrapy-redis.git
(3)打开example示例项目
(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)总结
步骤:
普通爬虫改成分布式爬虫
1.改造爬虫
1.1 导入类
1.2 继承类
1.3 注释start_url
2.改写配置文件
按常规创建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.改造爬虫
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
结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。