Scrapy-アイテムローダー
説明
アイテムローダーは、Webサイトから削り取られたアイテムを埋める便利な方法を提供します。
アイテムローダーの宣言
アイテムローダーの宣言はアイテムのようなものです。
例-
from scrapy.loader import ItemLoader 
from scrapy.loader.processors import TakeFirst, MapCompose, Join  
class DemoLoader(ItemLoader):  
   default_output_processor = TakeFirst()  
   title_in = MapCompose(unicode.title) 
   title_out = Join()  
   size_in = MapCompose(unicode.strip)  
   # you can continue scraping here上記のコードでは、入力プロセッサがを使用して宣言されていることがわかります。 _in サフィックスと出力プロセッサは、を使用して宣言されます _out サフィックス。
ザ・ ItemLoader.default_input_processor そして ItemLoader.default_output_processor 属性は、デフォルトの入出力プロセッサを宣言するために使用されます。
アイテムローダーを使用したアイテムの入力
アイテムローダーを使用するには、最初にdictのようなオブジェクトを使用して、またはアイテムがで指定されたItemクラスを使用するオブジェクトを使用せずにインスタンス化します。 ItemLoader.default_item_class 属性。
- セレクターを使用して、アイテムローダーに値を収集できます。 
- 同じアイテムフィールドにさらに値を追加できます。アイテムローダーは適切なハンドラーを使用してこれらの値を追加します。 
次のコードは、アイテムローダーを使用してアイテムがどのように入力されるかを示しています-
from scrapy.loader import ItemLoader 
from demoproject.items import Demo  
def parse(self, response): 
   l = ItemLoader(item = Product(), response = response)
   l.add_xpath("title", "//div[@class = 'product_title']")
   l.add_xpath("title", "//div[@class = 'product_name']")
   l.add_xpath("desc", "//div[@class = 'desc']")
   l.add_css("size", "div#size]")
   l.add_value("last_updated", "yesterday")
   return l.load_item()上に示したように、2つの異なるXPathがあり、そこから title フィールドはを使用して抽出されます add_xpath() 方法−
1. //div[@class = "product_title"] 
2. //div[@class = "product_name"]その後、同様のリクエストが descフィールド。サイズデータは以下を使用して抽出されますadd_css() メソッドと last_updated を使用して「昨日」の値で埋められます add_value() 方法。
すべてのデータが収集されたら、 ItemLoader.load_item() を使用して抽出されたデータで満たされたアイテムを返すメソッド add_xpath()、 add_css() そして add_value() メソッド。
入力および出力プロセッサ
アイテムローダーの各フィールドには、1つの入力プロセッサと1つの出力プロセッサが含まれています。
- データが抽出されると、入力プロセッサがデータを処理し、その結果がItemLoaderに格納されます。 
- 次に、データを収集した後、ItemLoader.load_item()メソッドを呼び出して、入力されたItemオブジェクトを取得します。 
- 最後に、出力プロセッサの結果をアイテムに割り当てることができます。 
次のコードは、特定のフィールドの入力プロセッサと出力プロセッサを呼び出す方法を示しています。
l = ItemLoader(Product(), some_selector)
l.add_xpath("title", xpath1) # [1]
l.add_xpath("title", xpath2) # [2]
l.add_css("title", css)      # [3]
l.add_value("title", "demo") # [4]
return l.load_item()         # [5]Line 1 −タイトルのデータはxpath1から抽出され、入力プロセッサを通過し、その結果が収集されてItemLoaderに格納されます。
Line 2 −同様に、タイトルはxpath2から抽出され、同じ入力プロセッサを通過し、その結果が[1]で収集されたデータに追加されます。
Line 3 −タイトルはcssセレクターから抽出され、同じ入力プロセッサーを通過し、その結果が[1]と[2]で収集されたデータに追加されます。
Line 4 −次に、値「demo」が割り当てられ、入力プロセッサに渡されます。
Line 5 −最後に、データはすべてのフィールドから内部的に収集され、出力プロセッサに渡され、最終的な値がアイテムに割り当てられます。
入力および出力プロセッサの宣言
入力プロセッサと出力プロセッサは、ItemLoader定義で宣言されています。これとは別に、それらはまたで指定することができますItem Field メタデータ。
例-
import scrapy 
from scrapy.loader.processors import Join, MapCompose, TakeFirst 
from w3lib.html import remove_tags  
def filter_size(value): 
   if value.isdigit(): 
      return value  
class Item(scrapy.Item): 
   name = scrapy.Field( 
      input_processor = MapCompose(remove_tags), 
      output_processor = Join(), 
   )
   size = scrapy.Field( 
      input_processor = MapCompose(remove_tags, filter_price), 
      output_processor = TakeFirst(), 
   ) 
