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

Scrapy爬取数据生成DataFrame时提示df未定义如何解决

Scrapy爬取结果转DataFrame报错修复方案

代码核心错误点

name 'df' is not defined只是表层报错,代码存在多层逻辑和语法问题:

  • 变量作用域错误:items列表定义在文章遍历的for循环内部,若页面CSS选择器未匹配到对应元素(比如原代码设置的起始页是网站首页,根本没有div.list_article_detail节点),循环不会执行,items变量根本不会被创建,后续调用items生成df时就会触发未定义错误;就算循环执行,每次循环都会把items重置为空列表,之前存储的数据会被直接覆盖。
  • 执行逻辑错位:Scrapy的parse方法是异步回调函数,每个分页请求返回后都会独立执行一次parse,把生成DataFrame的逻辑写在parse内部,会导致每加载一个分页就尝试生成一次df,根本无法聚合全量爬取数据。
  • 爬取逻辑漏洞:
    • 文章遍历循环内提取到item后没有做追加操作,循环结束后只会保留最后一篇文章的信息,前面的内容全部丢失
    • 文章链接硬编码为栏目固定地址,没有提取每篇文章对应的真实跳转url
    • 分页追加数据的逻辑和文章提取逻辑完全脱节,追加的永远是最后一次循环生成的单条item,完全无法收集全部分页数据
  • 依赖缺失:代码使用pandas生成DataFrame,但没有提前导入pandas库。

标准修复方案

Scrapy官方推荐使用Item Pipeline做爬取后的数据聚合处理,不要在parse回调中直接维护全局列表或生成DataFrame,避免异步执行导致的数据错乱、变量未定义问题。

1. 修正爬虫核心逻辑

import scrapy

class LaquotidienneSpider(scrapy.Spider):
    name = 'laquotidienne'
    # 修正起始地址,和后续分页规则保持一致,从经济栏目第一页开始爬取
    start_urls = ['https://laquotidienne.ma/articles/economie/1']

    def parse(self, response):
        # 遍历当前页所有文章条目
        for article in response.css('div.list_article_detail'):
            raw_link = article.css('a::attr(href)').get()
            item = {
                "title": article.css('a::text').get().replace('\n', ' ').strip(),
                "link": response.urljoin(raw_link),  # 自动补全文章相对链接为绝对地址
                "date": article.css('span::text').get().strip() if article.css('span::text').get() else None
            }
            # 单条数据提取完成后直接yield交给pipeline处理,不需要本地维护列表
            yield item

        # 分页逻辑:基于当前页码生成下一页地址,最多爬取到500页
        current_page_num = int(response.url.rstrip('/').split('/')[-1])
        if current_page_num < 500:
            next_page = f"https://laquotidienne.ma/articles/economie/{current_page_num + 1}"
            yield response.follow(next_page, callback=self.parse)

2. 编写Pipeline聚合数据生成DataFrame

打开项目下的pipelines.py文件,添加如下处理逻辑:

import pandas as pd

class LaquotidienneDataPipeline:
    def open_spider(self, spider):
        # 爬虫启动时初始化空列表,用于存储所有爬取到的条目
        self.all_articles = []

    def process_item(self, item, spider):
        # 每接收到一条爬取数据就追加到列表
        self.all_articles.append(dict(item))
        return item

    def close_spider(self, spider):
        # 所有爬取任务完成后,统一生成包含title、link、date三列的DataFrame
        df = pd.DataFrame(self.all_articles, columns=['title', 'link', 'date'])
        # 可按需将结果存储为csv文件
        df.to_csv('laquotidienne_eco_articles.csv', index=False, encoding='utf-8-sig')
        # 如需外部调用df,可将其绑定到spider实例属性
        spider.result_df = df

3. 开启Pipeline配置

打开项目下的settings.py文件,找到ITEM_PIPELINES配置项,取消注释并添加自定义pipeline:

ITEM_PIPELINES = {
   '替换为你的项目名称.pipelines.LaquotidienneDataPipeline': 300,
}

注意:不要尝试在parse方法中用全局变量收集数据,Scrapy的异步调度机制会导致数据重复、丢失,甚至触发跨线程变量访问错误,使用pipeline聚合数据是最稳定的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:39:20