【Scrapy Item和Item Loaders】基本使用和以及Item Loaders(项目加载器)的基本使用

                                        Item的基本使用

        Item是保存结构数据的地方,Scrapy可以将解析结果以字典形式返回,但是Python中字典缺少结构,在大型爬虫系统中很不方便。  Item提供了类字典的API,并且可以很方便的声明字段,很多Scrapy组件可以利用Item的其他信息。基本的使用方法如下:

import scrapy
class MovieItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()

        Field对象可用来对每个字段指定元数据。例如上面last_updated的序列化函数指定为str,可任意指定元数据,不过每种元数据对于不同的组件意义不一样。

        访问item中的值,就如访问字典值一样,如下:

#设置值的方法
product['last_updated'] = 'today'

#访问值得方法

>>> product['last_updated']
today

>>> product.keys()
['price', 'name']

>>> product.items()
[('price', 1000), ('name', 'Desktop PC')]

>>> product.get('name')
Desktop PC

                                      Item Loader的基本使用

        Item Loader为我们提供了生成Item的相当便利的方法。Item为抓取的数据提供了容器,而Item Loader可以让我们非常方便的将输入填充到容器中。

       Item Loaders(项目加载器),意义,当项目很大的时候,提取的字段数以百计,做维护是很困难的。
       所以scrapy就提供了ItemLoader这样一个容器,在这个容器里面可以配置item中各个字段的提取规则。可以通过函数分析原始数据,并对Item字段进行赋值,非常的便捷。参考网站:https://blog.csdn.net/zwq912318834/article/details/79530828
       可以这么来看 Item 和 Itemloader:Item提供保存抓取到数据的容器,而 Itemloader提供的是填充容器的机制。
       Itemloader提供的是一种灵活,高效的机制,可以更方便的被spider或source format (HTML, XML, etc)扩展并重写,更易于维护,尤其是分析规则特别复杂繁多的时候。

 

一般地使用方法,在爬虫.py文件中使用:

from scrapy.loader import ItemLoader
#从items中调用Product的类
from myproject.items import Product
def parse(self, response):
    #ItemLoader中的参数包含两个参数,第一个是引入的类,第二个是浏览器响应的结果
    l = ItemLoader(item=Product(), response=response)
    #这个是三种字段的添加方法
    l.add_xpath('name', '//div[@class="product_name"]')
    l.add_css('stock', 'p#stock]')
    l.add_value('last_updated', 'today') # you can also use literal values
    #添加load_item()来提交字段
    return l.load_item()填充到容器中

在item.py中可以自定义字段:

有两种方法,第一种是在item自定义Itemloader类中添加

from scrapy.loader import ItemLoader
#Identity、TakeFirst、Join、Compose、MapCompose、SelectJmes都是内置的处理器
from scrapy.loader.processors import TakeFirst, MapCompose, Join

class ProductLoader(ItemLoader):
    #定义默认的ItemLoader.default_input_processor和ItemLoader.default_input_processor
    default_output_processor = TakeFirst()
    #通过_in和_out后缀来定义输入和输出处理器
    name_in = MapCompose(unicode.title)
    name_out = Join()
    price_in = MapCompose(unicode.strip)

第二种方式是在item文件Field方法定义中添加

import scrapy
#Identity、TakeFirst、Join、Compose、MapCompose、SelectJmes都是内置的处理器
from scrapy.loader.processors import Join, MapCompose, TakeFirst
from w3lib.html import remove_tags

def filter_price(value):
    if value.isdigit():
        return value

class Product(scrapy.Item):
    name = scrapy.Field(
        input_processor=MapCompose(remove_tags),
        output_processor=Join(),
    )
    price = scrapy.Field(
        input_processor=MapCompose(remove_tags, filter_price),
        output_processor=TakeFirst(),
    )

                       ItemLoader的存入item的方式,以及输出到pipeline的方式

ItemLoader    包含的两个东西:

