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

如何通过单脚本运行多个Scrapy爬虫并分别保存至独立CSV文件

问题描述

我正在使用Scrapy编写脚本爬取自身网站,当前运行8个独立脚本分别爬取各个集合,并将数据保存至对应的CSV文件(如集合1保存至collection-1.csv等)。请问是否可通过一个脚本运行多个爬虫,且将爬取的数据分别保存至独立文件?

现有脚本
import scrapy
from scrapy.crawler import CrawlerProcess
import csv

cs = open('results/collection-1-results.csv', 'w', newline="", encoding='utf-8')
header_names = ['stk','name','price','url']
csv_writer = csv.DictWriter(cs, fieldnames=header_names)
csv_writer.writeheader()

class XXX(scrapy.Spider):
    name = 'XXX'
    start_urls = [
    'website-url.com'
    ]

    def parse(self,response):
        product_urls  = response.css('div.grid-uniform a.product-grid-item::attr(href)').extract()

        for product_url in product_urls:
            yield scrapy.Request(url='website-url.com'+product_url,callback=self.next_parse_two)

        next_url  = response.css('ul.pagination-custom li a[title="Next »"]::attr(href)').get()
        if next_url != None:
            yield scrapy.Request(url='website-url.com'+next_url,callback=self.parse)

    def next_parse_two(self,response):
        item = dict()
        item['stk'] = response.css('script#swym-snippet::text').get().split('stk:')[1].split(',')[0]
        item['name'] = response.css('h1.h2::text').get()
        item['price'] =response.css('span#productPrice-product-template span.visually-hidden::text').get()
        item['url'] = response.url
        csv_writer.writerow(item)
        cs.flush()

process = CrawlerProcess({
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})

process.crawl(XXX)
process.start()
解决方案

完全可以通过一个脚本运行多个爬虫并分别保存数据,推荐使用Scrapy官方的Feed Exports功能替代手动操作CSV文件,避免多线程下的文件冲突,同时简化代码维护。具体实现步骤如下:

1. 提取公共爬虫逻辑

创建一个基础爬虫类,把各个集合爬虫的通用逻辑(如列表页解析、详情页解析)放在这里,避免重复代码:

import scrapy
from scrapy.crawler import CrawlerProcess

class BaseCollectionSpider(scrapy.Spider):
    def parse(self, response):
        # 解析列表页的产品链接
        product_urls = response.css('div.grid-uniform a.product-grid-item::attr(href)').extract()
        for product_url in product_urls:
            yield scrapy.Request(url=f'website-url.com{product_url}', callback=self.next_parse_two)
        
        # 处理分页
        next_url = response.css('ul.pagination-custom li a[title="Next »"]::attr(href)').get()
        if next_url:
            yield scrapy.Request(url=f'website-url.com{next_url}', callback=self.parse)

    def next_parse_two(self, response):
        # 解析详情页数据并返回Item
        item = dict()
        item['stk'] = response.css('script#swym-snippet::text').get().split('stk:')[1].split(',')[0]
        item['name'] = response.css('h1.h2::text').get()
        item['price'] = response.css('span#productPrice-product-template span.visually-hidden::text').get()
        item['url'] = response.url
        yield item

2. 定义各个集合的爬虫

每个集合对应一个爬虫类,仅需指定唯一的name和对应的start_urls:

# 集合1爬虫
class Collection1Spider(BaseCollectionSpider):
    name = 'collection1'
    start_urls = ['website-url.com/collection1']

# 集合2爬虫
class Collection2Spider(BaseCollectionSpider):
    name = 'collection2'
    start_urls = ['website-url.com/collection2']

# 继续定义Collection3到Collection8的爬虫,以此类推...

3. 配置爬虫进程与输出

使用CrawlerProcess配置全局Feed输出规则,自动根据爬虫名称生成对应CSV文件;也可以为每个爬虫单独配置输出路径:

方式一:全局统一配置

process = CrawlerProcess({
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
    'FEEDS': {
        # 用%(name)s变量匹配爬虫name,自动生成对应文件名
        'results/collection-%(name)s-results.csv': {
            'format': 'csv',
            'fields': ['stk', 'name', 'price', 'url'],
            'overwrite': True,
            'encoding': 'utf-8'
        }
    }
})

# 添加所有爬虫到进程
process.crawl(Collection1Spider)
process.crawl(Collection2Spider)
# 依次添加Collection3到Collection8...

process.start()

方式二:单个爬虫单独配置

如果需要为不同爬虫指定不同的输出路径,可在process.crawl()时单独传入配置:

process = CrawlerProcess({
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})

# 集合1爬虫指定输出到collection-1.csv
process.crawl(Collection1Spider, settings={
    'FEEDS': {
        'results/collection-1-results.csv': {
            'format': 'csv',
            'fields': ['stk', 'name', 'price', 'url'],
            'overwrite': True,
            'encoding': 'utf-8'
        }
    }
})

# 集合2爬虫指定输出到collection-2.csv
process.crawl(Collection2Spider, settings={
    'FEEDS': {
        'results/collection-2-results.csv': {
            'format': 'csv',
            'fields': ['stk', 'name', 'price', 'url'],
            'overwrite': True,
            'encoding': 'utf-8'
        }
    }
})

# 继续配置其他爬虫...

process.start()

优势说明

  • 避免手动操作文件对象带来的线程安全问题,Feed Exports由Scrapy内部处理,更稳定可靠。
  • 代码复用性更高,公共逻辑只需维护一次,新增集合爬虫只需继承基础类并配置少量参数。
  • 输出配置灵活,可全局统一或单独定制,满足不同需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:15:39