crawlSpider

作用:为了方便提取页面整个链接url,不必使用创参寻找url,通过拉链提取器,将start_urls的全部符合规则的URL地址全部取出

使用:
创建文件scrapy startproject xxx(文件名)

cd xxx

scrapy genspider -t crawl xxx www.xxx.com

运行:
scrapy crawl xxx(文件名)

  1. import scrapy
  2. from scrapy.linkextractors import LinkExtractor
  3. from scrapy.spiders import CrawlSpider, Rule
  4.  
  5. class ChoutiSpider(CrawlSpider):
  6. # name = 'chouti'
  7. # # allowed_domains = ['www.xxx.com']
  8. # start_urls = ['https://dig.chouti.com/r/scoff/hot/1']
  9. #
  10. # #连接提取器:
  11. # #allow:表示的就是链接提取器提取连接的规则(正则)
  12. # link = LinkExtractor(allow=r'/r/scoff/hot/\d+')
  13. #
  14. # rules = (
  15. # #规则解析器:将链接提取器提取到的连接所对应的页面数据进行指定形式的解析
  16. # Rule(link, callback='parse_item', follow=True),
  17. # # 让连接提取器继续作用到链接提取器提取到的连接所对应的页面中
  18. # )
  19. #
  20. # def parse_item(self, response):
  21. # print(response)
  22.  
  23. name = 'qiubai'
  24. # allowed_domains = ['www.xxx.com']
  25. start_urls = ['https://www.qiushibaike.com/pic/']
  26.  
  27. # 连接提取器:
  28. # allow:表示的就是链接提取器提取连接的规则(正则)/pic/page/3?s=5172496
  29. link = LinkExtractor(allow=r'/pic/page/\d+\?s=\d+')
  30. link1 = LinkExtractor(allow=r'/pic/$')
  31. # link1 = LinkExtractor(allow=r'')
  32. rules = (
  33. # 规则解析器:将链接提取器提取到的连接所对应的页面数据进行指定形式的解析
  34. Rule(link, callback='parse_item', follow=True),
  35. # 让连接提取器继续作用到链接提取器提取到的连接所对应的页面中
  36.  
  37. Rule(link1, callback='parse_item', follow=True),
  38. )
  39.  
  40. def parse_item(self, response):
  41. print(response)

分布式

作用:为了进行多台机器一起进行爬取数据,倘若单纯使用继承原生的scrapy的话,有两个问题无法解决

- 调度器不能被共享  (你不知道这条url有没有被爬取)

- 管道无法被共享  (获取的数据不在同一个存储的数据库中)

使用分布式的scrapy-redis组件会为我们提供什么:
- 提供了可以被共享的调度器和管道

为什么分布式没有初始start_urls

- 因为是多台电脑操作,无法将start_urls 初始到哪一个主机上,所以在redis 是输入 url ,哪个主机抢到了算那个

- 分布式爬虫实现流程

1.环境安装:pip install scrapy-redis

2.创建工程
3.创建爬虫文件:RedisCrawlSpider  RedisSpider
    - scrapy genspider -t crawl xxx www.xxx.com

4.对爬虫文件中的相关属性进行修改:
    - 导报:from scrapy_redis.spiders import RedisCrawlSpider
    - 将当前爬虫文件的父类设置成RedisCrawlSpider
    - 将起始url列表替换成redis_key = 'xxx'(调度器队列的名称)

5.在配置文件中进行配置:
    - 使用组件中封装好的可以被共享的管道类:
        ITEM_PIPELINES = {
            'scrapy_redis.pipelines.RedisPipeline': 400
            }
    - 配置调度器(使用组件中封装好的可以被共享的调度器)
        # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
        DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
        # 使用scrapy-redis组件自己的调度器
        SCHEDULER = "scrapy_redis.scheduler.Scheduler"
        # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
        SCHEDULER_PERSIST = True

- 指定存储数据的redis:
        REDIS_HOST = 'redis服务的ip地址'
        REDIS_PORT = 6379

