【Scrapy】Scrapy的items.py用法

之前寫了pipelines.py的一些用法:【Scrapy】Scrapy的pipelines管道使用方法 ,主要是用來處理獲取數據後做的操作。

而這次介紹的items.py,它的作用主要是用來處理獲取的的數據,做數據清洗用的,具體也很難一時講清,先看代碼。

1.首先我們通過ItemLoader 獲取到數據

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&degreefrom=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等是數組,而我需要的是字符串。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章