【问题标题】:Scrapy output only the last incrementally updated itemScrapy 仅输出最后一个增量更新的项目
【发布时间】:2013-11-07 02:45:05
【问题描述】:

有人可以帮我解决这个问题吗,我一直在搜索此信息 2 天,没有运气。

我有一个包含 1 个字段的项目作为另一个项目的列表。蜘蛛工作正常,但在输出文件中我得到了该项目的所有行。

例如,我需要将json打印为:

{"id": "AAAA", "details": [
{"date" : "2013-01-10", type="A"},
{"date" : "2013-02-10", type="B"},
{"date" : "2013-03-10", type="C"},
{"date" : "2013-04-10"}, type="D"]}

但我明白了:

{"id": "AAAA", "details": [
{"date" : "2013-01-10", type="A"}]}

{"id": "AAAA", "details": [
{"date" : "2013-01-10", type="A"},
{"date" : "2013-02-10", type="B"}]}

{"id": "AAAA", "details": [
{"date" : "2013-01-10", type="A"},
{"date" : "2013-02-10", type="B"},
{"date" : "2013-03-10", type="C"}
]}

{"id": "AAAA", "details": [
{"date" : "2013-01-10", type="A"},
{"date" : "2013-02-10", type="B"},
{"date" : "2013-03-10", type="C"},
{"date" : "2013-04-10"}, type="D"]}

我使用一个函数来更新我的父项:

def rePackIt(parent, item):
    if 'details' in parent:
        items = parent.get('details')
    else:
        items = []
    items.append(dict(item))
    parent['details'] = items

return parent

在解析函数中我这样做:

parent = ParentItem()
parent['id'] = self.param   # actually I parse a text file with many IDs
parent['details'] = []

yield FormRequest.from_response(response,
                                    formname='...',
                                    formdata={'...':'...', '...': parent['id'], 
                                              '...':''},
                                    meta = {'parent': parent, 'dont_merge_cookies': True},
                                    callback=self.parse1)


def parse1(self, response):
    parent = response.meta['parent']
    sel = HtmlXPathSelector(response)
    records = sel.select('//ul[@class="...."]')
    for record in records:
        item = DetailItem()
        item['type'] = record.select('child...')
        doc_link = record.select('child.../a/@href').extract()
        yield Request(doc_link,
                              callback=self.parse2,
                              method='GET',
                              headers={...},
                              meta={'dont_merge_cookies': True, 'cookiejar': cookieJar, 'item'  : item, 'parent' : parent}
                          )
  def parse2(self, response):
      item = response.meta['item']
      parent = response.meta['parent']
      sel = HtmlXPathSelector(response)
      # some other parsing code
      item['date'] = cell.select('span[1]/text()[1]').extact()
      rePackIt(parent, item)
      return parent

【问题讨论】:

  • 你能分享一些你的蜘蛛代码吗?尤其是您如何实例化您的项目并设置此日期列表?
  • 您好,谢谢您的回复,我正在等待我的 gmail 中的任何回复通知,但它没有到达。我现在将更新问题的正文。
  • 嗨,保罗。你看过代码吗?我仍在等待您身边的任何 cmets。谢谢。

标签: scrapy


【解决方案1】:

您尝试废弃并输出为 json 的页面具有这种结构

  • MainItem 1 {一些信息}

    • 详细项目 1

    • 详细项目 2

  • 主要项目2

    • 详细项目 1

    • 详细项目 2

您将返回每个报废的细节项目的父对象。虽然您的意图是在“完成”之后只返回一次父对象。这意味着您的父母填写了所有详细的项目 1..n。问题是您没有更好的方式来说明何时完成构建父项。

处理此问题的一种方法是编写管道 (http://doc.scrapy.org/en/latest/topics/item-pipeline.html)。这听起来可能很复杂,但事实并非如此。

管道中基本上有三个步骤

open_spider

您创建表单的全局对象

项目列表 = []

process_item

if item is parent then
   add the item to the list 
if item is child then
   find the parentitem from the itemlist
   parentitem["detail"].add(childitem)

close_spider

编写您的 json 序列化并写入所需的文件。一个警告是,如果你正在抓取大量数据,所有抓取的项目都将存在于内存中,直到你用这种方法将它们写入文件,因为你将无法流式写入你的 json 项目。

让我知道这是否可行,或者您是否找到了更好的解决方案。

【讨论】:

  • 非常感谢您提供此解决方案。我回去工作了,我现在检查一下,然后回来。祝你有美好的一天。
  • 嗨,我已经测试了这个解决方案,它工作得非常完美,非常感谢!!!我用几个案例对其进行了测试,我的输出 JSON 文件应该是这样的。还有一件事:self.itemlist = [] 我在 init 方法中写的。再次感谢!!!
  • 抱歉,我不能投票,因为我是新来的,积分不够。
  • 如果解决方案适合您,您可以将其标记为答案。谢谢。
  • 哦,我错过了那个复选标记......现在它完成了。祝您度过愉快的一天和一周。
猜你喜欢
  • 1970-01-01
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多