Scrapy项目无法用Pandas导出爬取数据至Excel的问题排查
问题排查与修复方案
核心问题分析
列名大小写不匹配:
你的item字典键是小写的plate、price,但创建DataFrame时指定的列名是大写的PLATE、PRICE,Pandas无法匹配对应数据,导致生成空DataFrame,写入Excel自然没有内容。全局变量导致的异步冲突:
使用全局变量plate_num_xlsx传递车牌值,Scrapy是异步爬虫,多个请求并行处理时,全局变量会被后续请求覆盖,导致parse方法里的判断逻辑完全失效,无法正确匹配目标车牌。循环中item被覆盖:
在parse的循环里,每次迭代都会重新赋值item,最后只有循环最后一次的item会被处理,前面的结果全部丢失。重复写入覆盖数据:
每个请求的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=¤tmatches=&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
相关产品推荐
相关产品推荐

