[ScrapyFramework]「バージョン2.4.0ソースコード」アイテムローダー詳細な説明

すべてのソースコード分析記事インデックスディレクトリポータル

[Scrapy Framework]バージョン2.4.0ソースコード:すべての構成ディレクトリインデックス

前書き

この章では、ソースコードの事例を紹介します。個人的には、データ処理の操作が面倒で、データ処理プロセスが最も単純なコンテンツに簡略化されていると感じています。列のクローラーの例では、記事は面倒で、友達は飛び越えることができます。例を見てください。

アイテムローダーは、アイテムを生成するための非常に便利な方法を提供します。Itemはキャプチャされたデータのコンテナを提供し、ItemLoaderを使用するとコンテナへの入力を非常に便利に入力できます。

ItemLoaderパラメーター定義

item:ローダーによって解析されたItemオブジェクト。

コンテキスト:コンテンツのItemLoader。

default_item_class:__ init__メソッドをインスタンス化します。

default_input_processor:指定されたフィールドのデフォルトの入力プロセッサ。

default_output_processor:指定されたフィールドのデフォルトの出力プロセッサ。

default_selector_class:セレクターのItemLoaderを構築するために使用されます。この属性が__init__メソッドに存在する場合、この属性は無視されます。この属性は、サブクラスでオーバーライドされる場合があります。

セレクター:このセレクターオブジェクトからデータを抽出します。

add_css(field_name、CSS、* processors、** kw):
ItemLoader.add_value()に似ていますが、値の代わりにcssセレクターを受け取ります。これは、これに関連するセレクターからUnicode文字列のリストを抽出するために使用されます。

# HTML snippet: <p class="product-name">Color TV</p>
loader.add_css('name', 'p.product-name')
# HTML snippet: <p id="price">the price is $1200</p>
loader.add_css('price', 'p#price', re='the price is (.*)')

add_value(field_name、value、* processors、** kw):指定されたフィールドに指定された値を追加するプロセス。get_value()は、プロセッサとkwargsにデータ使用量を追加します

loader.add_value('name', 'Color TV')
loader.add_value('colours', ['white', 'blue'])
loader.add_value('length', '100')
loader.add_value('name', 'name: foo', TakeFirst(), re='name: (.+)')
loader.add_value(None, {
    
    'name': 'foo', 'sex': 'male'})

add_xpath(field_name、value、* processors、** kw):
ItemLoader.add_value()に似ていますが、値の代わりにXPathを受け取ります。これは、これに関連するセレクターから文字列のリストを抽出するために使用されます。

# HTML snippet: <p class="product-name">Color TV</p>
loader.add_xpath('name', '//p[@class="product-name"]')
# HTML snippet: <p id="price">the price is $1200</p>
loader.add_xpath('price', '//p[@id="price"]', re='the price is (.*)')

get_collected_values(field_name):フィールドの収集された値を返します。

get_css(CSS、* processors、** kw):ItemLoader.get_value()に似ていますが、値の代わりにcssセレクターを受け取ります。これは、これに関連するセレクターからUnicode文字列のリストを抽出するために使用されます。

# HTML snippet: <p class="product-name">Color TV</p>
loader.get_css('p.product-name')
# HTML snippet: <p id="price">the price is $1200</p>
loader.get_css('p#price', TakeFirst(), re='the price is (.*)')

get_output_value(field_name):出力プロセッサを使用して、指定されたフィールドに対して解析された収集値を返します。

get_value(value、* processors、** kw):指定された値の処理は、processorsキーワードパラメーターに与えられます。

>>> from itemloaders import ItemLoader
>>> from itemloaders.processors import TakeFirst
>>> loader = ItemLoader()
>>> loader.get_value('name: foo', TakeFirst(), str.upper, re='name: (.+)')
'FOO'

get_xpath(XPath、* processors、** kw):ItemLoader.get_value()に似ていますが、値の代わりにXPathを受け取ります。これは、これに関連付けられたセレクターからUnicode文字列のリストを抽出するために使用されます。

# HTML snippet: <p class="product-name">Color TV</p>
loader.get_xpath('//p[@class="product-name"]')
# HTML snippet: <p id="price">the price is $1200</p>
loader.get_xpath('//p[@id="price"]', TakeFirst(), re='the price is (.*)')

