如何自定义Scrapy的JSON导出格式,整合店铺与商品数据
问题描述
使用Scrapy爬取商品数据时,默认导出的JSON是字典列表格式,示例如下:
[{"Product Name":"Product1", "Categories":["Clothing","Top"], "Price":"20.5", "Currency":"USD"},...]
但需要导出包含店铺信息的自定义JSON格式,将爬取的商品数据放入Products数组中,示例格式:
{"Shop Name":"Shop 1","Location":"XXXXXXXXX","Contact":"XXXX-XXXXX","Products":[商品字典列表]}
当前爬虫的parse方法代码:
def parse(self, response): for products in response.css('div.single_product'): yield { 'name': products.css('h4.product_name::text').get(), 'price': products.css('span.current_price::text').get(), 'code': products.css('div.single_product').attrib['data-itemcode'], 'url' : urljoin("https://xxxx", products.css('a.image-popup-no-margins').attrib['data-image'] ) }
解决方案
方法1:修改爬虫逻辑,收集所有商品后统一生成最终结构
适合数据量不大的场景,直接在爬虫中收集所有商品数据,最后一次性生成包含店铺信息的完整结构。
修改后的代码:
from scrapy.spiders import Spider from urllib.parse import urljoin import json class YourSpider(Spider): name = 'your_spider_name' start_urls = ['https://your-target-url.com'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.products_list = [] # 存储所有商品的列表 def parse(self, response): for products in response.css('div.single_product'): product = { 'name': products.css('h4.product_name::text').get(), 'price': products.css('span.current_price::text').get(), 'code': products.css('div.single_product').attrib['data-itemcode'], 'url' : urljoin("https://xxxx", products.css('a.image-popup-no-margins').attrib['data-image'] ) } self.products_list.append(product) # 处理分页(如果有) # next_page = response.css('a.next-page::attr(href)').get() # if next_page: # yield response.follow(next_page, self.parse) def closed(self, reason): # 构造最终JSON结构 final_data = { "Shop Name": "Shop 1", "Location": "XXXXXXXXX", "Contact": "XXXX-XXXXX", "Products": self.products_list } # 写入文件 with open('custom_output.json', 'w', encoding='utf-8') as f: json.dump(final_data, f, ensure_ascii=False, indent=4)
方法2:自定义Scrapy导出器
如果需要保留Scrapy命令行导出功能(比如scrapy crawl your_spider -o output.json),可以自定义JSON导出器替换默认逻辑。
步骤1:编写自定义导出器(pipelines.py)
from scrapy.exporters import JsonItemExporter import json class CustomJsonExporter(JsonItemExporter): def __init__(self, file, **kwargs): kwargs['ensure_ascii'] = False super().__init__(file, **kwargs) self.products = [] # 定义固定店铺信息 self.shop_info = { "Shop Name": "Shop 1", "Location": "XXXXXXXXX", "Contact": "XXXX-XXXXX" } def export_item(self, item): self.products.append(dict(item)) def finish_exporting(self): final_data = {**self.shop_info, "Products": self.products} json.dump(final_data, self.file, ensure_ascii=False, indent=4)
步骤2:配置启用导出器(settings.py)
FEED_EXPORTERS = { 'json': 'your_project_name.pipelines.CustomJsonExporter', }
执行导出命令:
scrapy crawl your_spider -o custom_output.json
内容的提问来源于stack exchange,提问作者drowzee
相关产品推荐
相关产品推荐

