• 05 爬虫之scrapy


    一 scrapy框架简介

    01 什么是scrapy:

     Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性的项目模板。对于框架的学习,重点是要学习其框架的特性、各个功能的用法即可。

    Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。

    整体架构大致如下:

             

                          

    流程解释:

    1,spider打开某网页,获取到一个或者多个request,经由scrapy engine传送给调度器scheduler
      request特别多并且速度特别快会在scheduler形成请求队列queue,由scheduler安排执行
    2,schelduler会按照一定的次序取出请求,经由引擎, 下载器中间键,发送给下载器dowmloader
      这里的下载器中间键是设定在请求执行前,因此可以设定代理,请求头,cookie等
    3,下载下来的网页数据再次经过下载器中间键,经过引擎,经过爬虫中间键传送给爬虫spiders
      这里的下载器中间键是设定在请求执行后,因此可以修改请求的结果
      这里的爬虫中间键是设定在数据或者请求到达爬虫之前,与下载器中间键有类似的功能
    4,由爬虫spider对下载下来的数据进行解析,按照item设定的数据结构经由爬虫中间键,引擎发送给项目管道itempipeline
      这里的项目管道itempipeline可以对数据进行进一步的清洗,存储等操作
      这里爬虫极有可能从数据中解析到进一步的请求request,它会把请求经由引擎重新发送给调度器shelduler,调度器循环执行上述操作
    5,项目管道itempipeline管理着最后的输出
    

      

    常用组件解释:

    1、引擎(EGINE)
    引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。
    
    2、调度器(SCHEDULER)
    用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
    
    3、下载器(DOWLOADER)
    用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的
    
    4、爬虫(SPIDERS)
    SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求
    
    5、项目管道(ITEM PIPLINES)
    在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作
    下载器中间件(Downloader Middlewares)位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,
    你可用该中间件做以下几件事:
        (1) process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
        (2) change received response before passing it to a spider;
        (3) send a new Request instead of passing received response to a spider;
        (4) pass response to a spider without fetching a web page;
        (5) silently drop some requests.
    
    6、爬虫中间件(Spider Middlewares)
    位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)
    View Code

    02 scrapy的安装

     #Linux:
    
          pip3 install scrapy
    
      #Windows:
    
          a. pip3 install wheel
    
          b. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
    
          c. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl
    
          d. pip3 install pywin32
    
          e. pip3 install scrapy

    03 常用命令

     1 # 1 查看帮助
     2     scrapy -h
     3     scrapy <command> -h
     4 
     5 # 2 有两种命令:其中Project-only必须切到项目文件夹下才能执行,而Global的命令则不需要
     6     Global commands:
     7         startproject #创建项目
     8         genspider    #创建爬虫程序
     9         settings     #如果是在项目目录下,则得到的是该项目的配置
    10         runspider    #运行一个独立的python文件,不必创建项目
    11         shell        #scrapy shell url地址  在交互式调试,如选择器规则正确与否
    12         fetch        #独立于程单纯地爬取一个页面,可以拿到请求头
    13         view         #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求
    14         version      #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本
    15     Project-only commands:
    16         crawl        #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = False
    17         check        #检测项目中有无语法错误
    18         list         #列出项目中所包含的爬虫名
    19         edit         #编辑器,一般不用
    20         parse        #scrapy parse url地址 --callback 回调函数  #以此可以验证我们的回调函数是否正确
    21         bench        #scrapy bentch压力测试
    22 
    23 # 3 官网链接
    24     https://docs.scrapy.org/en/latest/topics/commands.html
    View Code

    特别注意:

    创建项目: scrapy startproject  名称
    
    创建新业务: 会先提醒进入项目 cd 项目名称
    创建业务指令: scrapy genspider 业务名称 域名
    
    运行程序:
    scrapy crawl 业务名称
    scrapy crawl 爬虫名称 --nolog:该种执行形式不会显示执行的日志信息

    小项目:爬取糗事百科文章笑话:

    spider:qiubai.py

     1 # -*- coding: utf-8 -*-
     2 import scrapy
     3 from ..items import QiubaiItem
     4 
     5 
     6 
     7 class QiubaiSpider(scrapy.Spider):
     8     name = 'qiubai'
     9     allowed_domains = ['www.qiushibaike.com']
    10     start_urls = ['http://www.qiushibaike.com/']
    11 
    12 
    13     def start_requests(self):
    14         url = "https://www.qiushibaike.com/text/"
    15         request = scrapy.Request(url)
    16         yield request
    17 
    18 
    19     def parse(self, response):
    20         print(">>>", response)
    21         contents = response.xpath('//*[@id="content-left"]/div')
    22         data=[]
    23         for item in contents:
    24             dic={}
    25             author = item.xpath('.//*[@class="author clearfix"]/*[2]/h2/text()').extract()[0].strip()
    26             content = item.xpath('.//*[@class="contentHerf"]/div/span/text()').extract()[0].strip()
    27             # data.append(
    28             #     {"author":author,
    29             #     "content":content}
    30             # )
    31             item = QiubaiItem()  #实例化QiubaiItem() 以获得统一的命名格式
    32             item["author"] = author
    33             item["content"] = content
    34             yield item
    View Code

    items:

    import scrapy
    
    
    class QiubaiItem(scrapy.Item):
        # define the fields for your item here like:
        author = scrapy.Field()
        content = scrapy.Field()
    View Code

    pipeline:

    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    #
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    import pymongo
    
    注意,若采用双管道存放数据的话要去settings 更改 ITEM_PIPELINES,并设置优先级
    此时更改示例如:
    ITEM_PIPELINES = {
       'QiuBai.pipelines.QiubaiMongoPipeline': 500,
       'QiuBai.pipelines.QiubaiFilePipeline': 300, # 优先级越小越高
    }
    
    
    # 管道一:将数据存入数据库
    class QiubaiMongoPipeline(object):    # def parse(self, response) 会将获得的数据通过yield data传到此处
    
        def open_spider(self, spider):
            print("爬虫开始....")
        def close_spider(self, spider):
            print("爬虫结束...")
        def process_item(self, item, spider):
            print("mongo....")
            # 1 连接mongo数据库(确保数据库是开着的)
            client = pymongo.MongoClient(host='localhost', port=27017)
            # 2 获取数据库以及集合
            db = client.spider
    
            if dict(item):
                 db.qiubai.save(dict(item))
            # 清洗数据,校验数据,存储到数据库
            return item
    
    
    # 管道二:将数据存入文档中
    class QiubaiFilePipeline(object):
    
        # @classmethod
        # def from_crawler(cls, crawler):
        #     pass
        def open_spider(self, spider):    #会在爬虫程序开始前启动
            print("QiubaiFilePipeline开始....")
        def close_spider(self, spider):     #会在爬虫程序结束后启动
            print("QiubaiFilePipeline结束...")
    
        def process_item(self, item, spider):
            print("file....")
            import json
            with open("qiubai.txt","a",encoding="utf8") as f:
                f.write(json.dumps(dict(item),ensure_ascii=False)+"
    ")
            return item
    View Code

    以下是scrapy常用几个模块:

    Spider:

      Spiders是定义如何抓取某个站点(或一组站点)的类,包括如何执行爬行(即跟随链接)以及如何从其页面中提取结构化数据(即抓取项目)。换句话说,Spiders是您为特定站点(或者在某些情况下,一组站点)爬网和解析页面定义自定义行为的地方。

    1、 生成初始的Requests来爬取第一个URLS,并且标识一个回调函数
         第一个请求定义在start_requests()方法内默认从start_urls列表中获得url地址来生成Request请求,
         默认的回调函数是parse方法。回调函数在下载完成返回response时自动触发
    
    2、 在回调函数中,解析response并且返回值
         返回值可以4种:
              包含解析数据的字典
              Item对象
              新的Request对象(新的Requests也需要指定一个回调函数)
              或者是可迭代对象(包含Items或Request)
    
    3、在回调函数中解析页面内容
       通常使用Scrapy自带的Selectors,但很明显你也可以使用Beutifulsoup,lxml或其他你爱用啥用啥。
    
    4、最后,针对返回的Items对象将会被持久化到数据库
       通过Item Pipeline组件存到数据库:https://docs.scrapy.org/en/latest/topics/item-pipeline.html#topics-item-pipeline)
       或者导出到不同的文件(通过Feed exports:https://docs.scrapy.org/en/latest/topics/feed-exports.html#topics-feed-exports)

    还有pipeline,items,等

    详见:https://www.cnblogs.com/pyedu/p/10314215.html

  • 相关阅读:
    剑指offer(29):最小的K个数(pop_heap函数的使用)
    C++ partition(STL partition)算法使用
    rvm离线安装
    解决redis requires ruby version 2.3.0
    vim 中如何替换选中行或指定几行内的文本
    Vue.js框架:官方命令行工具的安装和使用(三)
    Node.js:windows下安装配置(一)
    Redis开发:windows下的redis安装记录(一)
    Vue.js框架:计算属性computed的用法(二)
    面试知识(一)
  • 原文地址:https://www.cnblogs.com/Mixtea/p/10486470.html
Copyright © 2020-2023  润新知