Scrapy新手求助:三次GET请求生成Product Item的实现问题
解决Scrapy多请求联动生成Product Item的方案
嘿,作为Scrapy新手碰到这种需要三次GET请求联动生成Item的场景确实有点头大,不过咱们可以通过回调函数+meta传递数据的方式完美解决,思路就是把填充到一半的Item在各个请求之间传递,最后根据库存接口的响应决定是否保存。
整体流程梳理
- 第一步:请求
product_url,获取产品基础数据并填充Item的部分字段 - 第二步:带着已填充部分字段的Item,请求
category_url,补充分类相关字段 - 第三步:带着完整填充的Item,请求
stock_url,根据响应判断是否保存该Item
完整代码示例
import scrapy from your_project.items import ProductItem # 记得替换成你项目的Item类路径 class ProductSpider(scrapy.Spider): name = 'product_spider' def start_requests(self): # 这里可以是单个product_url,也可以是批量的,先以单个为例 product_url = 'https://www.someurl.com/product?' # 初始化空的Product Item item = ProductItem() # 发起第一个请求:产品详情页,把item通过meta传递给回调函数 yield scrapy.Request( url=product_url, callback=self.parse_product, meta={'item': item} ) def parse_product(self, response): # 从meta中取出传递过来的item item = response.meta['item'] # 填充产品相关字段,示例根据实际响应结构调整 item['product_name'] = response.css('h1.product-title::text').get().strip() item['product_price'] = response.css('span.price::text').get().strip() item['product_id'] = response.css('input[name="product_id"]::attr(value)').get() # 假设category_url是从product响应中提取的,或者是固定格式拼接的 category_url = f'https://www.someurl.com/category/{item["product_id"]}' # 发起第二个请求:分类页,继续传递item yield scrapy.Request( url=category_url, callback=self.parse_category, meta={'item': item} ) def parse_category(self, response): item = response.meta['item'] # 填充分类相关字段,示例根据实际响应调整 item['category_name'] = response.css('div.breadcrumb li:last-child a::text').get().strip() item['category_path'] = response.css('div.breadcrumb a::text').getall() # 假设stock_url也是从之前的响应提取或拼接的 stock_url = f'https://www.someurl.com/stock/{item["product_id"]}' # 发起第三个请求:库存查询页 yield scrapy.Request( url=stock_url, callback=self.parse_stock, meta={'item': item} ) def parse_stock(self, response): item = response.meta['item'] # 解析库存响应,这里假设返回的是JSON格式,根据实际情况调整 stock_data = response.json() item['stock_quantity'] = stock_data.get('quantity', 0) # 判断是否保存Item:比如库存大于0才保存 if item['stock_quantity'] > 0: yield item # 保存Item到管道 else: self.logger.info(f"产品{item['product_id']}库存不足,跳过保存")
关键知识点解释
- meta参数:Scrapy的
Request对象中的meta是一个字典,用来在不同的请求和回调之间传递数据,这里我们用它来携带逐步填充的ProductItem,避免重新创建或丢失数据。 - 回调函数链:每个请求的
callback指定下一个要执行的解析函数,形成一个请求→解析→下一个请求的链条,一步步完成Item的填充和判断。 - 库存判断逻辑:在最后一个回调
parse_stock中,根据接口返回的库存数据决定是否yieldItem,只有yield的Item才会进入后续的Item Pipeline进行处理。
如果你的product_url是批量的(比如从文件或数据库读取),只需要在start_requests里循环生成请求即可,每个请求携带自己的空Item就行啦!
内容的提问来源于stack exchange,提问作者hsy
相关产品推荐
相关产品推荐

