crawlSpider

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

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

cd xxx

scrapy genspider -t crawl xxx www.xxx.com

运行:
scrapy crawl xxx(文件名)

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule class ChoutiSpider(CrawlSpider):
# name = 'chouti'
# # allowed_domains = ['www.xxx.com']
# start_urls = ['https://dig.chouti.com/r/scoff/hot/1']
#
# #连接提取器:
# #allow:表示的就是链接提取器提取连接的规则(正则)
# link = LinkExtractor(allow=r'/r/scoff/hot/\d+')
#
# rules = (
# #规则解析器:将链接提取器提取到的连接所对应的页面数据进行指定形式的解析
# Rule(link, callback='parse_item', follow=True),
# # 让连接提取器继续作用到链接提取器提取到的连接所对应的页面中
# )
#
# def parse_item(self, response):
# print(response) name = 'qiubai'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/pic/'] # 连接提取器:
# allow:表示的就是链接提取器提取连接的规则(正则)/pic/page/3?s=5172496
link = LinkExtractor(allow=r'/pic/page/\d+\?s=\d+')
link1 = LinkExtractor(allow=r'/pic/$')
# link1 = LinkExtractor(allow=r'')
rules = (
# 规则解析器:将链接提取器提取到的连接所对应的页面数据进行指定形式的解析
Rule(link, callback='parse_item', follow=True),
# 让连接提取器继续作用到链接提取器提取到的连接所对应的页面中 Rule(link1, callback='parse_item', follow=True),
) def parse_item(self, response):
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    #查看数据

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from redisChoutiPro.items import RedischoutiproItem
class ChoutiSpider(RedisCrawlSpider):
name = 'chouti'
# allowed_domains = ['www.xxx.com']
# start_urls = ['http://www.xxx.com/']
redis_key = 'chouti'#调度器队列的名称
rules = (
Rule(LinkExtractor(allow=r'/all/hot/recent/\d+'), callback='parse_item', follow=True),
) def parse_item(self, response):
div_list = response.xpath('//div[@class="item"]')
for div in div_list:
title = div.xpath('./div[4]/div[1]/a/text()').extract_first()
author = div.xpath('./div[4]/div[2]/a[4]/b/text()').extract_first()
item = RedischoutiproItem()
item['title'] = title
item['author'] = author yield item

setting配置

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_HOST = '127.0.0.1'
REDIS_PORT = 6379

最后启动项目:
scrapy runspider xxx

在进行redis 的传入 url 的操作

增量式

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

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

sadd xx(文件名) 1

print(1)

sadd xx(文件名) 1

print(0)

继续用到crawlSpider来创建文件

关于url 使用sadd 作为判断

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

     items.py

import scrapy

class Increment1ProItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
actor = scrapy.Field()

pipelines.py

from redis import Redis
class Increment1ProPipeline(object):
conn = None
def open_spider(self,spider):
self.conn = Redis(host='127.0.0.1',port=6379)
def process_item(self, item, spider):
# dic = {
# 'name':item['name'],
# 'axtor':item['actor']
# }
print('有新数据被爬取到,正在入库......')
self.conn.lpush('movie_data',item)
return item

setting 配置user-agent 和 robot = False

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

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule from increment2_Pro.items import Increment2ProItem
from redis import Redis
import hashlib
class QiubaiSpider(CrawlSpider):
name = 'qiubai'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://www.qiushibaike.com/text/'] rules = (
Rule(LinkExtractor(allow=r'/text/page/\d+/'), callback='parse_item', follow=True),
) def parse_item(self, response): div_list = response.xpath('//div[@class="article block untagged mb15 typs_hot"]')
conn = Redis(host='127.0.0.1',port=6379)
for div in div_list:
item = Increment2ProItem()
item['content'] = div.xpath('.//div[@class="content"]/span//text()').extract()
item['content'] = ''.join(item['content'])
item['author'] = div.xpath('./div/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
source = item['author']+item['content']
#自己制定了一种形式的数据指纹
hashValue = hashlib.sha256(source.encode()).hexdigest() ex = conn.sadd('qiubai_hash',hashValue)
if ex == 1:
yield item
else:
print('没有更新数据可爬!!!')

剩下的都一样

如何提高爬虫效率

增加并发:
默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。 降低日志级别:
在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’ 禁止cookie:
如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False 禁止重试:
对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False 减少下载超时:
如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写: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. 表单生成器(Form Builder)之表单数据存储结构mongodb篇

    从这篇笔记开始,记录一下表单生成器(Form Builder)相关的一些东西,网上关于他的介绍有很多,这里就不解释了. 开篇说一下如何存储Form Builder生成的数据.

  2. Ubuntu 18.04 安装 python 的 redis 库

    安装 如果只是安装了 python2.x 或者 python3.x,直接安装即可,命令如下: pip install redis 如果是同时安装了 python2.x 和 python3.x 的,则需 ...

  3. 从傅里叶变换(FFT)到数论变换(NTT)

    FFT可以用来计算多项式乘法,但是复数的运算中含有大量的浮点数,精度较低.对于只有整数参与运算的多项式,有时,\(\text{NTT(Number-Theoretic Transform)}\)会是更 ...

  4. WPf 带滚动条WrapPanel 自动换行 和控件右键菜单

    原文:WPf 带滚动条WrapPanel 自动换行 和控件右键菜单 技能点包括 WPf 样式的引用 数据的验证和绑定 比较适合初学者 前台: <Window.Resources> < ...

  5. npm 命令 --save 和 --save-dev 的区别

    回顾 npm install 命令 我们在使用 npm install 安装模块的模块的时候 ,一般会使用下面这几种命令形式: 1 2 3 4 5 6 7 npm install moduleName ...

  6. swoole4创建Mysql连接池

    一 .什么是mysql连接池 场景:每秒同时有1000个并发,但是这个mysql同时只能处理400个连接,mysql会宕机.   解决方案:连接池,这个连接池建立了200个和mysql的连接,这100 ...

  7. 程序员,你还不会合理选择Filter、Interceptor、Aspect?

    小伙伴们应该听说过过滤器.拦截器.切面,印象上都能够起到截断拦截的作用,在做一些业务需求时,不知道如何选择,今天老顾就来介绍一下他们之间的区别. 过滤器可以拦截到方法的请求和响应 (ServletRe ...

  8. 鸟哥的Linux私房菜笔记第五章,文件权限与目录配置(二)

    Linux目录配置的依据--FHS 因为利用Linux来开发产品的公司太多,例如,CentOS.Ubuntu.ReHat...,导致了配置文件存放的目录没有统一的标准.后来就有了FHS(Filesys ...

  9. windows server 2008 r2 安装 vs2017 无法进入安装界面问题解决方法

    在 windows server 2008 r2 版本操作系统上安装 vs2017 经常出现下载进度条结束后没有任何反应问题,一般是因为安装程序兼容性造成的,解决方案如下: 将 C:\Program ...

  10. hive 标准hql建表语法格式

    一.标准hql建表语法格式1.官方标准语法:(hql不区分大小写,下面[]里的属性是可选属性) 具体参考官网界面:HIVE官网建表说明文档 CREATE [EXTERNAL] TABLE [IF NO ...