You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何通过Python运行Scrapy脚本时JSON导出功能失效?

问题分析与解决办法

为啥JSON文件没生成?

核心问题是工作目录不匹配:你直接运行Python脚本时,os.system()执行命令的当前工作路径,未必是你脚本所在的文件夹。比如你双击脚本运行,test.json可能生成在系统默认的工作目录(比如用户根目录),而不是脚本所在位置,看起来就像没生成一样。

另外,你已经导入了CrawlerProcess却没用上,这其实是Scrapy官方推荐的直接运行脚本的方式,比调用系统命令靠谱得多,还能避免这类路径坑。

办法1:给os.system指定工作目录

先切换到脚本所在的目录再执行命令,就能保证文件生成在你预期的位置:

import os
import scrapy
from scrapy.crawler import CrawlerProcess

# 你的爬虫类代码保持不变...

# 获取脚本的绝对路径所在目录
script_folder = os.path.dirname(os.path.abspath(__file__))
# 切换到该目录
os.chdir(script_folder)
# 执行导出命令
os.system("scrapy crawl preorder -O test.json")

办法2:用CrawlerProcess启动(强烈推荐)

这是Scrapy官方认可的直接运行脚本的方式,全程在Python代码里配置,不用依赖终端命令,还能灵活调整导出设置:

import scrapy
from scrapy.crawler import CrawlerProcess

class PreOrderSpider(scrapy.Spider): 
    name = 'preorder'
    start_urls = ['https://www.kapowtoys.co.uk/category/preorders.html']

    def parse(self, response):
        for products in response.css('li.product'):
            try:
                yield{
                    'name': products.css('h2::text').get(),
                    'price': products.css('ins::text').get().replace('£',''),
                    'link': products.css('a').attrib['href'],
                }
            except AttributeError:  # 捕获具体异常,别用裸except
                yield{
                    'name': products.css('h2::text').get(),
                    'price': 'unavailable', 
                    'link': products.css('a').attrib['href'],
                }

        # 用get方法避免找不到下一页按钮时抛错
        next_page = response.css('a.next.page-numbers').attrib.get('href')
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

if __name__ == "__main__":
    # 配置爬虫进程,设置导出规则
    process = CrawlerProcess(settings={
        "FEEDS": {
            "test.json": {"format": "json", "overwrite": True},  # overwrite对应终端的-O
        },
    })
    process.crawl(PreOrderSpider)
    process.start()

补充说明:

  • FEEDS是Scrapy 2.1及以上版本的特性,用来配置导出文件,overwrite: True等同于终端命令的-O(覆盖已有文件),如果要追加内容就改成overwrite: False(对应终端的-o)。
  • 用if __name__ == "__main__":包裹启动代码,防止脚本被其他文件导入时自动执行。
  • 把原来的裸except:改成except AttributeError:,只捕获你预期的异常(比如价格元素不存在导致的属性错误),避免隐藏其他未知问题。

内容的提问来源于stack exchange,提问作者GagGreene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:55:35