Scrapy : Items

Items

抓取的目标就是从非结构化资源中提取出来结构化数据,尤其使网站页面,scrapy 爬虫可以以python 字典的形式提取数据。虽然字典很方便和熟悉,但是缺少结构:很容易就会输入错别字或者返回不一致的数据,特别实在有很多爬虫的大型项目中

scrapy 提供了 Item 类来定义通常的输出数据格式,Item 对象是一个简单的容器用来收集抓取的数据。它们提供了一个跟字典API 相似的API ,并有方便的语法来声明可用的字段

各种scrapy 组件使用item 提供的额外的信息,导出器查看声明字段来找出需要导出的列,使用item 字段的元数据可用自定义序列化,trckref 跟踪item 示例帮助寻找内存流失。

Declaring Items

tems 使用简单的类定义和Field 对象来声明

import scrapy

class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field()
    stock = scrapy.Field()
    tags = scrapy.Field()
    last_updated = scrapy.Field(serializer=str)

Note

更 django 差不多,但是更加简单没了不同字段种类的概念。

Item Fields

Field 对象用来为每个字段指定元数据。例如,上面说明的 last_updated 字段的序列化函数

你可以为每一个字段指定任何种类的元数据。Field 对象接受的值没有限制,同样的原因,没有所有可使用元数据关键字的参考列表。定义在field 对象里的每一个关键字都可以在不同组件中使用,并且只有这些组件知道。你也可以定义使用其他的field 关键字在你的项目中,来适应你的需要。 field 对象的目的时提供定义所有字段元数据在同一个位置的方法。通常,依靠字段来指定组件的行为,并通过某些字段的关键字来配置这些行为。你必须参考他们的文档来看看每个组件元数据的关键字。

注意,用于声明 item 的 Field 对象不用保存分配作为类的属性,他们可以通过 item.fields 属性来访问

Working with Items

Here are some examples of common tasks performed with items, using the Product item declared above. You will notice the API is very similar to the dict API. # 确实跟字典一个样。。。

Creating items

>>> product = Product(name='Desktop PC', price=1000)
>>> print(product)
Product(name='Desktop PC', price=1000)

Getting field values

>>> product['name']
Desktop PC
>>> product.get('name')
Desktop PC
>>> product['price']
1000
>>> product['last_updated']
Traceback (most recent call last):
    ...
KeyError: 'last_updated'
>>> product.get('last_updated', 'not set')
not set
>>> product['lala'] # getting unknown field
Traceback (most recent call last):
    ...
KeyError: 'lala'
>>> product.get('lala', 'unknown field')
'unknown field'
>>> 'name' in product  # is name field populated?
True
>>> 'last_updated' in product  # is last_updated populated?
False
>>> 'last_updated' in product.fields  # is last_updated a declared field?
True
>>> 'lala' in product.fields  # is lala a declared field?
False

Setting field values

>>> product['last_updated'] = 'today'
>>> product['last_updated']
today
>>> product['lala'] = 'test' # setting unknown field
Traceback (most recent call last):
    ...
KeyError: 'Product does not support field: lala'

Accessing all populated values

To access all populated values, just use the typical dict API:

扫描二维码关注公众号,回复: 11307397 查看本文章
>>> product.keys()
['price', 'name']
>>> product.items()
[('price', 1000), ('name', 'Desktop PC')]

Copying items

再复制 item 前,你要决定是浅复制还是深复制。

如果你的item 包含了可变值像列表或字典,浅复制可以再所有不同副本里保留对相同可变值的引用。

例如,如果你有一个列表的标签的item ,你对这个item进行浅复制,原来的item和辅助的都有同样标签的列表,给其中一个增加一个标签,另一个也会增加一个。

如果没有想要的行为,使用深复制

See copy for more information.

对item的浅复制,你可以使用copy()再一个现有的item(product2=product.copy())或你的item的一个实例(product2=Product(product))。

深复制,调用 deepcopy() (prodect2=product.deepcopy())

Other common tasks

Creating dicts from items:

>>> dict(product) # create a dict from all populated values
{'price': 1000, 'name': 'Desktop PC'}

Creating items from dicts:

>>> Product({'name': 'Laptop PC', 'price': 1500})
Product(price=1500, name='Laptop PC')
>>> Product({'name': 'Laptop PC', 'lala': 1500}) # warning: unknown field in dict
Traceback (most recent call last):
    ...
KeyError: 'Product does not support field: lala'

Extending Items

你可以扩展 items (增加更多的 fields 或为一些 fields 改变元数据)通过声明你原来item 的子类

For example:

class DiscountedProduct(Product):
    discount_percent = scrapy.Field(serializer=str)
    discount_expiration_date = scrapy.Field()

还可以通过使用原来的 field元数据扩展 field的元数据并且添加更多值或改变已有的值。

class SpecificProduct(Product):
    name = scrapy.Field(Product.fields['name'], serializer=my_serializer)

为name field 增加(或替换)serializer 元数据的键,保留了原来有的元数据的值

Item objects

  • class scrapy.item.Item([arg])

    返回一个新的item ,从所给的参数选择性初始化

    items 复制标准 dict 的API,包括他的 _init_ 方法,并提供一些格外的API 成员。

    copy()

    deepcopy()

    Return a deepcopy() of this item.

    fields

    一个字典,包含了这个item 所有声明的 fields,不仅是这些的填充,关键字是fields的名字,值是在item声明中使用的 field对象

Field objects

  • class srapy.item.Field([arg])

Field 类就是内置 dict 类的别名,不提供任何格外的应用和参数,也就是说 Field 就是普通的字典。一个分离的类来支持基于类属性的项目声明语法。

Other classes related to Item

  • class scrapy.item.BaseItem[source]

    所有 scraped items 的基本类

在 scrapy中,如果一个类是 BaseItem or dict 的实例,就认为是一个item。例如:当评估爬虫回调的输出内容时,仅将 baseitem or dict的实例传递给 piplines

如果你需要某些其他的类被当作 item,你必须继承 baseitem or dict

Unlike instances of dict, instances of BaseItem may be tracked to debug memory leaks.

猜你喜欢

转载自blog.csdn.net/weixin_46192930/article/details/106597819