>>> from scrapy.loader import ItemLoader 
>>> il = ItemLoader(item = Product()) 
>>> il.add_value('title', [u'Hello', u'<strong>world</strong>']) 
>>> il.add_value('size', [u'<span>100 kg</span>']) 
>>> il.load_item()出力を-として表示します
{'title': u'Hello world', 'size': u'100 kg'}アイテムローダーコンテキスト
アイテムローダーコンテキストは、入力プロセッサと出力プロセッサの間で共有される任意のキー値の辞書です。
たとえば、関数parse_length −があるとします。
def parse_length(text, loader_context): 
   unit = loader_context.get('unit', 'cm') 
   
   # You can write parsing code of length here  
   return parsed_lengthloader_context引数を受信することにより、アイテムローダーコンテキストを受信できることをアイテムローダーに通知します。アイテムローダーコンテキストの値を変更する方法はいくつかあります-
- 現在アクティブなアイテムローダーコンテキストを変更する- 
loader = ItemLoader (product)
loader.context ["unit"] = "mm"- アイテムローダーのインスタンス化について- 
loader = ItemLoader(product, unit = "mm")- アイテムローダーコンテキストでインスタンス化する入出力プロセッサのアイテムローダー宣言について- 
class ProductLoader(ItemLoader):
   length_out = MapCompose(parse_length, unit = "mm")ItemLoaderオブジェクト
これは、指定されたアイテムにデータを入力するための新しいアイテムローダーを返すオブジェクトです。次のクラスがあります-
class scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)次の表は、ItemLoaderオブジェクトのパラメーターを示しています-
| シニア番号 | パラメータと説明 | 
|---|---|
| 1 | item これは、add_xpath()、add_css()、またはadd_value()を呼び出して入力する項目です。 | 
| 2 | selector Webサイトからデータを抽出するために使用されます。 | 
| 3 | response default_selector_classを使用してセレクターを構築するために使用されます。 | 
次の表は、ItemLoaderオブジェクトのメソッドを示しています-
| シニア番号 | 方法と説明 | 例 | 
|---|---|---|
| 1 | get_value(value, *processors, **kwargs) 指定されたプロセッサとキーワード引数によって、値はget_value()メソッドによって処理されます。 |  | 
| 2 | add_value(field_name, value, *processors, **kwargs) 値を処理し、フィールド入力プロセッサを通過する前にプロセッサとキーワード引数を指定することにより、最初にget_valueを通過するフィールドに追加します。 |  | 
| 3 | replace_value(field_name, value, *processors, **kwargs) 収集されたデータを新しい値に置き換えます。 |  | 
| 4 | get_xpath(xpath, *processors, **kwargs) XPathを受信してプロセッサとキーワード引数を指定することにより、Unicode文字列を抽出するために使用されます。 |  | 
| 5 | add_xpath(field_name, xpath, *processors, **kwargs) Unicode文字列を抽出するフィールドへのXPathを受け取ります。 |  | 
| 6 | replace_xpath(field_name, xpath, *processors, **kwargs) サイトからXPathを使用して収集されたデータを置き換えます。 |  | 
| 7 | get_css(css, *processors, **kwargs) Unicode文字列を抽出するために使用されるCSSセレクターを受け取ります。 |  | 
| 8 | add_css(field_name, css, *processors, **kwargs) これはadd_value()メソッドに似ていますが、CSSセレクターをフィールドに追加する点が1つ異なります。 |  | 
| 9 | replace_css(field_name, css, *processors, **kwargs) CSSセレクターを使用して抽出されたデータを置き換えます。 |  | 
| 10 | load_item() データが収集されると、このメソッドはアイテムに収集されたデータを入力して返します。 |  | 
| 11 | nested_xpath(xpath) これは、XPathセレクターを使用してネストされたローダーを作成するために使用されます。 |  | 
| 12 | nested_css(css) これは、CSSセレクターを使用してネストされたローダーを作成するために使用されます。 |  | 
次の表は、ItemLoaderオブジェクトの属性を示しています-
| シニア番号 | 属性と説明 | 
|---|---|
| 1 | item これは、アイテムローダーが解析を実行するオブジェクトです。 | 
| 2 | context アクティブなのは、アイテムローダーの現在のコンテキストです。 | 
| 3 | default_item_class コンストラクターで指定されていない場合は、アイテムを表すために使用されます。 | 
| 4 | default_input_processor default_input_processorsが使用されるのは、入力プロセッサを指定しないフィールドだけです。 | 
| 5 | default_output_processor default_output_processorsが使用されるのは、出力プロセッサを指定しないフィールドだけです。 | 
| 6 | default_selector_class コンストラクターで指定されていない場合、セレクターの構築に使用されるクラスです。 | 
| 7 | selector これは、サイトからデータを抽出するために使用できるオブジェクトです。 | 
ネストされたローダー
これは、ドキュメントのサブセクションから値を解析するときにネストされたローダーを作成するために使用されます。ネストされたローダーを作成しない場合は、抽出する値ごとに完全なXPathまたはCSSを指定する必要があります。
たとえば、データがヘッダーページから抽出されていると仮定します-
<header>
   <a class = "social" href = "http://facebook.com/whatever">facebook</a>
   <a class = "social" href = "http://twitter.com/whatever">twitter</a>
   <a class = "email" href = "mailto:[email protected]">send mail</a>
