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

使用json.load和json.loads触发两类TypeError错误的问题求助

问题原因定位

第一个报错(json.loads 触发 TypeError)

  • 原因:json.loads() 方法要求输入参数为JSON格式的字符串、bytes或bytearray类型,你之前直接将open()返回的文件对象(TextIOWrapper类型)传入,类型不匹配就会抛出该错误。

第二个报错(json.load 触发 TypeError)

  • 原因:json.load() 是直接接收文件对象解析JSON的正确方法,你切换后报错是因为你提取出的JSON文件根结构是列表,不是你预设的字典。你直接用data['url']试图用字符串键取列表的值,不符合列表的访问规则,因此触发该错误。
其他隐藏问题

除了JSON解析的问题外,你的代码还存在多个逻辑错误:

  • 后缀判断逻辑错误:for ft in ".zip" 会遍历字符串的每个字符,只要文件名包含./z/i/p任意一个字符就会进入ZIP处理逻辑,并非你想要的判断文件后缀为.zip
  • 资源泄漏:多处open()打开文件后未手动关闭,也未使用上下文管理器托管
  • 重复打开ZIP文件:已经实例化ZipFile对象后又重复打开同个ZIP文件,无意义且浪费资源
  • 结果覆盖:每次匹配到内容都用w+模式打开输出文件,之前的匹配结果会被直接覆盖
  • 递归栈溢出风险:用户输入空搜索词时直接递归实例化fileSearcher,多次输入空会触发栈溢出
  • 魔术方法直接调用:直接调用__contains__不符合Python编码规范,建议用in关键字替代
修复方案

下面是修复后的完整代码,已解决所有上述问题:

import os
import json
from zipfile import ZipFile

class fileSearcher:
    def __init__(self):
        self.directory = "my directory"
        # 替换递归逻辑为循环获取合法输入
        while True:
            self.word = input('Input the word you want to search for: ').strip()
            if self.word:
                break
        self.main()

    def main(self):
        # 输出文件改用追加模式,避免覆盖之前的结果
        with open("search_result.txt", "a+", encoding="utf-8") as out_f:
            for subdir, dirs, files in os.walk(self.directory):
                for file in files:
                    filepath = os.path.join(subdir, file)
                    # 修复后缀判断逻辑
                    if filepath.lower().endswith(".zip"):
                        with ZipFile(filepath, 'r') as zip_ref:
                            for file2 in zip_ref.namelist():
                                if "https" in file2:
                                    zip_ref.extract(file2, os.getcwd())
                                    # 用上下文管理器打开JSON文件,自动释放资源
                                    with open(file2, 'r', encoding="utf-8") as json_f:
                                        data = json.load(json_f)
                                    # 先判断data类型再处理,适配列表/字典两种结构
                                    url_list = []
                                    if isinstance(data, dict):
                                        url_list = data.get('url', [])
                                        # 如果url是单个字符串而非列表,统一转成列表处理
                                        if isinstance(url_list, str):
                                            url_list = [url_list]
                                    elif isinstance(data, list):
                                        # 如果根是列表,遍历每个元素取url字段
                                        for item in data:
                                            if isinstance(item, dict) and 'url' in item:
                                                url_val = item['url']
                                                if isinstance(url_val, str):
                                                    url_list.append(url_val)
                                                elif isinstance(url_val, list):
                                                    url_list.extend(url_val)
                                    # 遍历匹配关键词
                                    for url in url_list:
                                        if self.word in url:
                                            out_f.write(f"{self.word}: {url}\n")
                                    # 可选:用完就删除提取的临时文件,避免占用磁盘
                                    if os.path.exists(file2):
                                        os.remove(file2)

if __name__ == "__main__":
    fileSearcher()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:54:04