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

Scrapy项目无法用Pandas导出爬取数据至Excel的问题排查

问题排查与修复方案

核心问题分析

  1. 列名大小写不匹配:
    你的item字典键是小写的plate、price,但创建DataFrame时指定的列名是大写的PLATE、PRICE,Pandas无法匹配对应数据,导致生成空DataFrame,写入Excel自然没有内容。

  2. 全局变量导致的异步冲突:
    使用全局变量plate_num_xlsx传递车牌值,Scrapy是异步爬虫,多个请求并行处理时,全局变量会被后续请求覆盖,导致parse方法里的判断逻辑完全失效,无法正确匹配目标车牌。

  3. 循环中item被覆盖:
    在parse的循环里,每次迭代都会重新赋值item,最后只有循环最后一次的item会被处理,前面的结果全部丢失。

  4. 重复写入覆盖数据:
    每个请求的parse方法都会执行一次to_excel,直接覆盖之前的文件,最终只会保留最后一个请求的结果,甚至可能因异步写入导致文件损坏。

修复后的完整代码

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

class plateScraper(scrapy.Spider):
    name = 'scrapePlate'
    allowed_domains = ['dvlaregistrations.direct.gov.uk']
    # 用类变量存储所有结果,避免重复写入
    results = []

    def start_requests(self):
        df = pd.read_excel('data.xlsx')
        columnA_values = df['PLATE']
        for plate_num in columnA_values:
            # 将车牌作为meta参数传递给parse,替代全局变量
            base_url = f"https://dvlaregistrations.dvla.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="
            yield scrapy.Request(url=base_url, meta={'target_plate': plate_num})

    def parse(self, response):
        target_plate = response.meta['target_plate']
        found = False
        for row in response.css('div.resultsstrip'):
            plate = row.css('a::text').get()
            price = row.css('p::text').get()
            if not plate:
                continue
            cleaned_plate = plate.replace(" ", "").strip()
            # 匹配目标车牌
            if cleaned_plate == target_plate:
                self.results.append({
                    "PLATE": plate.strip(),
                    "PRICE": price.strip() if price else "-"
                })
                found = True
                break  # 找到目标后退出循环,提升效率
        # 如果没找到目标车牌,记录空价格
        if not found:
            self.results.append({
                "PLATE": target_plate,
                "PRICE": "-"
            })

    def closed(self, reason):
        # 爬虫结束后统一写入Excel,避免覆盖
        df_output = pd.DataFrame(self.results)
        df_output.to_excel("output_res.xlsx", sheet_name="result", index=False, header=True)

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

关键修复点说明

  • 用meta传递参数:把目标车牌通过Request的meta参数传给parse,避免全局变量的异步冲突,确保每个请求处理时拿到自己对应的车牌。
  • 统一存储结果:用类变量results收集所有爬取结果,爬虫结束后通过closed方法统一写入Excel,避免重复覆盖。
  • 列名匹配:item的键直接使用大写的PLATE、PRICE,和DataFrame列名保持一致,确保数据能正确映射。
  • 增加容错处理:判断plate是否存在,避免空值引发错误;没找到目标车牌时主动记录,保证所有输入车牌都有对应结果。

内容的提问来源于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 05:55:17