(1)输入处理器(input_processor) ,当这个item,title这个字段的值传过来时,可以在传进来的值上面做一些预处理。
(2)输出处理器(output_processor) , 当这个item,title这个字段被预处理完之后,输出前最后的一步处理。
总结一下,每个字段的数据的处理过程是:

       第一步, 通过 add_xpath(), add_css() 或者 add_value() 方法),提取到数据。
       第二步,将提取到的数据,传递到输入处理器(input_processor)中进行处理,处理结果被收集起来,并且保存在ItemLoader内(但尚未分配给该Item)。
       第三步,最后调用输出处理器(output_processor)来处理之前收集到的数据(这是最后一步对数据的处理)。然后再存入到Item中,输出处理器的结果是被分配到Item的最终值。
       第四步,收集到所有的数据后, 调用ItemLoader.load_item() 方法来填充,并得到填充后的 Item 对象。

 实例1:      关于ItemLoader中的输入输出问题,如果itemloader存入的是一个列表型数据,类似['字符串','字符串','字符串','字符串'],输入方式如下:

# -*- coding: utf-8 -*-
import scrapy
import re
from scrapy.loader import ItemLoader
from LianjiaScrapy.items import Lianjia1scrapyItem

class TestSpider(scrapy.Spider):
    name = 'test'
    #allowed_domains = ['www.lianjia.com']
    start_urls = ['https://sh.lianjia.com/zufang/jingan/rt200600000001l0/#contentList']

    def parse(self, response):
        item1Loader=ItemLoader(item=Lianjia1scrapyItem(),response=response)
        item1Loader.add_xpath('area','.//p[@class="content__list--item--des"]/a[1]//text()')
        item1Loader.add_xpath('Community','.//p[@class="content__list--item--des"]/a[2]//text()')
        item1Loader.add_xpath('village','.//p[@class="content__list--item--des"]/a[3]//text()')
        item1Loader.add_xpath('price','.//span[@class="content__list--item-price"]/em//text()')
        item1Loader.add_xpath('Content','.//p[@class="content__list--item--des"]')
        yield item1Loader.load_item()
        print("成功啦")

当输入的时候,在items.py中

from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose, Join
import scrapy
import re
def zufang(value):
    #value=value.encode("utf-8")
    value= str(value)
    value=re.sub('<.*?>',"",value) #去除html标签
    value=value.replace('/n',"") #去除换行键
    value=re.sub('\s+','',value).strip()#去除空格
    return value
def outzufang(value):
    print("这里是输出")
    print(value)
    return value
class Lianjia1scrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    area=scrapy.Field(
        input_processor = MapCompose(zufang),
        output_processor=MapCompose(outzufang)
    )

输出的结果如下,可见当我们用ItemLoader来输入输出的时候,它们是把数据单独提取出来传递的,就是把一个列表内容单独拆分出来输出。

当数据进入pipeline.py中,也就是最终输出形态的时候,数据是以怎么样的形式出现的,假设pipeline.py输出代码如下:

import pymysql
# 使用twsited异步IO框架,实现数据的异步写入。
from pymysql import cursors
from openpyxl import Workbook
from twisted.enterprise import adbapi

class ZufangscrapyPipeline(object):
    def __init__(self):
        self.wb = Workbook()
        self.ws = self.wb.active
        self.ws.append(['地区', '社区', '小区', '价格','内容' ])# 设置表头
    def process_item(self, item, spider):  # 具体内容
#        line = [item['area'],item['Community'], item['village'], item['price'], item['Content']]  # 把数据中项整理出来
#        self.ws.append(line)  # 将数据需要保存的项以行的形式添加到xlsx中
#        self.wb.save('web.xlsx')  # 保存xlsx文件
        print("这里是pipeline")
        print(item['area'])
        #print("pipeline中的item['area']是"+item['area'])
        return item

这里的关于Excel操作的内容可以忽略,只看print输出的item['area']结果,结果如下:

这些数据在进入ItemLoader之前是以列表存在的,进入后是以列表中每一个元素依次进行处理,然后被output_processor输出的时候是重新自动被转化成一个列表进行输出的。ItemLoader相当于一个放大细节的item处理程序,也就是你以什么形式进入的,就会以什么形式输出出来。这点当你存入excel的时候要非常的注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值