指定文件扩展名的Python URL文件下载代码及CSV损坏问题求助
问题分析与修复方案
你的代码能完成下载但生成的CSV文件损坏,大概率是这几个原因:
- 目标URL返回的不是纯CSV内容(比如是压缩包、网页源码)
- 保存路径没指定正确的CSV文件名,或者路径是文件夹导致写入异常
- 读取CSV时没匹配正确的编码,误以为文件损坏
先做排查步骤
- 先确认URL返回的内容类型:在
response = requests.get(...)后加一行print(response.headers.get('Content-Type')),看输出是text/csv(纯CSV)还是application/gzip(压缩包)这类。 - 检查
save_path是否是带.csv后缀的具体文件名,而不是文件夹路径。
修复后的单个CSV下载代码
这个版本会自动处理文件名、创建目录,还会验证CSV是否能正常读取:
import requests import os from tqdm import tqdm import pandas as pd def download_main( url, save_dir="/home/mohammed/spatialprot/store", file_format="csv" ): try: # 自动创建保存目录(不存在就新建) os.makedirs(save_dir, exist_ok=True) # 发送HTTP请求 response = requests.get(url, stream=True) response.raise_for_status() # 捕获请求错误 # 自动获取文件名:优先从URL提取,不行就从响应头取 filename = url.split('/')[-1] if not filename.endswith(f'.{file_format}'): content_disposition = response.headers.get('Content-Disposition') if content_disposition: filename = content_disposition.split('filename=')[-1].strip('"') else: filename = f'downloaded_file.{file_format}' # 拼接完整保存路径 save_path = os.path.join(save_dir, filename) # 分块写入文件,避免内存溢出 with open(save_path, "wb") as file: for chunk in tqdm(response.iter_content(chunk_size=8192)): if chunk: file.write(chunk) print(f"下载完成:{url},保存至:{save_path}") # 验证CSV文件是否完好 try: csv_df = pd.read_csv(save_path, encoding='utf-8') print(f"CSV验证成功,共{len(csv_df)}行数据") except UnicodeDecodeError: # 换编码重试(比如latin-1是常见兼容编码) csv_df = pd.read_csv(save_path, encoding='latin-1') print(f"用latin-1编码读取成功,共{len(csv_df)}行数据") except Exception as e: print(f"CSV验证失败:{e},文件可能不是纯CSV格式") except requests.exceptions.RequestException as e: print(f"请求出错:{e}") except Exception as e: print(f"其他错误:{e}")
如果URL返回的是包含CSV的压缩包(比如tar.gz)
用下面的代码先下载压缩包,再提取里面的CSV文件:
import requests import os import tarfile from tqdm import tqdm def download_and_extract_csv( url, save_dir="/home/mohammed/spatialprot/store" ): try: os.makedirs(save_dir, exist_ok=True) # 先下载临时压缩包 temp_tar_path = os.path.join(save_dir, 'temp.tar.gz') response = requests.get(url, stream=True) response.raise_for_status() with open(temp_tar_path, "wb") as file: for chunk in tqdm(response.iter_content(chunk_size=8192)): if chunk: file.write(chunk) # 解压并提取所有CSV文件 with tarfile.open(temp_tar_path, 'r:gz') as tar: for member in tar.getmembers(): if member.name.endswith('.csv'): tar.extract(member, save_dir) print(f"提取CSV:{member.name} 到 {save_dir}") # 删除临时压缩包 os.remove(temp_tar_path) print("临时压缩包已清理") except requests.exceptions.RequestException as e: print(f"请求出错:{e}") except tarfile.TarError as e: print(f"解压失败:{e},可能不是tar.gz格式") except Exception as e: print(f"其他错误:{e}")
使用说明
- 如果目标URL是单个CSV文件,直接调用
download_main("你的CSV URL") - 如果是tar.gz压缩包,调用
download_and_extract_csv("你的压缩包URL")
内容的提问来源于stack exchange,提问作者Mohammed Zidane
相关产品推荐
相关产品推荐