</header>次に、関連する値をヘッダーに追加することにより、ヘッダーセレクターを使用してネストされたローダーを作成できます-
loader = ItemLoader(item = Item())
header_loader = loader.nested_xpath('//header')
header_loader.add_xpath('social', 'a[@class = "social"]/@href')
header_loader.add_xpath('email', 'a[@class = "email"]/@href')
loader.load_item()アイテムローダーの再利用と拡張
アイテムローダーは、プロジェクトがより多くのスパイダーを取得するときに根本的な問題となるメンテナンスを軽減するように設計されています。
たとえば、サイトの製品名が3つのダッシュで囲まれているとします(例:-DVD ---)。次のコードに示すように、最終的な製品名にダッシュを含めたくない場合は、デフォルトの製品アイテムローダーを再利用してこれらのダッシュを削除できます。
from scrapy.loader.processors import MapCompose 
from demoproject.ItemLoaders import DemoLoader  
def strip_dashes(x): 
   return x.strip('-')  
class SiteSpecificLoader(DemoLoader): 
   title_in = MapCompose(strip_dashes, DemoLoader.title_in)利用可能な内蔵プロセッサ
以下は、一般的に使用される組み込みプロセッサの一部です-
クラスscrapy.loader.processors.Identity
変更せずに元の値を返します。例-
>>> from scrapy.loader.processors import Identity
>>> proc = Identity()
>>> proc(['a', 'b', 'c'])
['a', 'b', 'c']クラスscrapy.loader.processors.TakeFirst
受信した値のリストから、nullでも空でもない最初の値を返します。例-
>>> from scrapy.loader.processors import TakeFirst
>>> proc = TakeFirst()
>>> proc(['', 'a', 'b', 'c'])
'a'クラスscrapy.loader.processors.Join(separator = u '')
セパレータに付加された値を返します。デフォルトの区切り文字はu ''であり、関数と同等です。u' '.join。例-
>>> from scrapy.loader.processors import Join
>>> proc = Join()
>>> proc(['a', 'b', 'c'])
u'a b c'
>>> proc = Join('<br>')
>>> proc(['a', 'b', 'c'])
u'a<br>b<br>c'クラスscrapy.loader.processors.Compose(*関数、** default_loader_context)
これは、各入力値が最初の関数に渡され、その関数の結果が2番目の関数に渡されるというように、ast関数が最終値を出力として返すまでプロセッサによって定義されます。
例-
>>> from scrapy.loader.processors import Compose
>>> proc = Compose(lambda v: v[0], str.upper)
>>> proc(['python', 'scrapy'])
'PYTHON'クラスscrapy.loader.processors.MapCompose(*関数、** default_loader_context)
これは、入力値が繰り返され、最初の関数が各要素に適用されるプロセッサです。次に、これらの関数呼び出しの結果が連結されて新しいiterableが作成され、最後の関数まで2番目の関数に適用されます。
例-
>>> def filter_scrapy(x): 
   return None if x == 'scrapy' else x  
>>> from scrapy.loader.processors import MapCompose 
>>> proc = MapCompose(filter_scrapy, unicode.upper) 
>>> proc([u'hi', u'everyone', u'im', u'pythonscrapy']) 
[u'HI, u'IM', u'PYTHONSCRAPY']クラスscrapy.loader.processors.SelectJmes(json_path)
このクラスは、指定されたjsonパスを使用して値をクエリし、出力を返します。
例-
>>> from scrapy.loader.processors import SelectJmes, Compose, MapCompose
>>> proc = SelectJmes("hello")
>>> proc({'hello': 'scrapy'})
'scrapy'
>>> proc({'hello': {'scrapy': 'world'}})
{'scrapy': 'world'}以下は、json −をインポートして値をクエリするコードです。
>>> import json
>>> proc_single_json_str = Compose(json.loads, SelectJmes("hello"))
>>> proc_single_json_str('{"hello": "scrapy"}')
u'scrapy'
>>> proc_json_list = Compose(json.loads, MapCompose(SelectJmes('hello')))
>>> proc_json_list('[{"hello":"scrapy"}, {"world":"env"}]')
[u'scrapy']