上QQ阅读APP看书,第一时间看更新
4.1 Item和Field
Scrapy提供了以下两个类,用户可以使用它们自定义数据类(如书籍信息),封装爬取到的数据:
● Item基类
自定义数据类(如BookItem)的基类。
● Field类
用来描述自定义数据类包含哪些字段(如name、price等)。
自定义一个数据类,只需继承Item,并创建一系列Field对象的类属性(类似于在Django中自定义Model)即可。以定义书籍信息BookItem为例,它包含两个字段,分别为书的名字name和书的价格price,代码如下:
>>> from scrapy import Item, Field >>> class BookItem(Item): ... name=Field() ... price=Field()
Item支持字典接口,因此BookItem在使用上和Python字典类似,可按以下方式创建BookItem对象:
>>> book1 = BookItem(name='Needful Things', price=45.0) >>> book1 {'name': 'Needful Things', 'price': 45.0} >>> book2 = BookItem() >>> book2 {} >>> book2['name'] = 'Life of Pi' >>> book2['price'] = 32.5 {'name': 'Life of Pi', 'price': 32.5}
对字段进行赋值时,BookItem内部会对字段名进行检测,如果赋值一个没有定义的字段,就会抛出异常(防止因用户粗心而导致错误):
>>> book = BookItem() >>> book['name'] = 'Memoirs of a Geisha' >>>book['prize']=43.0 # 粗心,把price拼写成了prize. Traceback (most recent call last): ... KeyError: 'BookItem does not support field: prize'
访问BookItem对象中的字段与访问字典类似,示例如下:
>>> book = BookItem(name='Needful Things', price=45.0) >>> book['name'] 'Needful Things' >>> book.get('price', 60.0) 45.0 >>> list(book.items()) [('price', 45.0), ('name', 'Needful Things')]
接下来,我们改写第1章example项目中的代码,使用Item和Field定义BookItem类,用其封装爬取到的书籍信息项目目录下的items.py文件供用户实现各种自定义的数据类,在items.py中实现BookItem,代码如下:
from scrapy import Item, Field class BookItem(Item): name = Field() price = Field()
修改之前的BooksSpider,使用BookItem替代Python字典,代码如下:
from ..items import BookItem class BooksSpider(scrapy.Spider): ... def parse(self, response): for sel in response.css('article.product_pod'): book = BookItem() book['name'] = sel.xpath('./h3/a/@title').extract_first() book['price'] = sel.css('p.price_color::text').extract_first() yield book ...