繁体   English   中英

如何将批量更新从 Scrapy 管道写入 mongodb

[英]How to write bulk updates from a Scrapy pipeline to mongodb

我有一个基于 Scrapy 的持续运行的爬虫。

在每次运行中,此爬虫都会对给定 ID 列表执行请求,并将 output 写入 S3 存储桶。

这些请求可能会不时失败,我需要记录成功和失败。

我目前在成功时产生一个项目,在失败时产生一个特殊的 ErrorItem 。

我制作了一个应该处理成功和失败日志记录的管道。

def process_item(self, item, spider):
    if isinstance(item, MyErrorItem):
        self.errors.append(item['id'])
        raise DropItem('Dropped')
    else:
        self.success.append(item['id'])
        return item

def close_spider(self, spider):
    conn_to_mongo = getconn()
    errors_query = create_or_query_by_ids(self.errors)
    write_to_mongo(errors_query, {"$set": {"status": "fail"}})
    success_query = create_or_query_by_ids(self.success)
    write_to_mongo(success_query, {"$set": {"status": "success"}})

我没有找到任何关于这种模式的参考。 通常所有对外部数据引擎的写入都是从 process_item function 进行的。

在这里,我将 id 收集到相应的列表中,并在 close_spider 上批量写入。

原因是如果可以批量完成,则对数据库执行多个写入请求效率不高。

有没有更有效的方法来实现这种行为? 这种方法有什么缺陷吗?

我不认为这种方法有什么大问题。 我能想到的一些缺点:

  • 你在 memory 中保留了 2 个列表,它们在蜘蛛运行时不断增长。 如果列表变大,这可能会成为问题。 如果你逐项插入,你就不会有这个。
  • 如果最后的插入有误,您将丢失所有已抓取的数据。 例如,如果在您要插入数据时数据库不可用或过载,则必须再次运行爬虫

我认为更好的方法可能是:

  • 项目管道写入 json 文件而不是附加到列表
  • 在关闭蜘蛛时,您根据 json 文件而不是列表进行插入

这样你就不会超载 memory,如果最后插入失败,你可以根据文件重试,而不必重新运行所有内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM