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

如何重构循环使Scrapy爬虫所有迭代数据都存入Excel

问题根因
  • 你将Scrapy爬虫类QuotesSpider的定义写在了while循环内部,每次迭代都会重新定义同名爬虫类,前两次迭代生成的类会被最后一次(i=2)的定义直接覆盖,Scrapy运行时只会执行最后一次的爬取逻辑,自然只能拿到i=2对应的结果。
  • Excel写入逻辑嵌套层级错误:写文件操作被放在遍历页面元素的内层循环中,每次写入都会重新打开文件句柄,且startrow参数没有动态累计已写入行数,很容易出现内容互相覆盖的问题。
  • Scrapy本身自带任务调度逻辑,不需要手动写while循环逐个传入URL,批量传入待爬地址后框架会自动完成逐个请求、解析的流程,手动写循环反而会破坏框架的运行逻辑。
修正后代码
import pandas as pd
import scrapy
from scrapy.crawler import CrawlerProcess

# 读取Stata数据源
auto = pd.read_stata(r"D:\StataCopies\workersurlsSample.dta")
df = pd.DataFrame(auto)
save_path = r'C:\Users\nglew\Desktop\writingpractice2.xlsx'

class QuotesSpider(scrapy.Spider):
    name = "qid_spider"
    # 直接批量传入3个待爬URL,无需手动循环控制
    start_urls = df.iloc[:3, 3].tolist()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 初始化全局结果存储列表,所有页面的解析结果统一存在这里
        self.result_list = []

    def parse(self, response):
        # 解析当前页面的目标QID
        raw_id = response.css('span.wikibase-title span.wikibase-title-id::text').get()
        if raw_id:
            clean_id = raw_id.replace('(', '').replace(')', '')
            self.result_list.append({"wiki_qid": clean_id})

    def closed(self, reason):
        # 所有爬取任务结束后,一次性写入全部结果,避免反复操作文件导致的覆盖问题
        res_df = pd.DataFrame(self.result_list)
        with pd.ExcelWriter(save_path, engine="openpyxl") as writer:
            res_df.to_excel(writer, sheet_name='Sheet1', index=False)

if __name__ == "__main__":
    # 初始化爬虫运行进程
    runner = CrawlerProcess(settings={
        "LOG_LEVEL": "WARNING",
        "ROBOTSTXT_OBEY": False
    })
    runner.crawl(QuotesSpider)
    runner.start()
关键调整点
  • 移除了外层冗余的while循环,将3个待爬URL直接转为列表传入start_urls,交给Scrapy调度器自动完成爬取,从根源避免了类重复定义被覆盖的问题。
  • 用爬虫实例属性self.result_list统一存储所有页面的解析结果,不会因为单次请求的方法执行结束就丢失之前的数据。
  • 将Excel写入逻辑移到爬虫的closed生命周期方法中,等所有页面爬取完成后一次性写入文件,不需要在爬取过程中反复打开、关闭文件,也不需要手动计算写入行号,不会出现内容覆盖的问题。
  • 如果需要在已有Excel文件的基础上追加数据,只需要修改ExcelWriter的参数即可:先读取现有文件的已写入行数,将mode设为a、if_sheet_exists设为overlay,把startrow设为现有数据的总行数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:51:20