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

Python OOP水果爬虫无法访问listify函数,报NameError错误求助

问题分析与修复

直接报错原因

你调用Listified_info = FruitScraper().listify(family)时,family这个变量根本没定义,所以抛出NameError。更关键的是,你每次调用FruitScraper()都会创建一个全新的类实例,三个实例(对应Scraped_info、Listified_info、Fruits_statistics)的属性完全独立,数据不会共享,这会导致后续统计功能完全失效。

代码里的其他问题

  • scrape_all_fruits里的except:捕获所有异常,会掩盖请求失败、JSON解析错误等问题,不利于调试。
  • listify函数里把scrape_all_fruits()的结果先转成JSON字符串再解析回来,完全是多余操作,直接用返回的列表就行。
  • listify的参数stats设计不合理,实际只是原样返回传入的参数,逻辑混乱。
  • get_summary里的for i in self.listify(...):循环完全没必要,循环一次就直接return,根本没用到循环变量。

修复后的完整代码

import requests
import json

class FruitScraper():
    def __init__(self):
        self.name = []
        self.id = []
        self.family = []
        self.genus = []
        self.order = []
        self.carbohydrates = []
        self.protein = []
        self.fat = []
        self.calories = []
        self.sugar = []

    def scrape_all_fruits(self):
        data_list = []
        for fruit_id in range(1, 10):
            url = f'https://www.fruityvice.com/api/fruit/{fruit_id}'
            try:
                response = requests.get(url)
                response.raise_for_status()  # 主动抛出HTTP错误
                data = response.json()
                data_list.append(data)
            except requests.exceptions.RequestException as e:
                print(f"请求ID为{fruit_id}的水果数据失败: {e}")
            except json.JSONDecodeError as e:
                print(f"解析ID为{fruit_id}的水果数据失败: {e}")
        return data_list

    def listify(self):
        # 直接使用scrape_all_fruits返回的列表,移除冗余JSON转换
        data_list = self.scrape_all_fruits()
        for fruit_data in data_list:
            try:
                self.name.append(fruit_data['name'])
                self.id.append(fruit_data['id'])
                self.family.append(fruit_data['family'])
                self.genus.append(fruit_data['genus'])
                self.order.append(fruit_data['order'])
                # 处理营养数据
                nutritions = fruit_data['nutritions']
                self.carbohydrates.append(nutritions['carbohydrates'])
                self.protein.append(nutritions['protein'])
                self.fat.append(nutritions['fat'])
                self.calories.append(nutritions['calories'])
                self.sugar.append(nutritions['sugar'])
            except KeyError as e:
                print(f"水果数据缺少字段: {e}")

    def get_summary(self):
        # 先确保数据已加载,未加载则自动调用listify
        if not self.name:
            self.listify()
        
        # 计算并拼接统计结果
        max_stats = (
            f"\nNutrients maximum statistics:\n"
            f"Fat: {max(self.fat)}\n"
            f"Protein: {max(self.protein)}\n"
            f"Carbohydrates: {max(self.carbohydrates)}\n"
            f"Calories: {max(self.calories)}\n"
            f"Sugar: {max(self.sugar)}"
        )
        min_stats = (
            f"\nNutrients minimum statistics:\n"
            f"Fat: {min(self.fat)}\n"
            f"Protein: {min(self.protein)}\n"
            f"Carbohydrates: {min(self.carbohydrates)}\n"
            f"Calories: {min(self.calories)}\n"
            f"Sugar: {min(self.sugar)}"
        )
        total = f"\nTotal fruits scraped: {len(self.name)}"
        
        return max_stats + min_stats + total

# 只创建一个实例,所有操作基于同一个实例保证数据共享
scraper = FruitScraper()
scraper.listify()
fruit_stats = scraper.get_summary()
print(fruit_stats)

关键修改说明

  1. 解决实例数据不共享问题:只创建一个FruitScraper实例,所有数据操作都基于这个实例,确保属性数据能被后续方法访问。
  2. 修复NameError:移除listify的冗余参数,调用时直接执行scraper.listify()即可。
  3. 优化异常处理:替换宽泛的except:为捕获具体异常,添加response.raise_for_status()捕获HTTP请求错误,便于定位问题。
  4. 移除冗余操作:去掉不必要的JSON字符串转换,直接使用scrape_all_fruits返回的列表数据。
  5. 重构统计逻辑:在get_summary中先检查数据是否已加载,自动触发数据加载;移除无用循环,直接计算并拼接统计结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:10:30