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

Scrapy脚本中Pandas写入Excel无法追加,总是覆盖行的问题解决

问题原因分析
  1. Excel写入位置未指定:使用mode='a'和if_sheet_exists='overlay'时,pandas默认从工作表第2行(表头行之后)开始写入新数据,每次parse方法执行都会覆盖该位置起始的行,而非追加到现有数据末尾。
  2. 全局变量异步冲突:plate_num_xlsx作为全局变量,Scrapy异步处理多个请求时,后续请求会覆盖该变量值,导致plate_num_xlsx==plate.replace(" ","").strip()的匹配逻辑出错,数据对应关系混乱。
  3. 频繁IO操作隐患:每个请求的parse阶段都打开并写入Excel文件,不仅效率低下,还可能因异步并发写入导致数据覆盖或损坏。
修复方案

核心修改点

  • 用Scrapy的meta参数传递车牌号码,替代全局变量,避免异步冲突。
  • 统一收集所有爬取到的数据,在爬虫结束时一次性写入Excel,实现真正的追加功能。

修改后的完整代码

import scrapy
from scrapy.crawler import CrawlerProcess
import pandas as pd

class plateScraper(scrapy.Spider):
    name = 'scrapePlate'
    allowed_domains = ['dvlaregistrations.direct.gov.uk']
    # 类变量,用于统一收集所有爬取到的item
    all_items = []

    def start_requests(self):
        df = pd.read_excel('data.xlsx')
        columnA_values = df['PLATE']
        for plate_num in columnA_values:
            base_url = f"https://dvlaregistrations.direct.gov.uk/search/results.html?search={plate_num}&action=index&pricefrom=0&priceto=&prefixmatches=&currentmatches=&limitprefix=&limitcurrent=&limitauction=&searched=true&openoption=&language=en&prefix2=Search&super=&super_pricefrom=&super_priceto="
            # 通过meta传递当前车牌号码,避免全局变量冲突
            yield scrapy.Request(url=base_url, meta={'plate_num': plate_num})

    def parse(self, response):
        plate_num = response.meta['plate_num']
        for row in response.css('div.resultsstrip'):
            plate = row.css('a::text').get()
            price = row.css('p::text').get()
            
            if plate_num == plate.replace(" ", "").strip():
                item = {"plate": plate.strip(), "price": price.strip()}
            else:
                item = {"plate": plate.strip(), "price": "-"}
            
            self.all_items.append(item)
            yield item

    def closed(self, reason):
        """爬虫结束时执行的方法,统一写入数据到Excel"""
        df_output = pd.DataFrame(self.all_items)
        
        try:
            # 读取现有Excel文件中的数据
            existing_df = pd.read_excel('output_res.xlsx', sheet_name='result')
            # 合并现有数据与新爬取数据
            combined_df = pd.concat([existing_df, df_output], ignore_index=True)
        except FileNotFoundError:
            # 如果文件不存在,直接使用新爬取的数据
            combined_df = df_output
        
        # 写入Excel
        combined_df.to_excel('output_res.xlsx', sheet_name='result', index=False)

process = CrawlerProcess()
process.crawl(plateScraper)
process.start()

关键细节说明

  1. meta参数传递:在start_requests中,将当前循环的车牌号码通过meta字典传递给请求,在parse方法中从response.meta取出,确保每个请求处理的车牌号码唯一且不被覆盖。
  2. 统一收集数据:使用类变量all_items存储所有爬取到的item,避免每次请求都写入Excel,提升效率并避免并发写入问题。
  3. 爬虫关闭时写入:重写closed方法,在爬虫结束时先尝试读取现有Excel数据(如果存在),将新数据追加到现有数据后再写入;若文件不存在则直接写入新数据,实现真正的追加效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:10:30