- 配置redis数据库的配置文件
        - 取消保护模式:protected-mode no  #50多行
        - bind绑定: #bind 127.0.0.1    #70多行

- 启动redis

6.执行分布式程序
    scrapy runspider xxx.py

7.向调度器队列中仍入一个起始url:
    在redis-cli中执行:

lpsuh  xxx(文件名)  https://www.baidu.com   #启动公共的url

lrange xxx:items 0 -1    #查看数据

  1. import scrapy
  2. from scrapy.linkextractors import LinkExtractor
  3. from scrapy.spiders import CrawlSpider, Rule
  4. from scrapy_redis.spiders import RedisCrawlSpider
  5. from redisChoutiPro.items import RedischoutiproItem
  6. class ChoutiSpider(RedisCrawlSpider):
  7. name = 'chouti'
  8. # allowed_domains = ['www.xxx.com']
  9. # start_urls = ['http://www.xxx.com/']
  10. redis_key = 'chouti'#调度器队列的名称
  11. rules = (
  12. Rule(LinkExtractor(allow=r'/all/hot/recent/\d+'), callback='parse_item', follow=True),
  13. )
  14.  
  15. def parse_item(self, response):
  16. div_list = response.xpath('//div[@class="item"]')
  17. for div in div_list:
  18. title = div.xpath('./div[4]/div[1]/a/text()').extract_first()
  19. author = div.xpath('./div[4]/div[2]/a[4]/b/text()').extract_first()
  20. item = RedischoutiproItem()
  21. item['title'] = title
  22. item['author'] = author
  23.  
  24. yield item

setting配置

  1. ITEM_PIPELINES = {
  2. 'scrapy_redis.pipelines.RedisPipeline': 400
  3. }
  4.  
  5. # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
  6. DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
  7. # 使用scrapy-redis组件自己的调度器
  8. SCHEDULER = "scrapy_redis.scheduler.Scheduler"
  9. # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
  10. SCHEDULER_PERSIST = True #数据指纹
  11.  
  12. REDIS_HOST = '127.0.0.1'
  13. REDIS_PORT = 6379

最后启动项目:
scrapy runspider xxx

在进行redis 的传入 url 的操作

增量式

作用:进行爬取数据时,为了避免爬取重复的数据而产生的

增量式的核心,利用sadd判断是否爬取数据了

sadd xx(文件名) 1

print(1)

sadd xx(文件名) 1

print(0)

继续用到crawlSpider来创建文件

关于url 使用sadd 作为判断

  1. import scrapy
  2. from scrapy.linkextractors import LinkExtractor
  3. from scrapy.spiders import CrawlSpider, Rule
  4. from redis import Redis
  5. from increment1_Pro.items import Increment1ProItem
  6. class MovieSpider(CrawlSpider):
  7. name = 'movie'
  8. # allowed_domains = ['www.xxx.com']
  9. start_urls = ['https://www.4567tv.tv/index.php/vod/show/id/7.html']
  10.  
  11. rules = (
  12. Rule(LinkExtractor(allow=r'/index.php/vod/show/id/7/page/\d+\.html'), callback='parse_item', follow=True),
  13. )
  14.  
  15. def parse_item(self, response):
  16. conn = Redis(host='127.0.0.1',port=6379)
  17. detail_url_list = 'https://www.4567tv.tv'+response.xpath('//li[@class="col-md-6 col-sm-4 col-xs-3"]/div/a/@href').extract()
  18. for url in detail_url_list:
  19. #ex == 1:set中没有存储url
  20. ex = conn.sadd('movies_url',url)
  21. if ex == 1:
  22. yield scrapy.Request(url=url,callback=self.parse_detail)
  23. else:
  24. print('网站没有更新数据,暂无新数据可爬!')
  25.  
  26. def parse_detail(self,response):
  27. item = Increment1ProItem()
  28. item['name'] = response.xpath('/html/body/div[1]/div/div/div/div[2]/h1/text()').extract_first()
  29. item['actor'] = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[3]/a/text()').extract_first()
  30.  
  31. yield item

     items.py

  1. import scrapy
  2.  
  3. class Increment1ProItem(scrapy.Item):
  4. # define the fields for your item here like:
  5. name = scrapy.Field()
  6. actor = scrapy.Field()

