2017-03-05 17 views
0

すべての産出アイテムを2つのリストに分割するにはどうすればよいですか?たとえば、私がアイテムの2つの主要なタイプ - articleauthorを持っているとしましょう。私はそれらを2つの別々のリストに入れたいと思う。今すぐ出力を取得しています。JSONのサブアイテムとしての治療の収穫アイテム

[ 
    { 
    "article_title":"foo", 
    "article_published":"1.1.1972", 
    "author": "John Doe" 
    }, 
    { 
    "name": "John Doe", 
    "age": 42, 
    "email": "[email protected]" 
    } 
] 

どうすればこのように変換できますか?これらを出力するための

{ 
    "articles": [ 
    { 
     "article_title": "foo", 
     "article_published": "1.1.1972", 
     "author": "John Doe" 
    } 
    ], 
    "authors": [ 
    { 
     "name": "John Doe", 
     "age": 42, 
     "email": "[email protected]" 
    } 
    ] 
} 

私の機能は、これに似た、単純です:

def parse_author(self, response): 
     name = response.css('div.author-info a::text').extract_first() 
     print("Parsing author: {}".format(name)) 

     yield { 
      'author_name': name 
     } 

答えて

2

アイテム別途パ​​イプラインに到達し、この設定をそれに応じて、それぞれを追加します。

items.py

class Article(scrapy.Item): 
    title = scrapy.Field() 
    published = scrapy.Field() 
    author = scrapy.Field() 

class Author(scrapy.Item): 
    name = scrapy.Field() 
    age = scrapy.Field() 

spider.py

def parse(self, response): 

    author = items.Author() 
    author['name'] = response.css('div.author-info a::text').extract_first() 
    print("Parsing author: {}".format(author['name'])) 
    yield author 

    article = items.Article() 
    article['title'] = response.css('article css').extract_first() 
    print("Parsing article: {}".format(article['title'])) 

    yield article 

pipelines.py

process_item(self, item, spider): 
    if isinstance(item, items.Author): 
     # Do something to authors 
    elif isinstance(item, items.Article): 
     # Do something to articles 

は、私は、このアーキテクチャかかわら勧め:

[{ 
    "title": "foo", 
    "published": "1.1.1972", 
    "authors": [ 
     { 
     "name": "John Doe", 
     "age": 42, 
     "email": "[email protected]" 
     }, 
     { 
     "name": "Jane Doe", 
     "age": 21, 
     "email": "[email protected]" 
     }, 
    ] 
}] 

これは、それが一つの項目ですべてを行かせます。

items.py

class Article(scrapy.Item): 
    title = scrapy.Field() 
    published = scrapy.Field() 
    authors = scrapy.Field() 

spider.py

def parse(self, response): 

    authors = [] 
    author = {} 
    author['name'] = "John Doe" 
    author['age'] = 42 
    author['email'] = "[email protected]" 
    print("Parsing author: {}".format(author['name'])) 
    authors.append(author) 

    article = items.Article() 
    article['title'] = "foo" 
    article['published'] = "1.1.1972" 
    print("Parsing article: {}".format(article['title'])) 
    article['authors'] = authors 
    yield article 
+0

私はまだ1つのJSONキー。 '{'author':item}'を返すようにパイプラインを変更すると、すべてのアイテムに対して単一の 'author'キーが作成されます。どこかで自分のリストにすべてのアイテムを蓄積して、最後にJSONとして出力する必要があると思いますが、それをどこにするかはわかりません。 :::記事を繰り返し処理したい場合は、提案したアーキテクチャが良いです。たとえば、すべての著者をリストするのはずっと難しくなります。 –

+0

@MartinMelka私の答えを編集しました –

1
raw = [ 
    { 
     "article_title":"foo", 
     "article_published":"1.1.1972", 
     "author": "John Doe" 
    }, 
    { 
     "name": "John Doe", 
     "age": 42, 
     "email": "[email protected]" 
    } 
] 

data = {'articles':[], "authors":[]} 

for a in raw: 

    if 'article_title' in a: 
     data['articles'].extend([ a ]) 

    else: 
     data['articles'].extend([ a ]) 
+0

私はScrapyでそのような辞書を処理する方法を確認していません。解析関数からの「yield」は辞書をScrapyに直接渡し、私は最後にそれを処理することができません。あなたの答えを広げてください。 –

+0

@MartinMelkaプロセスとはどこですか?申し訳ありませんがあなたの質問を得る...あなたのデータが 'item ['articles']'パイプラインでアクセス可能でなければならないことを理解しています – Umair