• scrapy快速入门


    1. 什么是scrapy?

      其官网是这样简述的,“A Fast & Powerful Scraping &Crawling Framework ”,  并且其底层以twisted作为网络架构( Python实现的基于事件驱动的网络引擎框架),所以爬取效率及性能出色。

      定义·:Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试

    2. scrapy模块执行与通信流程

      2.1 流程图:

        

      2.2 各大组件的作用:

        引擎 (Scrapy Engine):用来处理整个系统的数据流,触发事物(框架核心)

        调度器 (Scheduler):用来接收引擎发送的请求,压入请求队列中,并在引擎再次请求的时候返回,可以想象成一个url(待爬取网页的url)的优先队列,由他决定下一个要抓取的网址是什么,同时去除重复的网址

        下载器 (Downloader):顾名思义,用于下载网页代码,并将结果返回给spider

        爬虫 (Spiders): 蜘蛛呢,就是执行者,用于解析网页中的信息,即实体(Item)

        项目管 道(Pipeline): 负责处理爬虫从网页中抽取的实体,主要功能是持久化实体,验证实体的有效性,清除不需要的信息。当爬虫被解析后,将被发送至项目管道,并经过几个特定次序来处理数据

        下载中间件 (Downloader Middlewares): 位于Engine及Spider之间的框架,主要工作是处理scrapy engine与Downloader之间的请求及响应

        爬虫中间件 (Spider Middlewares): 位于Engine及Spider之间的框架,主要工作是处理scrapy engine与spider之间的响应输入及请求输出

        调度中间件 (Schedule Middlewares): 介于scrapy engine及scheduler之间的中间件,处理从scrapy engine发送到scheduler的请求响应

     

       2.3 是不是感觉一头雾水,那我们直接上过程就很清楚啦

    3. scrapy的基本使用

      3.1 安装

    # 这里我们用conda创建一个名为rawling_py36的虚拟环境
    conda create --name crawling_py36 python=3.6
    
    # 进入环境
    activate crawling_py36
    
    # 安装scrapy
    conda install scrapy
    
    # 退出当前环境(windows)
    deactivate 

       说明:也可以使用pip install scrapy命令进行安装, 但是在windows平台下, scrapy依赖pypiwin32模块,在执行pip install scrapy命令前,请先执行pip install pypiwin32

       3.2 开始(这里以爬取糗事百科段子为例

        a. 新建项目

    # 新建一个文件夹 并进入文件夹
    mkdir spider_projects
    cd ./spider_projects
    
    # 进入虚拟环境
    activate crawling_py36
    
    # 新建爬虫项目,
    scrapy startproject qsbk
    
    #提示成功

        b.新建爬虫

         

        其域名为qiushibaike.com,我们这里根据域名新建一个spider

    # 一定要在项目文件夹下
    cd qsbk
    
    scrapy genspider qsbk_spider qiushibaike.com

        成功之后,其文件树结构为:

        

        c. 分析网页结构(https://www.qiushibaike.com/text/

        

         那么红圈里的div就是当前页的所有段子信息,我们使用xpath进行解析,那么每一个段子的xpath语法为    //div[@id='content-left']/div[contains(@class,'article')]

         

         提取下一页的地址的xpath语法为    //ul[@class='pagination']/li[last()]/a/@href

         

        d. 开始

        爬虫配置 (settings.py): 

     1 # Obey robots.txt rules
     2 ROBOTSTXT_OBEY = False
     3 
     4 # Override the default request headers:
     5 DEFAULT_REQUEST_HEADERS = {
     6   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
     7   'Accept-Language': 'en',
     8   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
     9 }
    10 
    11 
    12 # Configure item pipelines
    13 # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    14 ITEM_PIPELINES = {
    15    'qsbk.pipelines.QsbkPipeline': 300,
    16 }

        解析数据(qsbk_spider.py):

     1 # -*- coding: utf-8 -*-
     2 import scrapy
     3 from ..items import QsbkItem
     4 
     5 
     6 class QsbkSpiderSpider(scrapy.Spider):
     7     name = 'qsbk_spider'
     8     allowed_domains = ['qiushibaike.com']
     9     start_urls = ['https://www.qiushibaike.com/text/page/1/']
    10     base_domain = "https://www.qiushibaike.com"
    11 
    12     def parse(self, response):
    13         # 获取所有段子信息
    14         texts = response.xpath("//div[@id='content-left']/div[contains(@class, 'article')]")
    15         # 提取单个段子信息
    16         for text in texts:
    17             author_info = text.xpath("./div[contains(@class,'author')]")
    18             head_img = 'http:' + author_info.xpath(".//img/@src").get().strip()
    19             author_name = author_info.xpath(".//h2/text()").get().strip()
    20             content_list = text.xpath(".//div[@class='content']/span/text()").getall()
    21             content = ''.join(content_list).strip()
    22 
    23             article_item = QsbkItem(author_name=author_name, head_img=head_img, content=content)
    24 
    25             yield article_item
    26 
    27         # 下一页的地址
    28         next_page_url = response.xpath("//ul[@class='pagination']/li[last()]/a/@href").get()
    29 
    30         if next_page_url:
    31             yield scrapy.Request(url=self.base_domain+next_page_url, callback=self.parse)
    32         else:
    33             return

        结构化实体(items.py):

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

        持久化数据(pipelines.py):

     1 # -*- coding: utf-8 -*-
     2 
     3 # Define your item pipelines here
     4 #
     5 # Don't forget to add your pipeline to the ITEM_PIPELINES setting
     6 # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
     7 
     8 # import json
     9 # class QsbkPipeline(object):
    10 #
    11 #     def open_spider(self, spider):
    12 #         print('start crawling....')
    13 #         self.file = open('qsbk.json','w' , encoding='utf-8')
    14 #
    15 #     def process_item(self, item, spider):
    16 #         item_json = json.dumps(dict(item), ensure_ascii=False)
    17 #         self.file.write(item_json+'
    ')
    18 #         return item
    19 #
    20 #     def close_spider(self, spider):
    21 #         self.file.close()
    22 #         print('stop crawling.....')
    23 
    24 # 一次性写入
    25 # from scrapy.exporters import JsonItemExporter, JsonLinesItemExporter
    26 # class QsbkPipeline(object):
    27 #
    28 #     def open_spider(self, spider):
    29 #         print('start crawling....')
    30 #         self.file = open('qsbk.json', 'wb')
    31 #         self.exporter = JsonItemExporter(self.file, ensure_ascii=False)
    32 #         self.exporter.start_exporting()
    33 #
    34 #     def process_item(self, item, spider):
    35 #         self.exporter.export_item(item)
    36 #
    37 #     def close_spider(self, spider):
    38 #         self.exporter.finish_exporting()
    39 #         self.file.close()
    40 #         print('stop crawling.....')
    41 
    42 # 分行写入,(在数据量很大的时候推荐使用)
    43 from scrapy.exporters import JsonLinesItemExporter
    44 class QsbkPipeline(object):
    45 
    46     def open_spider(self, spider):
    47         print('start crawling....')
    48         self.file = open('qsbk.json', 'wb')
    49         self.exporter = JsonLinesItemExporter(self.file, ensure_ascii=False)
    50 
    51     def process_item(self, item, spider):
    52         self.exporter.export_item(item)
    53         return item
    54 
    55     def close_spider(self, spider):
    56         self.file.close()
    57         print('stop crawling.....')

       说明: 为了避免每次爬取使用命令行,可以在项目根目录下新建   run.py 代替命令行执行, 而scrapy也同样提供了执行cmd命令这一模块

      启动爬虫(run.py

    1 from scrapy import cmdline
    2 
    3 cmdline.execute("scrapy crawl qsbk_spider".split())

       e.爬取结束(qsbk.json)  

              

  • 相关阅读:
    MySQL 中now()时间戳用法
    ajax local.href不跳转的原因之一
    Call to a member function select() on string错误
    TP框架中ajax post请求时提示404
    TP框架中field查询字段
    jQuery如何获得select选中的值?input单选radio选中的值
    TP框架中session操作
    InnerHtml() 与html( )的区别
    C++开源项目等收集
    RCU-数据库初始化参数
  • 原文地址:https://www.cnblogs.com/kisun168/p/10865192.html
Copyright © 2020-2023  润新知