You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

程序化下载的MIDI文件无法播放,手动下载正常的问题排查

问题原因分析

从你提供的十六进制dump能一眼看出核心问题——你下载的根本不是MIDI文件,而是网页的HTML代码!程序化下载的文件开头是<!DOCTYPE html>(对应十六进制里的3c 21 44 4f 43 54 59 50),而标准MIDI文件的固定开头是MThd(对应十六进制4d 54 68 64),这就是文件无法播放的直接原因。

你的代码逻辑错误在于:循环访问的base_url + str(i)是列表页面的URL(比如http://www.midiworld.com/files/1),而不是实际的MIDI文件下载链接。你直接把这个页面的HTML内容保存成了.mid文件,自然无法被播放器识别。

解决办法

我们需要先解析每个列表页面,提取出页面内的真实MIDI文件下载链接,再去下载正确的文件。修改后的代码如下:

from bs4 import BeautifulSoup
import requests
import os
import urllib.request

base_url = "http://www.midiworld.com/files/"
base_path = 'path/where/I/will/save/the/downloaded/MIDI/files'

# 确保保存目录存在,不存在则创建
save_dir = os.path.join(base_path, 'MIDI Files')
os.makedirs(save_dir, exist_ok=True)
os.chdir(save_dir)

# 模拟浏览器请求头,避免被网站拦截
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}

for i in range(1, 2386):
    try:
        # 请求目标列表页面
        page_url = base_url + str(i)
        response = requests.get(page_url, headers=headers)
        response.raise_for_status()  # 检查请求是否成功,失败则抛出异常
        soup = BeautifulSoup(response.text, "html.parser")
        
        # 筛选出页面中指向.mid文件的下载链接
        midi_links = soup.select("div ul li a[href$='.mid']")
        if not midi_links:
            print(f"页面 {i} 未找到有效MIDI链接,跳过")
            continue
        
        # 获取第一个MIDI链接(通常每个页面对应一个MIDI文件)
        midi_href = midi_links[0]['href']
        # 拼接完整的下载URL
        midi_url = base_url + midi_href if midi_href.startswith('/') else midi_href
        
        # 从链接中提取原始文件名,和手动下载的命名保持一致
        filename = os.path.basename(midi_href)
        
        # 开始下载文件
        print(f"正在下载: {filename}")
        urllib.request.urlretrieve(midi_url, filename)
    except Exception as e:
        print(f"处理页面 {i} 时出错: {str(e)}")
        continue
关键修改点说明
  • 提取真实下载链接:通过soup.select("div ul li a[href$='.mid']")精准筛选出指向MIDI文件的链接,确保下载的是真正的音频文件而非网页。
  • 模拟浏览器请求:添加User-Agent请求头,避免网站把脚本识别为爬虫而拦截请求。
  • 合理命名文件:从链接中提取原始文件名,既避免了数字命名的混乱,也和手动下载的文件命名保持一致。
  • 异常处理机制:添加try-except块,处理页面请求失败、链接不存在等异常情况,让脚本运行更稳定。
  • 目录预检查:用os.makedirs(save_dir, exist_ok=True)确保保存目录存在,避免因目录缺失导致的报错。
验证方法

修改后下载的文件,你可以再次检查十六进制开头,应该会以MThd(十六进制4d 54 68 64)开头,和手动下载的文件格式完全一致,此时播放器就能正常识别并播放了。

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

火山引擎 最新活动