为何通过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
相关产品推荐
相关产品推荐

