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

