我有一些Scrapy蜘蛛运行,最近有一个奇怪的bug。我有一个基类和一些子类:
class MyBaseSpider(scrapy.Spider):
new_items = []
def spider_closed(self):
#Email any new items that weren't in the last run
class MySpiderImpl1(MyBaseSpider):
def parse(self):
#Implement site specific checks
self.new_items.append(new_found_item)
class MySpiderImpl2(MyBaseSpider):
def parse(self):
#Implement site specific checks
self.new_items.append(new_found_item)
这似乎一直运行良好,新的项目得到电子邮件给我的每个网站的基础上。但我最近有一些电子邮件从MySpiderImpl 1包含项目从网站2。
我按照文档从脚本运行:
scraper_settings = get_project_settings()
runner = CrawlerRunner(scraper_settings)
configure_logging()
sites = get_spider_names()
for site in sites:
runner.crawl(site.spider_name)
d = runner.join()
d.addBoth(lambda _: reactor.stop())
reactor.run()
我怀疑这里的解决方案是切换到一个管道,它整理一个站点的项目,并在调用pipeline.close_spider
时通过电子邮件将它们发送出去,但我惊讶地看到new_items
变量在蜘蛛之间泄漏。
是否有关于并发运行的文档?将变量保存在基类中是否是不好的做法?我还跟踪了变量中蜘蛛的其他信息,如运行编号-是否应该在其他地方跟踪?
1条答案
按热度按时间6tqwzwtp1#
在python中,所有的类变量都在所有的示例和子类之间共享,所以你的
MyBaseSpider.new_items
和MySpiderImpl1.new_items
和MySpiderImpl2.new_items
使用的列表是完全一样的。正如您所建议的,您可以实现一个管道,尽管这可能需要对当前代码进行大量重构。
pipelines.py
我想你们所有的蜘蛛都有名字...我想这是一个要求。
另一个可能需要较少工作的选项是覆盖基类中的
start_requests
方法,以便在爬网过程开始时分配一个唯一列表。