scrapy框架的使用

  • 基于管道的持久化存储的编码流程

    • 在爬虫文件中数据解析

    • 将解析到的数据封装到一个叫做Item类型的对象

    • item类型的对象提交给管道

    • 管道负责调用process_item的方法接收item,然后进行某种形式的持久化存储

    • 在配置文件中开启管道

      ITEM_PIPELINES = {
      'frist_scrapy.pipelines.FristScrapyPipeline': 300,
      } # 将这段代码的注释去掉
    • 注意事项:

      1.什么情况下需要用到多个管道类
      - 一个管道类对应一种形式的持久化存储 2.process_item中的return item:
      - 可以将item提交给下一个即将被执行的管道类 3.如果直接将一个字典写入到redis报错的话:
      - pip install redis==2.10.6
  • 全栈数据的爬取

    • 手动请求的发送

      yield scrapy.Request(url=new_url,callback=self.parse)
      
      # 可以传入参数 meta
      yield scrapy.Request(url=new_url,callback=self.parse,meta={'item':item})
    • 总结:什么时候用yield

      1.向管道提交item的时候
      2.手动请求发送的时候
  • 如何发送post请求:

      yield scrapy.FromRequest(url=new_url,callback=self.parse,formdata={})
    
    
    • 为什么start_urls列表可以进行get请求的发送:

      父类对start_requests的原始实现:
      def start_requests(self):
      for url in self.start_urls:
      yield scrapy.Request(url,callback=self.parse)
  • 五大核心组件(对象)

    • 对scrapy的异步实现有一定的理解

    • 相关方法和对象实例化的调用流程

    • 组件的作用:

      引擎(Scrapy)
      用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler)
      用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址 下载器(Downloader)
      用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的) 爬虫(Spiders)
      爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面 项目管道(Pipeline)
      负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
  • 如何适当提升scrapy爬取数据的效率

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

    • 作用:帮助scrapy实现深度爬取

      • 深度爬取:

        • 爬取的数据没有在同一张页面中
    • 需求:爬取名称和简介,https://www.4567tv.tv/frim/index1.html

    • 实现流程

      • 传参:

        yield scrapy.Request(url,callback,meta),将meta这个字典传递给callback
      • 接收参数

        response.meta
    • 代码实现:

      # -*- coding: utf-8 -*-
      import scrapy class MvspidersSpider(scrapy.Spider):
      name = 'mvspiders'
      # allowed_domains = ['https://www.4567tv.tv/frim/index1.html']
      start_urls = ['https://www.4567tv.tv/frim/index1.html'] url = "https://www.4567tv.tv/index.php/vod/show/id/5/page/%s.html"
      pageNum = 1 def parse(self, response): li_list = response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li') for li in li_list:
      a_href = li.xpath('./div/a/@href').extract_first()
      url = 'https://www.4567tv.tv/' + a_href # 对详情页的url进行手动请求发送
      # 请求传参:
      # 参数meta是一个字典,字典会传递给callback
      yield scrapy.Request(url,callback=self.infoparse) # 用于全栈的爬取
      if self.pageNum < 5:
      self.pageNum += 1
      new_url = self.url%self.pageNum
      # 递归调用自己
      yield scrapy.Request(new_url,callback=self.parse) def infoparse(self,response): title = response.xpath("/html/body/div[1]/div/div/div/div[2]/h1/text()").extract_first() content = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[2]/text()').extract_first()

      items.py文件中的,它的作用就是为了定义你需要给上边文件中的item封装数据就必须要在这个类中添加对应的数据名,后边的scrapy.Field()就是内置字典类(dict)的一个别名,并没有提供额外的方法和属性,被用来基于类属性的方法来支持item生命语法。

      # -*- coding: utf-8 -*-
      
      # Define here the models for your scraped items
      #
      # See documentation in:
      # https://docs.scrapy.org/en/latest/topics/items.html import scrapy
      class MvItem(scrapy.Item):
      # define the fields for your item here like:
      title = scrapy.Field()
      content = scrapy.Field()

      pipelines.py文件中多种数据存储的方法

      # -*- coding: utf-8 -*-
      
      # Define your item pipelines here
      #
      # Don't forget to add your pipeline to the ITEM_PIPELINES setting
      # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html #写入到文本文件中
      import pymysql
      from redis import Redis
      class DuanziproPipeline(object):
      fp = None
      def open_spider(self,spider):
      print('开始爬虫......')
      self.fp = open('./duanzi.txt','w',encoding='utf-8')
      #方法每被调用一次,参数item就是其接收到的一个item类型的对象
      def process_item(self, item, spider):
      # print(item)#item就是一个字典
      self.fp.write(item['title']+':'+item['content']+'\n')
      return item#可以将item提交给下一个即将被执行的管道类
      def close_spider(self,spider):
      self.fp.close()
      print('爬虫结束!!!')
      #将数据写入到mysql
      class MysqlPipeLine(object):
      conn = None
      cursor = None
      def open_spider(self,spider):
      self.conn = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='222',db='spider',charset='utf8')
      print(self.conn)
      def process_item(self,item,spider):
      sql = 'insert into duanzi values ("%s","%s")'%(item['title'],item['content'])
      self.cursor = self.conn.cursor()
      try:
      self.cursor.execute(sql)
      self.conn.commit()
      except Exception as e:
      print(e)
      self.conn.rollback()
      return item
      def close_spider(self,spider):
      self.cursor.close()
      self.conn.close() #将数据写入到redis
      class RedisPileLine(object):
      conn = None
      def open_spider(self,spider):
      self.conn = Redis(host='127.0.0.1',port=6379)
      print(self.conn)
      def process_item(self,item,spider):
      self.conn.lpush('duanziData',item)
      return item

