如何修改Python脚本通过MusicBrainz API获取歌曲原始专辑名
问题
我正在开发一款Python脚本,计划通过MusicBrainz API为音乐文件更新规范的专辑名与封面图。脚本需要根据歌手名和歌曲名获取对应专辑名,但目前经常返回合辑、精选集等非目标专辑,甚至无结果,无法获取歌曲最初发行的原始专辑。
测试Kim Carnes的《Bette Davis Eyes》时,脚本返回了合辑《Old Hits of 80’s, Volume 2》而非正确的原始专辑《Mistaken Identity》。
原核心代码
def get_album_info(artist, title): try: result = musicbrainzngs.search_recordings(artist=artist, recording=title, limit=5, strict=True) for recording in result['recording-list']: for release in recording['release-list']: if 'secondary-type-list' in release and 'Compilation' in release['secondary-type-list']: continue # Skip compilations if release['status'] == 'Official' and 'Album' in release['release-group']['primary-type']: album_title = release['title'] album_id = release['id'] print(f"Found album: {album_title} with ID: {album_id} for artist: {artist} and title: {title}") return album_title, album_id # If no suitable album is found print(f"No suitable album found for artist: {artist} and title: {title}. Setting album to 'Single'.") return "Single", None except (IndexError, KeyError): print(f"No album found for artist: {artist} and title: {title}. Setting album to 'Single'.") return "Single", None
测试输出
Processing file: /Users/user/Documents/MUSIC/11/Kim Carnes - Bett Davis Eyes.mp3 Artist: Kim Carnes, Title: Bette Davis Eyes Found album: Old Hits of 80’s, Volume 2 with ID: a477e219-f84f-4296-9688-b7629eea5e93 for artist: Kim Carnes and title: Bette Davis Eyes Found cover art for album ID: a477e219-f84f-4296-9688-b7629eea5e93 Updated file: /Users/user/Documents/MUSIC/11/Kim Carnes - Bett Davis Eyes.mp3 with album: Old Hits of 80’s, Volume 2
解决方案
要获取歌曲的原始发行专辑,需从排除非原始专辑类型和按发行时间排序优先选择最早版本两个核心方向修改:
修改要点
- 扩展排除的次级类型:除了
Compilation,还要排除Greatest Hits、Best Of、Remix Album等非原始专辑类型 - 按发行日期排序:对符合条件的发行版本提取发行日期,优先选择最早发行的版本(即原始专辑)
- 验证主艺人匹配:确保发行版本的主艺人是目标歌手,避免合辑中客串歌曲的误匹配
- 优化搜索参数:在搜索时指定
release_type=album缩小范围,同时放宽strict参数避免因名称微小差异导致无结果
修改后的完整get_album_info函数
def get_album_info(artist, title): # 定义需要排除的非原始专辑次级类型 excluded_secondary_types = {'Compilation', 'Greatest Hits', 'Best Of', 'Remix Album', 'Compilation Album'} valid_releases = [] try: # 优化搜索参数:指定发行类型为专辑,放宽strict避免名称差异导致无结果 result = musicbrainzngs.search_recordings( artist=artist, recording=title, limit=10, # 增加返回数量,确保能找到原始版本 strict=False, release_type="album" ) for recording in result['recording-list']: for release in recording['release-list']: # 跳过非官方发行 if release.get('status') != 'Official': continue # 跳过非专辑类型的发行组 release_group = release.get('release-group', {}) if release_group.get('primary-type') != 'Album': continue # 排除指定的次级类型 secondary_types = set(release.get('secondary-type-list', [])) if secondary_types & excluded_secondary_types: continue # 验证主艺人匹配(避免合辑中客串歌曲) release_artists = release.get('artist-credit', []) if not any(artist.lower() in cred.get('artist', {}).get('name', '').lower() for cred in release_artists): continue # 提取发行日期,用于排序 release_date = release.get('date', '9999-12-31') # 默认设为最晚日期 valid_releases.append((release_date, release['title'], release['id'])) if valid_releases: # 按发行日期升序排序,取最早的版本 valid_releases.sort(key=lambda x: x[0]) earliest_date, album_title, album_id = valid_releases[0] print(f"Found original album: {album_title} (released {earliest_date}) with ID: {album_id} for {artist} - {title}") return album_title, album_id print(f"No suitable original album found for {artist} - {title}. Setting album to 'Single'.") return "Single", None except (IndexError, KeyError, musicbrainzngs.ResponseError) as e: print(f"Error finding album for {artist} - {title}: {str(e)}. Setting album to 'Single'.") return "Single", None
其他注意事项
- 增加
limit=10可以获取更多结果,避免原始专辑因排序靠后被遗漏 - 使用
strict=False允许名称的微小差异(比如用户文件中的"Bett Davis Eyes"少了一个'e',也能匹配到正确的录音) - 发行日期处理:如果MusicBrainz没有提供具体日期,会用默认的
9999-12-31,确保这类结果排在最后
内容的提问来源于stack exchange,提问作者LewTrocki
相关产品推荐
相关产品推荐

