2016-12-26 45 views
1

嵌套的项目我都这个对象我试图用itemLoader填充:scrapy:填充与itemLoader

{ 
    "domains": "string", 
    "date_insert": "2016-12-23T11:25:00.213Z", 
    "title": "string", 
    "url": "string", 
    "body": "string", 
    "date": "2016-12-23T11:25:00.213Z", 
    "authors": [ 
    "string" 
    ], 
    "categories": [ 
    "string" 
    ], 
    "tags": [ 
    "string" 
    ], 
    "stats": { 
    "views_count": 0, 
    "comments_count": 0 
    } 
} 

这里是我的items.py

class StatsItem(scrapy.Item): 
    views_count=scrapy.Field() 
    comments_count=scrapy.Field() 

class ArticleItem(scrapy.Item): 
    domain = scrapy.Field() 
    date_insert=scrapy.Field() 
    date_update=scrapy.Field() 
    date=scrapy.Field() 
    title=scrapy.Field() 
    url=scrapy.Field() 
    body=scrapy.Field(
     output_processor=Join()) 
    date=scrapy.Field() 
    authors=scrapy.Field(
     output_processor=Identity()) 
    categories=scrapy.Field(
     output_processor=Identity()) 
    tags=scrapy.Field() 
    stats=scrapy.Field() 

部分我蜘蛛:

def parse(self, response): 
    loader = ArticleItemLoader(response=response) 
    parsed_uri = urlparse(response.url) 
    domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri) 

    loader.add_css('authors','span.meta-author') 
    loader.add_css('title', 'h1.title-article') 
    loader.add_value('url', response.url) 
    loader.add_xpath('date_insert', '//div[@class=\'meta\']/time[@itemprop=\'datePublished\']/@datetime') 
    loader.add_xpath('date_update', '//div[@class=\'meta\']/time[@itemprop=\'dateModified\']/@datetime') 
    loader.add_value('domain', domain) 
    loader.add_xpath('categories', '//ul[@class=\'breadcrumbs\']//li[not(contains(@class, \'home\'))]') 

到目前为止,我已经成功填充每个领域,但“统计”。我已检查此页面correct way to nest Item data in scrapy但它似乎不工作了(我无法使它工作,我的错误是TypeError:to_unicode必须接收一个字节,str或unicode对象,得到StatsItem)

我会喜欢用itemLoader但我不知道我怎么能填充我的“统计”我StatsItem

THX的帮助

编辑 我很接近,但它仍然不工作:

loader.add_value('stats', self.getStats(response)) 

def getStats(self, response): 
    statsLoader = StatsItemLoader(response=response) 
    statsLoader.add_xpath('comments_count', '//div[@class=\'btn-count\']//a/text()') 
    statsLoader.add_value('views_count', '42') 
    return json.dumps(dict(statsLoader.load_item())) 

但我的输出如下: { [...] “stats”:“{\”comments_count \“:\”0 \“,\”views_count \“:\”42 \“}” }

+0

我觉得你忘记在'ArticleItem'的'stats'属性中包含'Field(serializer = MetaItem)'' – eLRuLL

+0

从上面的代码你确定你不需要提供'input_processor'和' output_processor'为您的'StatsItem'像[本示例](https://doc.scrapy.org/en/latest/topics/loaders.html#declaring-input-and-output-processors)从文档? –

+0

@ kiran.koduru我thnik因为我设置了Item Loader的默认值,所以我不需要'处理器'。 – RogerFromSpace

回答

1

感谢@eLRuLL我设法找到一个体面的解决方案:

items.py:

class StatsItem(scrapy.Item): 
    views_count=scrapy.Field() 
    comments_count=scrapy.Field() 

class ArticleItem(scrapy.Item): 
    [...] 
    stats=scrapy.Field(
     input_processor=Identity()) 


class StatsItemLoader(ItemLoader): 
    default_input_processor=MapCompose(remove_tags) 
    default_output_processor=TakeFirst() 
    default_item_class=StatsItem 

spider.py:

def parse(self, response): 
    [...] 
    loader.add_value('stats', self.getStats(response)) 
    [...] 

def getStats(self, response): 
    statsLoader = StatsItemLoader(response=response) 
    statsLoader.add_xpath('comments_count', '//div[@class=\'btn-count\']//a/text()') 
    statsLoader.add_value('views_count', '42') 
    return dict(statsLoader.load_item()) 

最初它不工作,因为我的input_processor为MapCompose(remove_tags)为stats字段。为了序列化你必须return dict(loader.load_item())而不仅仅是return loader.load_item()

谢谢!