1. Items
爬虫的主要任务就是从非结构化的数据中获得结构化的数据。
Item 对象是种简单的容器,保存了爬取到得数据。 其提供了 类似于词典(dictionary-like) 的API以及用于声明可用字段的简单语法。
声明Item
Item使用简单的class定义语法以及 Field 对象来声明。例如:
import scrapy
class Product(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
last_updated = scrapy.Field(serializer=str)
Item字段:
Field 对象指明了每个字段的元数据(metadata)。例如上面例子中 last_updated 中指明了该字段的序列化函数。
可以为每个字段指明任何类型的元数据。Field 对象对接受的值没有任何限制。Field 对象中保存的每个键可以由多个组件使用,并且只有这些组件知道这个键的存在。设置 Field 对象的主要目的就是在一个地方定义好所有的元数据。
需要注意的是,用来声明item的 Field 对象并没有被赋值为class的属性。 不过您可以通过 Item.fields 属性进行访问。
2. 用Item Loader来填充Item
Item Loaders提供了一种便捷的方式填充抓取到的 Items 。 虽然Items可以使用自带的类字典形式API填充,但是Items Loaders提供了更便捷的API, 可以分析原始数据并对Item进行赋值。
从另一方面来说, Items 提供保存抓取数据的 容器 , 而 Item Loaders提供的是 填充 容器的机制。
Item Loaders提供的是一种灵活,高效的机制,可以更方便的被spider或source format (HTML, XML, etc)扩展,并override更易于维护的、不同的内容分析规则。
要使用Item Loader, 你必须先将它实例化. 可以使用类似字典的对象来进行实例化, 或者不使用对象也可以, 当不用对象进行实例化的时候,Item会自动使用 ItemLoader.default_item_class 属性中指定的Item 类在Item Loader constructor中实例化.
然后,你开始收集数值到Item Loader时,通常使用 Selectors. 你可以在同一个item field 里面添加多个数值;Item Loader将知道如何用合适的处理函数来“添加”这些数值.
下面是在 Spider 中典型的Item Loader的用法, 使用 Items chapter 中声明的 Product item:
from scrapy.contrib.loader import ItemLoader
from myproject.items import Product
def parse(self, response):
l = ItemLoader(item=Product(), response=response)
l.add_xpath('name', '//div[@class="product_name"]')
l.add_xpath('name', '//div[@class="product_title"]')
l.add_xpath('price', '//p[@id="price"]')
l.add_css('stock', 'p#stock]')
l.add_value('last_updated', 'today') # you can also use literal values
return l.load_item()
我们可以看到发现 name 字段被从页面中两个不同的XPath位置提取:
//div[@class="product_name"]
//div[@class="product_title"]
换言之,数据通过用 add_xpath()
的方法,把从两个不同的XPath位置提取的数据收集起来. 这是将在以后分配给 name
字段中的数据。
之后,类似的请求被用于 price
和 stock
字段 (后者使用 CSS selector 和 add_css()
方法), 最后使用不同的方法 add_value()
对 last_update
填