2013-08-24 46 views
0

我解析如下:Scrapy出口无效JSON

def parse(self, response): 
    hxs = HtmlXPathSelector(response) 
    titles = hxs.select("//tr/td") 
    items = [] 
    for titles in titles: 
     item = MyItem() 
     item['title'] = titles.select('h3/a/text()').extract() 
     items.append(item) 
    return items 

为什么它输出JSON这样的:

[{"title": ["random title #1"]}, 
{"title": ["random title #2"]}] 
+0

这是有效的JSON。你从哪里得到这个输出?张贴所有的刮板输出。 – Blender

+0

我通过cmdline:scrapy抓取myspider -o items.json -t json - 我想我不明白[]来自哪里。应该是一个纯文本项目。 – deekay

+0

@agf:Scrapy将列表和生成器解包为单个项目。 – Blender

回答

2

titles.select('h3/a/text()').extract()返回一个列表,所以你得到一个列表。 Scrapy不会对你的物品结构做任何假设。

速战速决是只得到第一个结果:

item['title'] = titles.select('h3/a/text()').extract()[0] 

一个更好的解决办法是使用的物品装载和使用TakeFirst()为输出处理器:

from scrapy.contrib.loader import XPathItemLoader 
from scrapy.contrib.loader.processor import TakeFirst, MapCompose 

class YourItemLoader(XPathItemLoader): 
    default_item_class = YourItemClass 

    default_input_processor = MapCompose(unicode.strip) 
    default_output_processor = TakeFirst() 

    # title_in = MapCompose(unicode.strip) 

和负载该项目的方式:

def parse(self, response): 
    hxs = HtmlXPathSelector(response) 

    for title in hxs.select("//tr/td"): 
     loader = YourItemLoader(selector=title, response=response) 
     loader.add_xpath('title', 'h3/a/text()') 

     yield loader.load_item() 
+0

工作!谢谢! – deekay

0

作为一个替代简单的答案,你可以写一个这样的辅助函数:

def extractor(xpathselector, selector): 
    """ 
    Helper function that extract info from xpathselector object 
    using the selector constrains. 
    """ 
    val = xpathselector.select(selector).extract() 
    return val[0] if val else None 

,并调用它像这样:

item['title'] = extractor(titles, 'h3/a/text()')