You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python读取MP3标签按歌手专辑分类移动文件报错求助

MP3文件按歌手专辑分类移动时的WinError 123错误修复

问题场景

尝试用Python读取指定目录下MP3文件的ID3标签,按歌手和专辑分类移动到新目录,但运行代码时触发WinError 123错误,提示文件名/目录名语法错误。

原代码

import os
import shutil
from mutagen.easyid3 import EasyID3

# Set the source and destination directories
source_dir = "E:\Radio Metaverse\Songs\Greatest Hits"
destination_dir = "/sorted"
# Walk through the directory tree and find all mp3 files
for root, dirs, files in os.walk(source_dir):
 for file in files:
    if file.endswith(".mp3"):
        # Use Mutagen to extract the artist and album tags
        mp3_path = os.path.join(root, file)
        tags = EasyID3(mp3_path)
        artist = tags.get("artist", ["Unknown Artist"])[0]
        album = tags.get("album", ["Unknown Album"])[0]

        # Create directories for the artist and album if they don't exist
        artist_dir = os.path.join(destination_dir, artist)
        if not os.path.exists(artist_dir):
            os.makedirs(artist_dir)
        album_dir = os.path.join(artist_dir, album)
        if not os.path.exists(album_dir):
            os.makedirs(album_dir)

        # Move the mp3 file to the album directory
        destination_path = os.path.join(album_dir, file)
        shutil.move(mp3_path, destination_path)

print("Done!")

错误信息

OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 
sorted/Joe Walsh\\Confessions.

'OSError:' is not recognized as an internal or external command,

错误原因及修复步骤

1. 路径格式问题

Windows系统使用反斜杠\作为路径分隔符,原代码中:

  • 源路径未加r前缀,导致\S这类字符被当作转义序列解析错误
  • 目标目录用了Unix风格的/sorted,Windows无法识别这种相对路径格式

修复:
给路径添加r前缀(raw字符串)避免转义,同时改用Windows兼容的路径格式:

source_dir = r"E:\Radio Metaverse\Songs\Greatest Hits"
destination_dir = r"E:\Radio Metaverse\Songs\sorted"  # 绝对路径
# 或者用相对路径:destination_dir = r".\sorted"

2. MP3标签含非法字符

歌手或专辑名称可能包含Windows文件名禁止的字符(比如\ / : * ? " < > |),导致创建目录时触发语法错误。

修复:
添加清理非法字符的函数,处理标签内容:

def clean_filename(name):
    invalid_chars = '<>:"/\\|?*'
    for char in invalid_chars:
        name = name.replace(char, '')
    return name.strip()

获取标签后调用该函数:

artist = clean_filename(tags.get("artist", ["Unknown Artist"])[0])
album = clean_filename(tags.get("album", ["Unknown Album"])[0])

3. 目录创建逻辑优化

用os.makedirs(..., exist_ok=True)替代手动判断目录是否存在,简化代码同时避免竞态条件:

artist_dir = os.path.join(destination_dir, artist)
os.makedirs(artist_dir, exist_ok=True)
album_dir = os.path.join(artist_dir, album)
os.makedirs(album_dir, exist_ok=True)

修复后的完整代码

import os
import shutil
from mutagen.easyid3 import EasyID3

def clean_filename(name):
    invalid_chars = '<>:"/\\|?*'
    for char in invalid_chars:
        name = name.replace(char, '')
    return name.strip()

# 修正路径格式,使用raw字符串避免转义
source_dir = r"E:\Radio Metaverse\Songs\Greatest Hits"
# 目标目录改为Windows格式的绝对路径
destination_dir = r"E:\Radio Metaverse\Songs\sorted"

for root, dirs, files in os.walk(source_dir):
    for file in files:
        if file.lower().endswith(".mp3"):  # 兼容大小写后缀
            mp3_path = os.path.join(root, file)
            try:
                tags = EasyID3(mp3_path)
                artist = clean_filename(tags.get("artist", ["Unknown Artist"])[0])
                album = clean_filename(tags.get("album", ["Unknown Album"])[0])
            except Exception as e:
                # 处理标签读取失败的文件,归类到未知目录
                print(f"读取{mp3_path}标签失败: {e}")
                artist = "Unknown Artist"
                album = "Unknown Album"

            artist_dir = os.path.join(destination_dir, artist)
            os.makedirs(artist_dir, exist_ok=True)
            album_dir = os.path.join(artist_dir, album)
            os.makedirs(album_dir, exist_ok=True)

            destination_path = os.path.join(album_dir, file)
            # 避免同名文件覆盖
            if os.path.exists(destination_path):
                name, ext = os.path.splitext(file)
                counter = 1
                while os.path.exists(os.path.join(album_dir, f"{name}_{counter}{ext}")):
                    counter += 1
                destination_path = os.path.join(album_dir, f"{name}_{counter}{ext}")
            shutil.move(mp3_path, destination_path)

print("Done!")

额外说明

  • 增加try-except块处理标签读取失败的文件,避免程序崩溃
  • 兼容.MP3这类大写后缀的文件
  • 处理目标目录中已存在的同名文件,自动添加数字后缀避免覆盖

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:40:38