前言
- 由于毕业设计的课题是通过CycleGAN搭建一个音乐风格转换系统,需要大量的音乐文件来训练神经网络,而MIDI文件作为最广泛使用的一种电脑编曲保存媒介,十分容易搜集资源,也有很多成熟的Python库来对MIDI文件进行处理。
- 如今,相关领域的研究最常用的数据集是The Lakh MIDI Dataset 。这一数据集包括十万余个MIDI格式文件,数据的数量是足够使用了,可是通过个人的测试,其质量没有达到我的预期,主要的原因是一首歌对应多个MIDI文件,而且元数据同数据相比远远不足,这两点导致了使用时的困难和不顺手,让我萌生了自己搭建数据集的想法。下面便是我从 Free Midi Files Download 这个网站爬取数据,构建数据集的过程,涉及简单的爬虫知识,和MongoDB数据库的Python API, PyMongo的简单操作。
- 如果您对爬虫实施过程中Session和Cookies的使用有疑惑之处,本篇文章也可以为您提供借鉴。若对爬虫的内容不感兴趣,尽可以滚动到本篇文章底部的资源链接,通过百度网盘下载这一数据集,使用时请注明本文链接,希望本文内容可以帮助到您!
- 下面的实施过程源代码地址在 josephding23/Free-Midi-Library
实施过程
编写爬虫
爬虫的代码在 Free-Midi-Library/src/midi_scratch.py
在搜索MIDI资源的过程中,我浏览了很多网站,其中 Free Midi Files Download 这个网站从资源数量以及资源组织形式这两个方面来看都是最优秀的一个,包含的音乐风格有17种之多,这之中摇滚乐的MIDI文件数目达到了9866个,通过结构化的爬取操作,这些文件的元数据(风格、歌手、歌名)都十分完整地保存在了MongoDB数据库中,方便之后的训练和测试。
爬虫的过程分为以下三个阶段:
- 爬取音乐风格信息,得到每个风格的艺术家名称、链接等 ,将信息添加到数据库,通过以下函数实现,比较简单:
def free_midi_get_genres():
genres_collection = get_genre_collection()
for genre in get_genres():
if genres_collection.count({
'name': genre}) != 0:
continue
url = 'https://freemidi.org/genre-' + genre
text = get_html_text(url)
soup = BeautifulSoup(text, 'html.parser')
urls = []
performers = []
for item in soup.find_all(name='div', attrs={
'class': 'genre-link-text'}):
try:
href = item.a['href']
name = item.text
urls.append(href)
performers.append(name)
except:
pass
genres_collection.insert_one({
'name': genre,
'performers_num': len(urls),
'performers': performers,
'performer_urls': urls
})
print(genre, len(urls))
- 构建艺术家数据表,将所有艺术家的信息添加进去,这一步不需要爬虫,而是为之后的爬取工作做准备:
def free_midi_get_performers():
root_url = 'https://freemidi.org/'
genres_collection = get_genre_collection()
performers_collection = get_performer_collection()
for genre in genres_collection.find({
'Finished': False}):
genre_name = genre['Name']
performers = genre['Performers']
performer_urls = genre['PerformersUrls']
num = genre['PerformersNum']
for index in range(num):
name = performers[index]
url = root_url + performer_urls[index]
print(name, url)
performers_collection.insert_one({
'Name': name,
'Url': url,
'Genre': genre_name,
'Finished': False
})
genres_collection.update_one(
{
'_id': genre['_id']},
{
'$set': {
'Finished': True}})
print('Progress: {:.2%}\n'.format(genres_collection.count({
'Finished': True}) / genres_collection.count()))
- 爬取每个艺术家的页面,将每个艺术家的所有作品信息添加到新建的MIDI数据表,注意这一步需要针对该网站的反爬虫机制来编辑响应头,重点在于Cookie的设置,具体方法在这里不详细展开,若有不解的地方可以在下面评论,与我交流。
def get_free_midi_songs_and_add_performers_info():
root_url = 'https://freemidi.org/'
midi_collection = get_midi_collection()
performer_collection = get_performer_collection()
while performer_collection.count({
'Finished': False}) != 0:
for performer in performer_collection.find({
'Finished': False}):
num = 0
performer

本文详述了从FreeMidiFilesDownload网站爬取MIDI文件构建音乐数据集的过程,包括爬虫技术、MongoDB数据库操作及音乐文件预处理。
最低0.47元/天 解锁文章
1898





