使用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
相关产品推荐
相关产品推荐

