Python实现Movielens数据集下载、MD5校验及压缩包文件列表打印的代码优化
代码补全与优化方案
原有代码的核心问题
- 变量定义顺序颠倒:下载校验文件时,
checksum变量还未被赋值为本地存储路径,直接运行会触发NameError - 缺失MD5校验核心逻辑:没有实现本地文件哈希与官方校验值的比对流程
- 校验值解析逻辑缺失:GroupLens提供的.md5文件格式为「<32位哈希值> <原文件名>」,无法直接读取全文与本地计算结果比对
- 拼写错误:
listOfiles遗漏字母f,代码可读性差 - 无异常容错:网络失败、文件损坏、权限不足等场景会直接抛出原生栈信息,用户无法快速定位问题
补全校验逻辑的实现流程
整体流程严格遵循「先校验、再操作」的要求:
- 先定义所有本地存储的文件名常量,避免变量顺序错误
- 下载数据集压缩包与官方MD5校验文件
- 分块计算本地压缩包的MD5值
- 解析官方校验文件,提取有效32位哈希值
- 比对两个哈希值,一致则继续执行,不一致则清理损坏文件并退出
- 校验通过后,调用封装的
print_zip_files函数读取并打印压缩包内的文件列表
优化后的可运行代码
from zipfile import ZipFile from urllib import request import hashlib import os # 提前定义所有固定常量,避免变量顺序错误 URL_DATASET = "http://files.grouplens.org/datasets/movielens/ml-25m.zip" URL_MD5 = "http://files.grouplens.org/datasets/movielens/ml-25m.zip.md5" LOCAL_DATASET = "ml-25m.zip" LOCAL_MD5_FILE = "ml-25m.zip.md5" def calculate_md5(file_path: str) -> str: """分块读取计算文件MD5,避免大文件占满内存""" hash_md5 = hashlib.md5() with open(file_path, "rb") as f: for chunk in iter(lambda: f.read(4096), b""): hash_md5.update(chunk) return hash_md5.hexdigest() def extract_official_md5(md5_file_path: str) -> str: """从官方MD5文件中提取有效哈希值,适配文件的标准格式""" with open(md5_file_path, "r", encoding="utf-8") as f: # 官方文件格式为 "哈希值 原文件名",拆分后取第一个元素即可 return f.read().strip().split()[0] def print_zip_files(zip_path: str): """校验通过后,读取并打印压缩包内的所有文件名""" with ZipFile(zip_path, "r") as zip_obj: file_list = zip_obj.namelist() for file_name in file_list: print(file_name) if __name__ == "__main__": # 下载目标文件,增加异常捕获 try: request.urlretrieve(URL_DATASET, LOCAL_DATASET) request.urlretrieve(URL_MD5, LOCAL_MD5_FILE) except Exception as e: print(f"文件下载失败:{str(e)}") exit(1) # 执行MD5校验 local_calc_md5 = calculate_md5(LOCAL_DATASET) official_md5 = extract_official_md5(LOCAL_MD5_FILE) if local_calc_md5 != official_md5: print("MD5校验不通过,下载文件已损坏,请重新下载") # 自动清理损坏的无效文件 if os.path.exists(LOCAL_DATASET): os.remove(LOCAL_DATASET) exit(1) print("MD5校验通过,压缩包包含以下文件:") print_zip_files(LOCAL_DATASET)
可进一步优化的方向
- 增加重复下载判断:如果本地已存在对应文件,先计算本地MD5与官方值比对,一致则跳过下载流程,节省带宽
- 增加下载进度提示:通过
urlretrieve的reporthook参数实现下载进度条,提升大文件下载的交互体验 - 替换为HTTPS请求:将原有HTTP地址替换为对应HTTPS地址,避免下载过程被篡改,提升安全性
- 增加压缩包合法性校验:读取文件列表前先判断Zip对象是否正常,避免损坏的非zip文件触发解压错误
- 优化文件存储逻辑:下载过程中先使用临时后缀(如
.tmp)存储文件,校验通过后再重命名为正式文件名,避免用户提前访问未下载完成的文件
内容的提问来源于stack exchange,提问作者user289143
相关产品推荐
相关产品推荐

