2015-09-23 50 views
10

1つのアイテムクラスに保存できないデータをスクラップするSpiderがあります。Scrapy、Python:1つのパイプラインに複数のアイテムクラスがありますか?

私は1つのプロファイルアイテムを持っており、各プロファイルアイテムには未知数のコメントが含まれている可能性があります。そのため、私はプロファイル項目とコメント項目を実装したいのです。単純に歩留まりを使ってパイプラインに渡すことができます。

  1. ただし、1つのparse_item関数を持つパイプラインが2つの異なるアイテムクラスを処理する方法はわかりません。

  2. 異なるparse_item関数を使用することはできますか?

  3. 複数のパイプラインを使用する必要がありますか?

  4. または、IteratorをScrapy Itemフィールドに書き込むことは可能ですか?


comments_list=[] 
comments=response.xpath(somexpath) 
for x in comments.extract(): 
     comments_list.append(x) 
    ScrapyItem['comments'] =comments_list 

答えて

1

簡単な方法は、2つのサブパーサ、各データ・タイプのいずれかを含むパーサを有することです。メインパーサーは入力から型を判別し、その文字列を適切なサブルーチンに渡します。

第2のアプローチは、パーサを順番に含めることです.1つはプロファイルを解析し、それ以外はすべて無視します。 2つ目はコメントを解析し、それ以外はすべて無視します(上記と同じ原則)。

これが先に進んでいますか?

9

デフォルトでは、すべてのアイテムがすべてのパイプラインを通過します。例えば

、あなたがProfileItemCommentItemを得た場合、彼らは両方とも、すべてのパイプラインを通過します。あなたは、トラックの項目タイプにパイプラインを設定している場合は、あなたのprocess_item方法は次のようになります。

def process_item(self, item, spider): 
    self.stats.inc_value('typecount/%s' % type(item).__name__) 
    return item 

ProfileItemが伝わってくるときは、'typecount/ProfileItem'がインクリメントされます。 CommentItemが届くと、'typecount/CommentItem'がインクリメントされます。

は商品リクエストの一種類のみ、しかし、その項目タイプを扱う場合は先に進む前に、アイテムの種類を確認することで、ユニークである1つのパイプラインのハンドルを持つことができます:あなたは上記の2つのprocess_item方法を持っていた場合

def process_item(self, item, spider): 
    if not isinstance(item, ProfileItem): 
     return item 
    # Handle your Profile Item here. 

を別のパイプラインで設定すると、そのアイテムは両方を通過し、追跡され、処理されます(または2番目のアイテムでは無視されます)。 、あなたはそれがさらに複雑にし、クラスをロードすると、デフォルトのハンドラメソッドを呼び出すタイプの委譲システムを開発することができ、

def process_item(self, item, spider): 
    if isinstance(item, ProfileItem): 
     return self.handleProfile(item, spider) 
    if isinstance(item, CommentItem): 
     return self.handleComment(item, spider) 

def handleComment(item, spider): 
    # Handle Comment here, return item 

def handleProfile(item, spider): 
    # Handle profile here, return item 

または:

はまた、あなたはすべての「関連」の項目を処理するための1つのパイプラインを設定している可能性がありScrapyがミドルウェア/パイプラインをどのように処理するかと同様です。どのくらい複雑で必要なのか、何をしたいのかはあなた次第です。

5

複数のアイテムを定義すると、データがパイプラインによって異なる時間に処理されるため、データが関連性を持つ場合(プロファイル1 - Nコメントなど)、それらを一緒にエクスポートする必要がある場合、データをエクスポートするのは難しいことです。非常にこのタイプのそれぞれに異なるパイプラインを使用することが提案され、あなたは2つの項目がなければならないシナリオ与え

class CommentItem(scrapy.Item): 
    profile = ProfileField() 

class ProfileField(scrapy.item.Field): 
    # your business here 

しかし、このシナリオのための別のアプローチは、例えば、カスタムScrapyフィールドを定義することですアイテムとも異なる輸出インスタンス(あなたがファイルを使用している場合)を使用すると、別のファイルにこの情報を取得するよう:

settings.py

ITEM_PIPELINES = { 
    'pipelines.CommentsPipeline': 1, 
    'pipelines.ProfilePipeline': 1, 
} 

pipelines.py

class CommentsPipeline(object): 
    def process_item(self, item, spider): 
     if isinstance(item, CommentItem): 
      # Your business here 

class ProfilePipeline(object): 
    def process_item(self, item, spider): 
     if isinstance(item, ProfileItem): 
      # Your business here 
関連する問題