pipelines.py

  1. from redis import Redis
  2. class Increment1ProPipeline(object):
  3. conn = None
  4. def open_spider(self,spider):
  5. self.conn = Redis(host='127.0.0.1',port=6379)
  6. def process_item(self, item, spider):
  7. # dic = {
  8. # 'name':item['name'],
  9. # 'axtor':item['actor']
  10. # }
  11. print('有新数据被爬取到,正在入库......')
  12. self.conn.lpush('movie_data',item)
  13. return item

setting 配置user-agent 和 robot = False

关于文件内容基于sadd 的判断

  1. import scrapy
  2. from scrapy.linkextractors import LinkExtractor
  3. from scrapy.spiders import CrawlSpider, Rule
  4.  
  5. from increment2_Pro.items import Increment2ProItem
  6. from redis import Redis
  7. import hashlib
  8. class QiubaiSpider(CrawlSpider):
  9. name = 'qiubai'
  10. # allowed_domains = ['www.xxx.com']
  11. start_urls = ['https://www.qiushibaike.com/text/']
  12.  
  13. rules = (
  14. Rule(LinkExtractor(allow=r'/text/page/\d+/'), callback='parse_item', follow=True),
  15. )
  16.  
  17. def parse_item(self, response):
  18.  
  19. div_list = response.xpath('//div[@class="article block untagged mb15 typs_hot"]')
  20. conn = Redis(host='127.0.0.1',port=6379)
  21. for div in div_list:
  22. item = Increment2ProItem()
  23. item['content'] = div.xpath('.//div[@class="content"]/span//text()').extract()
  24. item['content'] = ''.join(item['content'])
  25. item['author'] = div.xpath('./div/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
  26. source = item['author']+item['content']
  27. #自己制定了一种形式的数据指纹
  28. hashValue = hashlib.sha256(source.encode()).hexdigest()
  29.  
  30. ex = conn.sadd('qiubai_hash',hashValue)
  31. if ex == 1:
  32. yield item
  33. else:
  34. print('没有更新数据可爬!!!')

剩下的都一样

如何提高爬虫效率

  1. 增加并发:
  2. 默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100
  3. 降低日志级别:
  4. 在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = INFO
  5. 禁止cookie
  6. 如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False
  7. 禁止重试:
  8. 对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False
  9. 减少下载超时:
  10. 如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s

爬虫 crawlSpider 分布式 增量式 提高效率的更多相关文章

  1. python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制

    CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器Link ...

  2. 爬虫07 /scrapy图片爬取、中间件、selenium在scrapy中的应用、CrawlSpider、分布式、增量式

    爬虫07 /scrapy图片爬取.中间件.selenium在scrapy中的应用.CrawlSpider.分布式.增量式 目录 爬虫07 /scrapy图片爬取.中间件.selenium在scrapy ...

  3. 爬虫---scrapy分布式和增量式

    分布式 概念: 需要搭建一个分布式的机群, 然后在每一台电脑中执行同一组程序, 让其对某一网站的数据进行联合分布爬取. 原生的scrapy框架不能实现分布式的原因 调度器不能被共享, 管道也不能被共享 ...

  4. Scrapy 增量式爬虫

    Scrapy 增量式爬虫 https://blog.csdn.net/mygodit/article/details/83931009 https://blog.csdn.net/mygodit/ar ...

  5. 基于Scrapy框架的增量式爬虫

    概述 概念:监测 核心技术:去重 基于 redis 的一个去重 适合使用增量式的网站: 基于深度爬取的 对爬取过的页面url进行一个记录(记录表) 基于非深度爬取的 记录表:爬取过的数据对应的数据指纹 ...

  6. Python爬虫教程-34-分布式爬虫介绍

    Python爬虫教程-34-分布式爬虫介绍 分布式爬虫在实际应用中还算是多的,本篇简单介绍一下分布式爬虫 什么是分布式爬虫 分布式爬虫就是多台计算机上都安装爬虫程序,重点是联合采集.单机爬虫就是只在一 ...

  7. Java 多线程爬虫及分布式爬虫架构探索

    这是 Java 爬虫系列博文的第五篇,在上一篇 Java 爬虫服务器被屏蔽,不要慌,咱们换一台服务器 中,我们简单的聊反爬虫策略和反反爬虫方法,主要针对的是 IP 被封及其对应办法.前面几篇文章我们把 ...

  8. Java 多线程爬虫及分布式爬虫架构

    这是 Java 爬虫系列博文的第五篇,在上一篇 Java 爬虫服务器被屏蔽,不要慌,咱们换一台服务器 中,我们简单的聊反爬虫策略和反反爬虫方法,主要针对的是 IP 被封及其对应办法.前面几篇文章我们把 ...

  9. 增量式PID简单翻板角度控制

    1.研究背景 随着电子技术.信息技术和自动控制理论技术的完善与发展,近来微型处理器在控制方面的应用也越来越多.随之逐渐渗透到我们生活的各个领域.如导弹导航装置,飞机上仪表的控制,网络通讯与数据传输,工 ...

随机推荐

  1. Linux:FTP服务器的搭建

    FTP服务器的简介 系统用户 即系统本机的用户.Linux一般不会针对实体用户进行限制,因此实体用户可以针对整个文件 系统进行工作.但通常不希望他们通过FTP方式远程访问系统. 虚拟用户 只能采用FT ...

  2. java8-04-初识函数式接口

    为什么用函数式接口                                   在函数式编程思想下,允许函数本身作为参数传入另一个函数.使用函数式接口实现"传递行为"的思想 ...

  3. 断点调试debugger

    断点调试有两种打点方式 (1)控制台手动打点 (2)代码中添加 debugger打点 .

  4. 80道最新java基础部分面试题(五)

    自己整理的面试题,希望可以帮到大家,需要更多资料的可以私信我哦,大家一起学习进步! 48.同步和异步有何异同,在什么情况下分别使用他们?举例说明.  如果数据将在线程间共享.例如正在写的数据以后可能被 ...

  5. (day57)九、多对多创建的三种方式、Forms组件

    目录 一.多对多三种创建方式 (一)全自动 (二)纯手撸(基本不用) (三)半自动(推荐使用) 二.forms组件 (一)校验数据 (1)常用内置字段及参数 (2)内置的校验器 (3)HOOK方法 ( ...

  6. docker /var/lib/docker/aufs/mnt 目录满了怎么清理

    1.创建脚本文件 vi cleandocker.sh 内容如下: #!/bin/sh echo "==================== start clean docker contai ...

  7. HTML连载42-清空默认边距、文字行高

    一.            webstorm取色技巧:webstorm内置了颜色取色器,我们对某种颜色未知的时候,可以利用下图中的取色器,进行颜色识别. 二.系统会默认给body添加外边距,因此我们对 ...

  8. IT兄弟连 HTML5教程 HTML5的靠山 W3C、IETF是什么

    无规矩不成方圆,软件开发当然不能例外.Web开发涉及的厂商和技术非常多,所以必须要有参考的标准,而且需要一系列的标准.Web程序都是通过浏览器来解析执行的,通过页面的展示内容与用户互动,所以Web标准 ...

  9. Java语言入门-第一个HelloWorld程序

    1.官网下载Jdk 这里给出官网下载网址:https://www.oracle.com/technetwork/java/javase/downloads . 1.1 打开之后出现如下界面: 1.2选 ...

  10. 创 PHP RSA2 签名算法

        什么是RSA2 ? RSA2 是在原来SHA1WithRSA签名算法的基础上,新增了支持SHA256WithRSA的签名算法. 该算法比SHA1WithRSA有更强的安全能力. 为了您的应用安 ...