美文网首页Python爬虫程序员@IT·互联网
爬虫课堂(十九)|编写Spider之使用Item封装数据

爬虫课堂(十九)|编写Spider之使用Item封装数据

作者: 小怪聊职场 | 来源:发表于2018-03-24 07:31 被阅读0次

    在前面的章节我们学习了使用Selector提取数据,那么接下来要做的就是如何封装这些数据。以提取简书文章信息为例,我们需要获取文章标题,文章URL和文章的作者名称信息字段。应该用怎样的数据结构来封装这些零散的信息字段呢?最简单的方式就是使用Python字典(dict),如下。

    jianshu = 
    ----{
    --------'title': '文章标题', 
    --------'url': '文章URL', 
    --------'author_name':'文章的作者'
    ----}
    

    但是使用Python字典存储字段信息有如下缺点:

    • 无法一目了然地了解数据中包含哪些字段,影响代码可读性。
    • 缺乏对字段名字的检测,容易因程序员的笔误而出错。
    • 不便于携带元数据(传递给其他组件的信息)。

    为解决上述问题,在Scrapy中可以使用自定义的Item来封装数据。Item是保存结构数据的地方,Scrapy可以将解析结果以字典形式返回,但是Python中字典缺少结构,在大型爬虫系统中很不方便。Item提供了类字典的API,并且可以很方便的声明字段,很多Scrapy组件可以利用Item的其他信息。
    一、Item和Field介绍
    Scrapy提供了两个类用来封装数据:

    • Item基类
      自定义数据类的基类。
    • Field类
      用来描述自定义数据类包含哪些字段。

    定义Item非常简单,只需要继承scrapy.Item类,并将所有字段都定义为scrapy.Field类型即可。
    以获取简书文章信息为例,我们要获取文章标题,文章URL和文章的作者名称。对此,在Item中定义相应的字段。

    import scrapy
    class JianshuItem(scrapy.Item):
    ----title = scrapy.Field()
    ----url = scrapy.Field()
    ----author_name = scrapy.Field()
    

    二、Item字段(Item Fields)
    Field对象指明了每个字段的元数据(metadata)。例如下面例子中 author_name 中指明了该字段的序列化函数。

    import scrapy
    class JianshuItem(scrapy.Item):
    ----title = scrapy.Field()
    ----url = scrapy.Field()
    ----author_name = scrapy.Field(serializer=str)
    

    可以为每个字段指明任何类型的元数据, Field 对象对接受的值没有任何限制。Field 对象中保存的每个键可以由多个组件使用,并且只有这些组件知道这个键的存在。设置 Field 对象的主要目的就是在一个地方定义好所有的元数据。一般来说,那些依赖某个字段的组件肯定使用了特定的键(key)。如下例子,元数据的种类非常多。

    import scrapy
    class ExampleItem(scrapy.Item):
    # field_1有两个元数据,a是一个字符串,b是列表
    ----field_1 = scrapy.Field(a='hello', b=[1,2,3]) 
    # field_2有一个元数据,a是一个函数
    ----field_2 = scrapy.Field(a=num(1:n))
    

    至于它们在实战上是如何使用的,将在实战章节做详细讲解,目前只要了解有这些内容即可。
    三、Item Loader
    Item Loader为我们提供了生成Item的相当便利的方法。Item为抓取的数据提供了容器,而Item Loader可以让我们非常方便的将输入填充到容器中。
    下面通过一个例子来展示一般使用方法:

    from scrapy.loader import ItemLoader  
    from myproject.items import JianshuItem  
    
    def parse(self, response):  
    ----jianshu_item = ItemLoader(item=JianshuItem(), response=response)  
    ----jianshu_item.add_xpath('title', '获取对应元素的XPath表达式')  
    ----jianshu_item.add_xpath('url', '获取对应元素的XPath表达式')  
    ----jianshu_item.add_xpath('author_name', '获取对应元素的XPath表达式')  
    ----return jianshu_item.load_item()  
    

    四、扩展Item
    可以通过继承原始的Item来扩展Item(添加更多的字段或者修改某些字段的元数据)。有些时候,我们会根据需求对已有的Item进行扩展。比如我们有一个特定的爬虫需要采集这篇文章的发布时间,那么可以继承JianshuItem定义一个ParticularJianshuItem类,在其中添加一个时间的字段,代码如下:

    import scrapy
    class JianshuItem(scrapy.Item):
    ----title = scrapy.Field()
    ----url = scrapy.Field()
    ----author_name = scrapy.Field()
    
    class ParticularJianshuItem(JianshuItem):
    ----time = Field()
    

    相关文章

      网友评论

        本文标题:爬虫课堂(十九)|编写Spider之使用Item封装数据

        本文链接:https://www.haomeiwen.com/subject/xysfcftx.html