【Scrapy】Scrapy的items.py用法

之前写了pipelines.py的一些用法:【Scrapy】Scrapy的pipelines管道使用方法 ,主要是用来处理获取数据后做的操作。

而这次介绍的items.py,它的作用主要是用来处理获取的的数据,做数据清洗用的,具体也很难一时讲清,先看代码。

1.首先我们通过ItemLoader 获取到数据

【Scrapy】Scrapy的items.py用法_第1张图片

import sys
sys.path.append(r'E:\projects\python-spider')
import scrapy
from  scrapy.loader import ItemLoader
from spiderJob.items import SpiderjobItem
def getUrl():
    return 'https://search.51job.com/list/030200,000000,0000,00,9,99,%2520,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='

class itemSpider(scrapy.Spider):
    name = 'argsSpider'
    def start_requests(self):
        url = getUrl()
        yield scrapy.Request(url, self.parse)  # 发送请求爬取参数内容

    def parse(self, response):
        mingyan = response.css('div#resultList>.el')  # 提取首页所有数据,保存至变量mingyan
        for index ,v in enumerate(mingyan):  # 循环获取
            if(index > 0):
                load = ItemLoader(item= SpiderjobItem(), selector=v)
                load.add_css("t1", ".t1 a::text")
                load.add_css("t2", ".t2 a::attr(title)")
                load.add_css("t3", ".t3::text")
                load.add_css("t4", ".t4::text")
                item =  load.load_item()
                yield item;

2.处理并返回

import scrapy

# ItemLoader
# 是分离数据的另一种方式,可以将数据的分离和提取分为两部分,
# 默认使用xpath, css数据提取方式,
# 让代码更加整洁,更加清晰。
from  scrapy.loader import ItemLoader
from scrapy.loader.processors import *

# 如果list为空则不会进行处理,这种情况需要重载MapCompose类的__call__方法
class MapComposeCustom(MapCompose):
    #自定義MapCompose,當value沒元素時傳入" "
    def __call__(self, value, loader_context=None):
        if not value:
            value.append(" ")
        values = arg_to_iter(value)
        if loader_context:
            context = MergeDict(loader_context, self.default_loader_context)
        else:
            context = self.default_loader_context
        wrapped_funcs = [wrap_loader_context(f, context) for f in self.functions]
        for func in wrapped_funcs:
            next_values = []
            for v in values:
                next_values += arg_to_iter(func(v))
            values = next_values
        return values

#TakeFirst来作为默认输出处理器,但该函数会筛掉空字符,因此重载该类的__call__
class TakeFirstCustom(TakeFirst):
    def __call__(self, values):
        for value in values:
            if value is not None and value != '':
                return value.strip() if isinstance(value, str) else value


# 过滤空格
def cutSpace(value):
    result = str(value).replace(" ","");
    result = str(result).replace("\n", "");
    result = str(result).replace("\r", "");
    return result


class SpiderjobItem(scrapy.Item):
    t1 = scrapy.Field(
        input_processor=MapComposeCustom(cutSpace),
        output_processor=Join()
    )  # 标题
    t2 = scrapy.Field(
        input_processor = MapComposeCustom(cutSpace),
        output_processor = Join()
    )  # 标题
    t3 = scrapy.Field(
        input_processor = MapComposeCustom(cutSpace),
        output_processor = Join()
    )  # 标题
    t4 = scrapy.Field(
        input_processor=MapComposeCustom(cutSpace),
        output_processor=Join()
    )  # 标题
    pass

这里遇到几个坑:

1.一开始我用的并不是 MapComposeCustom ,而是 MapCompose ,但是为什么之后改了? 因为它不能处理传入来的数据为空导致会出现下面的情况,有些项没有了,我获取item['1']报错了,所以通过重载MapCompose方法的__call__,处理这个情况。而TakeFirstCustom我没用到,但别人一般都会用到,我就也列出来。

{
't1':['1'],
't2':['1'],
't3':['1'],
't4':['1'],
},
{
't2':['1'],
't3':['1'],
}

2.用为什么要用上Join()

因为返回的是t1等是数组,而我需要的是字符串。

 

 

你可能感兴趣的:(python)