Python借助requests与bs4下载无content-disposition头的.torrent文件方法
适配无
content-disposition响应头的文件下载逻辑 目标服务器未在torrent资源的响应中返回content-disposition字段属于正常的服务端配置,该字段本身是可选配置,作用是告知浏览器下载时的默认文件名。缺失该字段时,完全可以从资源的目标URL中自行提取文件名,不需要依赖服务端返回。
调整思路
- 保留原有优先解析响应头文件名的逻辑,兼容后续服务端配置变更的场景
- 新增URL路径提取文件名的兜底逻辑,直接取目标资源URL的路径最后一段作为文件名,对齐主流浏览器的默认下载行为
- 修正原有代码中重复实例化类对象、正则匹配输入对象错误的问题,增加分块写入能力适配后续大文件下载场景
修改后可运行代码
from urllib.parse import urlparse import requests from bs4 import BeautifulSoup import traceback import re class Download_Kali: def __init__(self, locator): self.locator = locator self.torrent_url = None def locate_torrent(self): torrent_links = [torrent['href'] for torrent in self.locator.findAll('a', string='Torrent')] for live_iso in torrent_links: if 'live-amd64' in live_iso: print('[*] Downloading iso Torrent') self.torrent_url = live_iso return live_iso def install(self): try: target_url = self.locate_torrent() with requests.get(target_url, stream=True) as torrent_response: torrent_response.raise_for_status() # 优先尝试从响应头解析文件名 disposition = torrent_response.headers.get('content-disposition', '') torrent_file_name = re.findall(r'filename="(.+)"', disposition) # 无响应头文件名时,从URL提取作为兜底 if not torrent_file_name: parsed_url = urlparse(target_url) torrent_file_name = [parsed_url.path.split('/')[-1]] # 分块写入文件,避免内存占用过高 with open(torrent_file_name[0], 'wb') as f_torrent: for chunk in torrent_response.iter_content(chunk_size=8192): if chunk: f_torrent.write(chunk) print(f'[+] Torrent文件已保存为: {torrent_file_name[0]}') except Exception as err: print(traceback.format_exc())
效果说明
- 不管服务端是否返回
content-disposition字段,都能正确提取到类似kali-linux-2024.1-live-amd64.iso.torrent的正确文件名 - 分块写入逻辑可以直接复用在后续直接下载大体积ISO镜像的场景,不需要修改核心下载逻辑
- 异常捕获范围调整为全流程异常,避免非HTTP类错误(比如文件写入权限问题)导致的脚本直接崩溃
内容的提问来源于stack exchange,提问作者Matt Millar
相关产品推荐
相关产品推荐