load_item():収集されたデータが入力されて返されます。

nested_css(CSS、** context):CSSセレクターを使用してネストされたローダーを作成します。提供されるセレクターは、ItemLoaderに関連しています。

nested_xpath(XPath、** context):XPathセレクターを使用してネストされたローダーを作成します。提供されるセレクターは、ItemLoaderに関連しています。

replace_css(field_name、CSS、* processors、** kw):add_css()に似ていますが、データを追加する代わりに、収集されたデータを置き換えます。

replace_value(field_name、value、* processors、** kw):add_value()に似ていますが、収集されたデータを追加する代わりに新しい値に置き換えます。

replace_xpath(field_name、XPath、* processors、** kw):add_xpath()に似ていますが、データを追加する代わりに、収集されたデータを置き換えます。

データ処理例

アイテムを定義する

import scrapy
 
class Product(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field()
    stock = scrapy.Field()
    last_updated = scrapy.Field(serializer=str)

Spiderに塗りつぶしデータを読み込んでいます

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') # you can also use literal values
    return l.load_item()

データセット項目の処理

データのフィールドタイプとデフォルト値を定義します。

from dataclasses import dataclass, field
from typing import Optional

@dataclass
class InventoryItem:
    name: Optional[str] = field(default=None)
    price: Optional[float] = field(default=None)
    stock: Optional[int] = field(default=None)

入出力プロセッサ

各アイテムローダーには、フィールドごとに入力プロセッサと出力プロセッサがあります。入力プロセッサはデータを受信したときに実行され、出力プロセッサはデータが収集された後にItemLoader.load_item()が呼び出されたときに実行され、最終結果が返されます。

l = ItemLoader(Product(), some_selector)
l.add_xpath('name', xpath1) # (1)
l.add_xpath('name', xpath2) # (2)
l.add_css('name', css) # (3)
l.add_value('name', 'test') # (4)
return l.load_item() # (5)

アイテムローダーを宣言する

入力プロセッサと出力プロセッサは_inと_outのサフィックスで定義され、デフォルトのItemLoader.default_input_processorとItemLoader.default_input_processorも定義できます。

from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose, Join
 
class ProductLoader(ItemLoader):
    default_output_processor = TakeFirst()
 
    name_in = MapCompose(unicode.title)
    name_out = Join()
 
    price_in = MapCompose(unicode.strip)
 
    # ...

フィールド定義で入出力プロセッサを宣言します

フィールドで入出力プロセッサを直接定義して追加すると非常に便利です。

  1. アイテムローダーで定義されたField_inとfield_out
  2. ファイルされたメタデータ(input_processorおよびoutput_processorキーワード)
  3. アイテムローダーのデフォルト
import scrapy
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(),
    )

アイテムローダーのコンテキスト

アイテムローダーのコンテキストは、すべての入力/出力プロセッサで共有されます。

def parse_length(text, loader_context):
    unit = loader_context.get('unit', 'm')
    # ... 这里写入长度解析代码 ...
    return parsed_length
# 初始化和修改上下文的值
loader = ItemLoader(product)
loader.context['unit'] = 'cm'
 
loader = ItemLoader(product, unit='cm')
 
class ProductLoader(ItemLoader):
    length_out = MapCompose(parse_length, unit='cm')

アイテムローダーを書き直して拡張する

操作の共通設定を使用して、大規模なコード保守操作に使用されます。

指定したシンボルを削除する操作は、後のデータクレンジング部分で処理することをお勧めします。

from itemloaders.processors import MapCompose
from myproject.ItemLoaders import ProductLoader

def strip_dashes(x):
    return x.strip('-')

class SiteSpecificLoader(ProductLoader):
    name_in = MapCompose(strip_dashes, ProductLoader.name_in)
from itemloaders.processors import MapCompose
from myproject.ItemLoaders import ProductLoader
from myproject.utils.xml import remove_cdata

class XmlProductLoader(ProductLoader):
    name_in = MapCompose(remove_cdata, ProductLoader.name_in)

おすすめ

転載: blog.csdn.net/qq_20288327/article/details/113494261