zoukankan      html  css  js  c++  java
  • Python 爬虫之Scrapy《上》

    欢迎关注【无量测试之道】公众号,回复【领取资源】,
    Python编程学习资源干货、
    Python+Appium框架APP的UI自动化、
    Python+Selenium框架Web的UI自动化、
    Python+Unittest框架API自动化、

    资源和代码 免费送啦~
    文章下方有公众号二维码,可直接微信扫一扫关注即可。

    一、什么是Scrapy

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

    二、工作流程是怎么样的

    下图是从网络上找的一张Scrapy的工作流程图,并且标注了相应的中文说明信息:

    三、Scrapy框架的六大组件

    它们分别是:

    • 调度器(Scheduler)

    • 下载器(Downloader)

    • 爬虫(Spider)

    • 中间件(Middleware)

    • 实体管道(Item Pipeline)

    • Scrapy引擎(Scrapy Engine)

    四、工作流程如下

    Step1. 当爬虫(Spider)要爬取某URL地址的页面时,使用该URL初始化Request对象提交给引擎(Scrapy Engine),并设置回调函数,Spider中初始的Request是通过调用start_requests() 来获取的。start_requests() 读取start_urls 中的URL,并以parse为回调函数生成Request 。

    备注:你所创建的项目名.py 文件里面有一个列表:start_urls=[‘http://lab.scrapyd.cn/page/1/‘] (这是我的示例),这里的start_requests() 读取的start_urls 就是来自于这里,这个文件在大家创建爬虫项目时会自动新建。parse()这个回调函数也是自动创建的。只是简单的定义了一下,如下所示:

    1 def parse(self, response):
    2     pass

    Step2. Request对象进入调度器(Scheduler) 按某种算法进行排队,之后的每个时刻调度器将其出列,送往下载器。

    备注:Scheduler的作用就是对请求的调度,包括过滤,请求的入队和出队操作。

    Step3. 下载器(Downloader)根据Request对象中的URL地址发送一次HTTP请求到网络服务器把资源下载下来,并封装成应答包(Response)。

    备注:相当于就是将获取的页面资源数据信息转化为Response实例,以便传递给Spider 的Parse() 函数继续处理。

    Step4. 应答包Response对象最终会被递送给爬虫(Spider)的页面解析函数进行处理。

    备注:这个页面解析函数就是步骤一里面提到的parse() 函数,它是创建项目时自动生成的。

    Step5. 若是解析出实体(Item),则交给实体管道(Item Pipeline)进行进一步的处理。

    由Spider返回的Item将被存到数据库(由某些Item Pipeline处理)或使用Feed exports存入到文件中。

    备注:实体(Item) 实际上就是指我们要获取的数据

    Step6. 若是解析出的是链接(URL),则把URL交给调度器(Scheduler)等待抓取。

    备注:这里有一种循环调用的感觉,解析的item如果是url就重复整个工作流程。

    五、如何安装与简单使用

    1.安装就很简单了,一条命令搞定:
    python3 -m pip install scrapy #这个可能需要花掉一段时间,如果你的网络快可能就比较快,如果你出现超时导致没有安装成功可以继续执行这个命令

    检验是否安装成功:进入python3 的命令行,输入import scrapy 如果没有报错就表示安装成功了。

    2.简单使用说明:
    Step1. 开始创建一个Scrapy 项目,我这里以爬取lab为示例
    scrapy startproject lab #创建新的Scrapy项目,注意一下,如果此命令没有你就需要配置一下Scrapy 的环境变量

    cd lab #进入创建的项目目录

    scrapy genspider labs http://lab.scrapyd.cn/page/1/ # 生成spider 代码

    Step2. 定义提取的Item

    1 class LabItem(scrapy.Item): 
    2     title = scrapy.Field()
    3     author = scrapy.Field()

    Step3. 编写解析Parse函数

     1  
     2 def parse(self, response):
     3     items=LabItem() #实例化一个数据对象,用于返回
     4     for sel in response.xpath('//div[@class="col-mb-12 col-8"]'):
     5         print(sel)
     6         for i in range(len(sel.xpath('//div[@class="quote post"]//span[@class="text"]/text()'))):
     7             title = sel.xpath('//div[@class="quote post"]//span[@class="text"]/text()')[i].get()
     8             author = sel.xpath('//div[@class="quote post"]//small[@class="author"]/text()')[i].get()
     9             items["title"]=title
    10             items["author"] = author
    11             yield items #返回提出来的每一个数据对象

    Step4. 编写Pipeline 来提取Item数据

     1  
     2 from itemadapter import ItemAdapter
     3 import json
     4  
     5 class FilePipeline(object):
     6  
     7     def open_spider(self, spider):
     8         print("当爬虫执行开始的时候回调:open_spider")
     9  
    10     def __init__(self):
    11         print("创建爬虫数据存储文件")
    12         self.file = open('test.json',"w", encoding="utf-8")
    13  
    14     def process_item(self, item, spider):
    15         print("开始处理每一条提取出来的数据")
    16         content = json.dumps(dict(item),ensure_ascii=False)+"\n"
    17         self.file.write(content)
    18         return item
    19  
    20     def close_spider(self, spider):
    21         print("当爬虫执行结束的时候回调:close_spider")
    22         self.file.close()
    23  
    24 这里是自定义的一个pipeline,所以还需要在setting.py 文件里面把它配置上,如下:
    25 ITEM_PIPELINES = {
    26    'lab.pipelines.FilePipeline': 300,
    27 }

    最终提取到文件的结果如下图所示:

    总结:今天的分享主要是从整体上讲了一下Scrapy 的工作流程,算是一个入门的学习,如果把这个流程中的一些概念性的内容能够掌握好理解到位,那么接下来的学习会更容易一些,同时基于理解的学习会更深刻。

    备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:

     添加关注,让我们一起共同成长!

  • 相关阅读:
    [Effective C++ --009]确定对象被使用前已先被初始化
    [Effective C++ --008]别让异常逃离析构函数
    [Effective C++ --007]为多态基类声明virtual析构函数
    [Effective C++ --006]若不能使用编译器自动生成的函数,就该明确拒绝
    [Effective C++ --005]了解C++默默编写并调用哪些函数
    [000]socket通信--server和client实现的简单例子
    [014]模板-模板实参推导
    [013]模板-非类型模板参数
    [012]泛型--lambda表达式捕获
    U3d keyCode值对应的按键
  • 原文地址:https://www.cnblogs.com/Wu13241454771/p/13571849.html
Copyright © 2011-2022 走看看