【发布时间】:2020-04-24 03:51:16
【问题描述】:
我有一个爬虫,它会抓取一些数据并为管道生成一个项目。然后管道检查数据库中是否存在此数据。如果没有,它会丢弃该项目。蜘蛛是信号连接的,以调用 item_drop 信号的回调。我想从 item_dropped 回调中向不同的 url 发出另一个请求,以用其他数据填充同一个项目。如果我在回调中不包含 yield 语句,它会触发,但如果我包含,它不会触发,我不知道为什么。
(为简洁起见)
MySpider.py:
def from_crawler(cls, crawler, *args, **kwargs):
spider = super(MySpider, cls).from_crawler(crawler, *args, **kwargs)
crawler.signals.connect(spider.item_dropped, signal=signals.item_dropped)
return spider
[ ...parse start url and yield to pipeline here... ]
def item_dropped(self, item, response, exception, spider,):
print("ITEM ERROR CAUGHT")
yield Request(
url="http://www.example.com/api/data",
callback=self.parse_request_2,
cb_kwargs=dict(item=item))
MyPipeline.py:
def process_item(self, item, spider):
/* ORM model mapping */
data = Data(
name = item['name']
)
data_exists = self.session.query(exists().where(Data.name == item['name'])).scalar()
if data_exists is False:
raise DropItem("DATA_INCOMPLETE")
我尝试这样做的原因是新对象不断添加到第一个 url,所以我需要重复抓取它,但它不包含该项目所需的所有数据。然后我需要抓取一个不同的 url 以将其他数据添加到该项目,但只有一次,即第一次将该项目添加到数据库中。
如何让 scrapy 从 item_dropped 回调中产生另一个请求?更重要的是,我是否以正确的方式进行此操作,还是有更好的方法来完成此操作?我知道我可以从蜘蛛内部进行数据库检查并在那里实现回调逻辑,但我宁愿不要让蜘蛛和管道都打开数据库会话。
【问题讨论】:
标签: python sqlalchemy scrapy