0

我正在使用 Scrapy 抓取一个站点并从三个元素中创建一个 CSV,我们会说“id”、“name”和“desc”,以与 Scrapy 站点管道示例保持一致。我正在抓取这些项目并将它们输出到 csv。我不想要任何具有相同 'id' 字符串的 ROWS。

这是 Scrapy 的示例管道:

class DuplicatesPipeline(object):

    def __init__(self):
        self.ids_seen = set()

    def process_item(self, item, spider):
        if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(item['id'])
            return item

但是当我使用该代码时,我得到exceptions.TypeError: unhashable type:'list'

但是,如果我尝试转换为元组,那么:

def process_item(self, item, spider):
    if tuple(item.get('id', '')) in self.ids_seen:
        raise DropItem("Duplicate item found: %s" % item)
    else:
        self.ids_seen.add(item.get['id'])
        return item

我明白了exceptions.TypeError: 'instancemethod' object has no attribute '__getitem__'

有人可以让我知道如何使用项目管道来简单地不允许在“id”列中具有相同“id”字符串的多行吗?当我不想在单元格中出现空白点时,我可能无法拒绝单个元素 - 如果它们共享一个“id”项,我希望整个行被跳过。当我可能需要 csvexporter 或 csv 蜘蛛或其他东西时,我也可能无法为此使用管道。看起来这对 Scrapy 来说是一件容易的事。


解决方案?

我想我通过将初始代码更改为此来创建一个字符串来解决它:

def process_item(self, item, spider):
        idstring = str(item['id'])
        if idstring in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(idstring)
            return item

请让我知道这是否是一个有问题的解决方案,因为我是一个完全的 Python 新手 :)

4

1 回答 1

0

嗯,我想您可以更改您的管道以使用列表而不是集合。

尝试改变:

class DuplicatesPipeline(object):

    def __init__(self):
        self.ids_seen = set()

    def process_item(self, item, spider):
        if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(item['id'])
            return item

进入:

class DuplicatesPipeline(object):

def __init__(self):
    self.ids_seen = []

def process_item(self, item, spider):
    if item['id'] in self.ids_seen:
        raise DropItem("Duplicate item found: %s" % item)
    else:
        self.ids_seen.append(item['id'])
        return item

干杯

于 2014-11-17T11:49:10.733 回答