Scrapy-Item对象

熟悉Django的人会注意到 Scrapy Items 的声明类似于Django Models,只是 Scrapy Items 更简单,因为没有不同字段类型的概念。

Item提供了类似dict的 API 以及其他功能,使其成为功能最完整的项目类型:

一、使用 Item 对象

声明项目子类

项目子类使用简单的类定义语法和 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)
创建项目
>>> product = Product(name='Desktop PC', price=1000)
>>> print(product)
{'name': 'Desktop PC', 'price': 1000}
获取字段值
>>> 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'] 
Traceback (most recent call last):
    ...
KeyError: 'lala'
>>> product.get('lala', 'unknown field')
'unknown field'
>>> 'name' in product # product中是否存在name字段
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
设置字段值
>>> product['last_updated'] = 'today'
>>> product['last_updated']
today
>>> product['lala'] = 'test' 
Traceback (most recent call last):
    ...
KeyError: 'Product does not support field: lala'
访问所有填充的值

要访问所有填充的值,只需使用典型的dictAPI:

>>> product.keys()
['price', 'name']
>>> product.items()
[('price', 1000), ('name', 'Desktop PC')]
复制项目

要创建项目的浅表副本,您可以调用 copy()现有项目 实例化项目类。

product2 = product.copy()

要创建深层副本,请deepcopy()改为调用。

product2 = product.deepcopy()

从item创建字典:
>>> dict(product) 
{'price': 1000, 'name': 'Desktop PC'}
从字典创建item:
>>> Product({'name': 'Laptop PC', 'price': 1500})
Product(price=1500, name='Laptop PC')
>>> Product({'name': 'Laptop PC', 'lala': 1500}) 
Traceback (most recent call last):
    ...
KeyError: 'Product does not support field: lala'

二、使用ItemLoader

我们上面的item其实就上面的功能来看,emmm,是吧,和字典没啥区别,甚至更加的繁琐了

我们有了itemloader就知道,这样写是为了后期的维护。

from scrapy.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')
    return l.load_item()

三、Item Pipeline

Spider中返回一个Item后,这个Item将会被发送给Item Pipeline,每个Item Pipeline都是一个Python类,实现了几个简单的方法。其主要有以下几种作用:

  1. 清洗数据
  2. 验证抓取下来的数据(检查是否含有某些字段)
  3. 检查去重
  4. 存储数据
process_item(self, item, spider)

每一个Item Pipeline都会调用这个方法,用来处理Item,返回值为item或dict。

这个方法还可以抛出一个DropItem异常,这样将会不再继续调用接下来的Item Pipeline。

参数item(Item对象或者Dict) 是parse方法传来的。

参数spider(Spider对象) - 抓取这个Item的Spider。

open_spider(self, spider)

这个方法将会在Spider打开时调用。

close_spider(self, spider)

这个方法将会在Spider关闭时调用。

四、实例

我们这里举个例子,存储item的实例

class Job2_Tenxun(scrapy.Spider):
    name = 'job2'
    start_urls = ['https://hr.tencent.com/position.php?keywords=python',]
    def parse(self, response):
        item = MyItem()
        res = response.xpath("//tr[@class='even']|//tr[@class='odd']")
        for tr in res:
            item['job_name'] = tr.xpath("./td[1]/a/text()").extract_first()
            item['job_label'] = tr.xpath("./td[2]/text()").extract_first()
            item['num'] = tr.xpath("./td[3]/text()").extract_first()
            yield  item
        next_url = response.xpath("//a[@id='next']/@href").extract_first()
        yield scrapy.Request('https://hr.tencent.com/%s'%next_url)
class MyItem(scrapy.Item):
    job_name = scrapy.Field()
    job_label = scrapy.Field()
    num = scrapy.Field()
import json
class MyPipeline(object):
    def open_spider(self,spider):
        self.f = open('job2.json','w',encoding='utf-8')
    def process_item(self, item, spider):
        self.f.write(json.dumps(dict(item),ensure_ascii=False))
        self.f.write('\n')
        return item
    def close_spider(self,spider):
        self.f.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LyaJpunov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值