Scrapy :: JSON导出问题

时间:2011-10-20 17:08:39

标签: python json web-crawler scrapy

所以,我花了很多时间浏览Scrapy文档和教程,之后我就开始使用非常基本的爬虫了。但是,我无法将输出转换为JSON文件。我觉得我错过了一些明显的东西,但是在看了很多其他的例子之后我又找不到任何东西,并尝试了几个不同的东西。

为了彻底,我将包括所有相关代码。我想要的是一些特定的项目及其相关价格。价格会经常变化,而且项目的变化频率要低得多。

这是我的items.py:

class CartItems(Item):
    url = Field()
    name = Field()
    price = Field()

这是蜘蛛:

from scrapy.selector import HtmlXPathSelector                                                                                                                                        
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.item import Item, Field

from Example.items import CartItems

class DomainSpider(CrawlSpider):
    name = 'example.com'
    allowed_domains = ['example.com']
    start_urls = ['http://www.example.com/path/to/desired/page']


    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        cart = CartItems()
        cart['url'] = hxs.select('//title/text()').extract()
        cart['name'] = hxs.select('//td/text()').extract()[1]
        cart['price'] = hxs.select('//td/text()').extract()[2]
        return cart

例如,如果我从URL http://www.example.com/path/to/desired/page上的Scrapy shell运行hxs.select('// td / text()')。extract()[1],那么我得到以下响应:< / p>

u'Text field I am trying to download'

编辑:

好吧,所以我编写了一个管道,跟随我在wiki中找到的那个(我在过去几天挖掘这个时错过了这个部分),只是改为使用JSON而不是XML。

from scrapy.xlib.pydispatch import dispatcher
from scrapy import signals
from scrapy.contrib.exporter import JsonItemExporter

class JsonExportPipeline(object):

    def __init__(self):
        dispatcher.connect(self.spider_opened, signals.spider_opened)
        dispatcher.connect(self.spider_closed, signals.spider_closed)
        self.files = {}

    def spider_opened(self, spider):
        file = open('%s_items.json' % spider.name, 'w+b')
        self.files[spider] = file
        self.exporter = JsonItemExporter(file)
        self.exporter.start_exporting()

    def spider_closed(self, spider):
        self.exporter.finish_exporting()
        file = self.files.pop(spider)
        file.close()

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item

这会输出一个文件“example.com_items.json”,但它包含的只是“[]”。所以,我仍然不在这里。是蜘蛛的问题,还是管道没有正确完成?很显然,我在这里遗漏了一些东西,所以如果有人能够朝着正确的方向推动我,或者将任何可能有帮助的例子与我联系起来,那将是非常感激的。

2 个答案:

答案 0 :(得分:1)

JsonItemExporter非常简单:

class JsonItemExporter(JsonLinesItemExporter):

    def __init__(self, file, **kwargs):
        self._configure(kwargs)
        self.file = file
        self.encoder = json.JSONEncoder(**kwargs)
        self.first_item = True

    def start_exporting(self):
        self.file.write("[")

    def finish_exporting(self):
        self.file.write("]")

    def export_item(self, item):
        if self.first_item:
            self.first_item = False
        else:
            self.file.write(',\n')
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(self.encoder.encode(itemdict))

所以,我有两个结论:

  1. 创建了文件 - 您的管道处于有效状态,并挂起了spider_openedspider_closed个事件。

  2. 永远不会调用
  3. process_item。也许没有项目被删除,所以没有项目传递给这个管道?

  4. 此外,我认为代码中存在错误:

    def spider_opened(self, spider):
        file = open('%s_items.json' % spider.name, 'w+b')
        self.files[spider] = file
        self.exporter = JsonItemExporter(file)
        self.exporter.start_exporting()
    

    self.exporter = JsonItemExporter(file) - 这是不是意味着只有一个出口商一直处于活动状态?打开蜘蛛后,您将创建一个导出器。当该蜘蛛处于活动状态时,另一个蜘蛛可以打开,self.exporter将被新的导出器覆盖。

答案 1 :(得分:1)

我从JsonExportPipeline复制了您的代码并在我的机器上进行了测试。 它对我的蜘蛛很好。

所以我认为你应该查看页面。

start_urls = ['http://www.example.com/path/to/desired/page']

也许你的解析函数在提取内容方面有问题。以下功能如下:

def parse(self, response):
    hxs = HtmlXPathSelector(response)
    cart = CartItems()
    cart['url'] = hxs.select('//title/text()').extract()
    cart['name'] = hxs.select('//td/text()').extract()[1]
    cart['price'] = hxs.select('//td/text()').extract()[2]
    return cart