scrapy框架基于管道的持久化存储的更多相关文章

  1. scrapy框架基于CrawlSpider的全站数据爬取

    引入 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法 ...

  2. 11.scrapy框架持久化存储

    今日概要 基于终端指令的持久化存储 基于管道的持久化存储 今日详情 1.基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的 ...

  3. scrapy框架持久化存储

    基于终端指令的持久化存储 基于管道的持久化存储 1.基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文 ...

  4. scrapy框架的持久化存储

    一 . 基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 执行输出指定格式进行存 ...

  5. 11,scrapy框架持久化存储

    今日总结 基于终端指令的持久化存储 基于管道的持久化存储 今日详情 1.基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的 ...

  6. scrapy 框架持久化存储

    1.基于终端的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表或字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. # 执行输出指定格式进行存储:将 ...

  7. 10 Scrapy框架持久化存储

    一.基于终端指令的持久化存储 保证parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 执行输出指定格式进行存储:将爬取到的 ...

  8. scrapy框架之持久化操作

    1.基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 执行输出指定格式进行存储: ...

  9. Scrapy持久化存储

    基于终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作; 执行输出指定格式进行存储:将爬 ...

随机推荐

  1. Flink开发中的问题

    1. 流与批处理的区别 流处理系统 流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一个节点,由下一个节点继续处理. 批处理系统 批处理系统, ...

  2. MyBatisPlus-常用注解

    一.@TableName 映射数据库的表名 package com.md.entity; import com.baomidou.mybatisplus.annotation.*; import co ...

  3. 个人微信公众号搭建Python实现 -个人公众号搭建-构想(14.3.1)

    @ 目录 1.需求 2.怎么做 关于作者 1.需求 个人便捷工具 2.怎么做 针对个人未认证订阅号拥有以下权限 以及微信网页的一些权限,但是由于开发微信网页有限制 可定制功能只有被动回复,以及这个素材 ...

  4. 安装nodejs 版本控制器

    安装下载地址: https://pan.baidu.com/s/1Ed_IPDTOHxR9NShUEau-ZA 下载好后,放在安装nodejs的文件夹下 然后敲cmd,进入安装nodejs的文件夹下. ...

  5. Mysql实现定时清空一张表的旧数据并保留几条数据

    要达到如下目的: Mysql数据库会每隔一段时间(可以是2小时,也可以是一天,这个可以自定义),定时对一张库中的表做一个判断,如果这张表的数据超过了20条(这个数据也是自定义的,也可以是200条),就 ...

  6. 【mybatis-plus】CRUD必备良药,mybatis的好搭档

    做开发,免不了对数据进行增删改查,那么mybatis-plus我觉得很适合我这个java新手,简单好用. 官网在这 一.什么是mybatis-plus MyBatis-Plus(简称 MP),是一个M ...

  7. ReentrantLock锁-CAS与阻塞

    ReentrantLock锁 ReentrantLock通过原子操作和阻塞实现锁原理,一般使用lock获取锁,unlock释放锁 lock的时候可能被其他线程获得所,那么此线程会阻塞自己,关键原理底层 ...

  8. 唐诗宋词APP

    古诗词个人爱好,已收集5万多首唐诗以及1万多首宋词,因时间有限目前只开发了苹果版,后期开发安卓版, <风月醉>一 国学经典,有兴趣的可以下载学习古诗词,有问题可以留言哦! https:// ...

  9. java中使用IO流将以文件中的内容去取到指定的文件中

    public class Demo12 { public static void main(String[] args) throws IOException { File file=new File ...

  10. Java面试被经常问到的常用算法

    一.冒泡排序 原理:比较两个相邻的元素,较大的放在右边 N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次 最好时间复杂度为O(N) Cmax = N(N-1)/2 = O(N2 ...