1. 程式人生 > >Scrapy從json檔案載入解析規則,使一個爬蟲重複使用.並進行資料清洗

Scrapy從json檔案載入解析規則,使一個爬蟲重複使用.並進行資料清洗

我們在scrapy框架做爬蟲的時候,對於不同規則的頁面,需要寫不同的爬蟲檔案,在這種情況下,部分程式碼需要重複書寫很不方便,對於這種問題.我們可以通過json檔案載入解析規則的方法,來解決這樣個問題.
同時在爬取到的資料中也有一些資料是我們不需要的,同時資料的型別/格式也可能不是我們需要的.需要對資料進行清洗整合才能達到我們的需求,並儲存.
1.建立一個json檔案,並把頁面的解析規則寫入json檔案.

{
    "title":"tr#places_country__row td.w2p_fw::text",
    "population":"tr#places_population__row td.w2p_fw::text"
}

2.建立爬蟲.

# -*- coding: utf-8 -*-
import scrapy
import json
from scrapy import Request
from country_spider.items import CountryItem
from country_spider.items import CountryItemLoader


class CountrySpider(scrapy.Spider):
    name = 'country'
    allowed_domains = ['example.com']

    def __init__(self):
        self.urls = ['http://example.webscraping.com/places/default/view/China-47']

    def start_requests(self):
        for url_str in self.urls:
            yield Request(url_str, callback=self.parse, dont_filter=True)

    def parse(self, response):
        item = CountryItemLoader(item=CountryItem(), response=response)

        # 從json檔案載入解析規則
        with open("json檔案路徑", "r", encoding="utf8") as fp:
            datas = json.load(fp)
        for key in datas:
            item.add_css(key, datas[key])

        # 新增相應欄位的解析規則
        # 可以使用item.add_xpath / item.add_css    
        # item.add_css("title","tr#places_country__row td.w2p_fw::text")
        # item.add_css("population","tr#places_population__row td.w2p_fw::text")
        return item.load_item()

3.在item中對爬取資料進行清洗

# -*- coding: utf-8 -*-

from scrapy.loader import ItemLoader
from scrapy.item import Item
from scrapy import Field
from scrapy.loader.processors import MapCompose, TakeFirst, Join


def str_convert(value):
    return "country_" + value


def get_nums(value):
    return value.replace(",", "")


class CountryItemLoader(ItemLoader):
    # TakeFirst 取出陣列中的第一個(相當於extract_first)
    # 定義一個預設的輸出處理器
    default_output_processor = TakeFirst()


class CountryItem(Item):
    # 定義一個輸入處理器,這裡將處理函式對映到函式str_convent,進行資料清洗
    title = Field(
        input_processor=MapCompose(str_convert),
    )
    population = Field(
        input_processor=MapCompose(get_nums),
    )

4.在pipelines中對資料進行儲存


class CountrySpiderPipeline(object):
    def process_item(self, item, spider):
        print("#" * 50)
        print("item name is ::", item["title"])
        print("item content is ::", item["population"])
        print("#" * 50)
        return item

最後爬蟲的起始url也可以通過json載入,在這裡就不寫了,參考解析規則就可輕鬆實現.