我分析了55W歌词,就是想听听中国民谣在唱什么
1. 歌词获取
首先我需要一个民谣歌曲集合,选歌单的原则是尽力为选择能代表中国民谣的作品,事实上,现在民谣制作的门槛是真的低。有的民谣里面通篇就几个词翻来覆去。比如底下这种歌单很快就舍弃掉了。
(野鸡民谣)
最终选择的是 歌单:民谣合集。歌单比较全,总共大概2128首歌,涉及到不少华语民谣歌手。按每人50首来算,这也有40左右个中国民谣人了
网易提供了(体验并不好的)某些API,
# 获取歌单中歌曲API url
playlist_url = 'http://music.163.com/api/playlist/detail?id=[id]'
# 获取歌曲的歌词API url
song_lyrics_url = 'http://music.163.com/api/song/lyric?os=pc&id=[id]&lv=-1'
实际请求时,请将[id]替换为真实id,比如《民谣合集》歌单id为2618345367,你可以从网易音乐相关超链接上找到。这两个API返回都是JSON格式,需要自己解析。(可以看出实际中这个#是没什么用的)
然后,我们请求获取歌单的所有歌曲信息(歌曲云上id、歌曲名、作者)
def get_playlist(playlist_id, path=''):"""获得歌单中所有歌曲的id,cloud_id,title,author信息:param playlist_id: 歌单id:param path: 保存的路径和文件名:return: text"""json_text = requests.get(playlist_url % playlist_id).textjson_dict = json.loads(json_text)text_list = []for idx, song in enumerate(json_dict['result']['tracks']):if not idx:text_list.append('id cloud_id title author')text_list.append('%d %d %s %s' % (idx + 1, song['id'], song['name'], song['artists'][0]['name']))text = '\n'.join(text_list)if path:with open(path, 'w') as file:file.write(text)return text
我们还需要一个函数,请求获取某首歌的歌词
def get_lyric(song_id, path=''):"""根据歌曲id获得歌曲歌词:param song_id::param path: 当前歌词被保存的路径和文件名:return:"""json_text = requests.get(song_lyrics_url % song_id).textjson_dict = json.loads(json_text)text_list = []for idx, line in enumerate(json_dict['lrc']['lyric'].split('\n')):if '作曲' in line or '作词' in line: # 去除歌词中可能出现的作词、作曲行continueif line.strip() != '':if ']' in line: # []内可能是时间信息,去除if line.rindex(']') + 1 != len(line):line = line[line.rindex(']') + 1:].strip()else:continueif ':' in line: # 冒号前面可能是歌者,应去除。e.g.: "女:"、"老狼:"line = line[line.rindex(':') + 1:]if ':' in line: # 冒号前面可能是歌者,应去除。e.g.: "女:"、"老狼:"line = line[line.rindex(':') + 1:]text_list.append(line.strip())text = '\n'.join(text_list)if path:with open(path, 'w') as file:file.write(text)return text
最后,我们将此歌单中所有歌曲歌词都保存下来
if __name__ == '__main__':# 获取"中国民谣集"歌单中所有歌曲歌词df = pd.read_csv(os.path.join(cfg.ProjectPath, cfg.DataDirectory, cfg.SongInfoFileName), delimiter=' ',engine='python')for idx, cloud_id, title, author in df.values:try:get_lyric(cloud_id, file_name='%d_%s_%s' % (idx, title, author))except IOError as ioe:print('id为%s,云id为%s的文件异常,%s' % (idx, cloud_id, ioe))except BaseException as be:print('id为%s,云id为%s的文件异常,%s' % (idx, cloud_id, be))
写个函数在目录里自动生成目录保存下来所有歌词
def makedir(dir_name):path = r"C:\Users\admin\PycharmProjects\Cloudlyric\data"dir_name = path+'./'+dir_namefolder = os.path.exists(dir_name)if not folder:os.makedirs(dir_name)print("creat dir success")else:print("this folder has existed")return dir_name
2.数据存储和初步简单清洗
简单的看了一下爬下来的每一个数据,发现前两行经常有不用的作词作曲信息,想办法去除掉
def ConvertStrToFile(dir_name, filename, str):if (str == ""):returnfilename = filename.replace('/', '')text_list = ""for idx, line in enumerate(str.split('\n')):if '作曲' in line or '作词' in line or '编曲' in line: # 去除歌词中可能出现的作词、作曲行continueif line.strip() != '':if ']' in line: # []内可能是时间信息,去除if line.rindex(']') + 1 != len(line):line = line[line.rindex(']') + 1:].strip()else:continueif ':' in line: # 冒号前面可能是歌者,应去除。e.g.: "女:"、"老狼:"line = line[line.rindex(':') + 1:]if ':' in line: # 冒号前面可能是歌者,应去除。e.g.: "女:"、"老狼:"line = line[line.rindex(':') + 1:]text_list +=line.strip()path = r"C:\Users\admin\PycharmProjects\Cloudlyric\data"with open(path+"./"+dir_name + "//" + filename + ".txt", 'w',encoding='utf-8') as f:f.write(text_list)
于是保存歌词成txt文档在最开始创建的目录里
def get_list_lyric(playlist_id):songlist = get_list(playlist_id)print(songlist)playlist_name = songlist['playlist_name']idlist = songlist['list']dir=makedir(playlist_name)for music in idlist:ConvertStrToFile(playlist_name, music.text, get_lyric(music['href']))print("File " + music.text + " is writing on the disk")print("All files have created successfully")return dir
3.数据的清洗、分词、统计
在分词前,为了最终结果得出不必要的语气词以及冗余词,我是用的是哈工大停用词表再结合结巴分词,效果好了不少
def load_stopwords():"""加载停用词:return:"""stopwords = set()with open(os.path.join(naming.ProjectPath, naming.DictDirectory, naming.StopwordsFileName),encoding='utf-8') as file:for line in file:stopwords.add(line[:-1]) # 切除换行符stopwords.add(' ')return stopwordsdef get_words_freq(stopwords, lyrics_dir):"""统计词频:param stopwords: 停用词集合:type stopwords: set(stopword1, stopword2, ...):param lyrics_dir: 歌词路径:return: {word1: freq, word2: freq, ...}"""# 迭代每个文件,对每个文件,每一行分词,去除停用词后,统计词频words_freq = {}for file_name in os.listdir(lyrics_dir):try:with open(os.path.join(lyrics_dir, file_name),encoding='utf-8') as file:for line in file:words = posseg.cut(line.strip())for word, pos in words:if word not in stopwords and pos[0] in pos_retained: # 过滤停用词,词性筛选if word not in words_freq:words_freq[word] = 1else:words_freq[word] += 1except IOError as ioe:logger.warning('异常信息:%s' % ioe)except BaseException as be:logger.warning('异常信息:%s' % be)return words_freq
为了方便,得出的结果转为json格式,存储在data数据目录下
初步优化
发现许多地方名称、路径又多又杂。又开了一个py文件naming来设置命名规范 大概是这样的
# -*- coding: utf-8 -*-
from dataGet import getData
__author__ = 'Jmh'# Project path
ProjectPath = r'C:\Users\admin\PycharmProjects\Cloudlyric'# Data directorye
DataDirectory = 'data'
LyricsDirectory = 'data/民谣合集 - 歌单 - 网易云音乐'
DictDirectory = 'data/dict'
Resource = 'resource'# File nameStopwordsFileName = 'stopwords' # 停用词文件名
简单的数据处理后,轻易可以得出各种自己想要的数据:
4.运用WordClouD词云
此部分比较简单也就写的比较随意了,生成了两个,一个带图片蒙版一个不带
wordcloud = WordCloud(background_color='white',mask=alice_mask,max_words =1000,font_path=r"C:\\Windows\\Fonts\\STFANGSO.ttf",).fit_words(read_dict)
#生成词云(通常字体路径均设置在C:\\Windows\\Fonts\\也可自行下载)
#不加这一句显示口字形乱码 ""报错
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
其中生成中文词云时,不加font_path会显示满屏幕的口字乱码
带蒙版的,需要ps去除背景且大小要合适,最大词频数控制在1000个左右
通过词云,我们大概很清晰的能看出来:民谣歌手最常出现的几个词“时间”“姑娘”“梦想”“世界”“远方”“城市”
看来民谣歌手也没有那么丧。
5.制作图表
共用到两种工具:matplot和echarts
绘制柱状图:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 创建一个点数为 8 x 6 的窗口, 并设置分辨率为 80像素/每英寸
plt.figure(figsize=(8, 6), dpi=80)# 再创建一个规格为 1 x 1 的子图
plt.subplot(1, 1, 1)# 柱子总数
N = 11
# 包含每个柱子对应值的序列
values = (75, 17, 9, 9, 2,7,6,12,7,9,25)# 包含每个柱子下标的序列
index = np.arange(N)# 柱子的宽度
width = 0.35# 绘制柱状图, 每根柱子的颜色为紫罗兰色
p2 = plt.bar(index, values, width, label="城市", color="#87CEFA")# 设置横轴标签
plt.xlabel('')
# 设置纵轴标签
plt.ylabel('次数')# 添加标题
plt.title('民谣歌手最钟爱的城市')# 添加纵横轴的刻度
plt.xticks(index, ('北京', '上海', '深圳', '成都', '苏州', '重庆','武汉','南京','青岛','郑州','兰州'))
plt.yticks(np.arange(0, 81, 10))# 添加图例
plt.legend(loc="upper right")plt.show()
民谣歌手最爱的城市是北京,其次竟然是兰州,出乎了我的意料
比起其他季节,民谣歌手更爱歌颂冬天
即是丧如民谣歌手,人还是要向前看。
民谣歌手更喜欢忧郁的蓝色
我分析了55W歌词,就是想听听中国民谣在唱什么相关推荐
- 【SA8295P 源码分析】34 - 老婆都想懂的Audio系列 -
[SA8295P 源码分析]34 - 老婆都想懂的Audio系列 - 一.Audio 音频框架介绍 1.1 Android Audio Framework 软件框架介绍 - based Android ...
- 李志飞:想在中国复制 Echo 的成功,肯定都不靠谱
雷锋网(公众号:雷锋网)按:李志飞明白,智能音箱背后有一个庞大的产业,中文生态.内容.服务.对接,渠道等等,但他并不认为现在就要考虑这些,所以当别人认为这最终是一场巨头之争时,他说他能给出一百个理由证 ...
- 互联网金融想革中国金融体系的命?
本文讲的是互联网金融想革中国金融体系的命,我今天主要讲的不是产品本身,主要讲的是互联网金融未来的逻辑,因为金融是有本质的,把这个逻辑讲清楚了,可以帮我们理解未来. 第一,从中国的经济和金融制度所理解的 ...
- [案例分析]一汽高工离职后揭示的中国汽车业绝对内幕!(转)
网友们: 前段时间,我看了一些关于民族轿车的帖子,对一些网友避开民族危机和民族情感谈竞争的态度非常痛心. 我也是一个经常上网看帖子的人,但很少发帖,同大家一样,我也是一位关注国家命运和实事的人,在这里 ...
- 我用分析了42万字的歌词,为了搞清楚民谣歌手们在唱些什么
文章来源于互联网 写在前面的话 (https://jq.qq.com/?_wv=1027&k=gAwXvrat) 听了这么多年民谣,我有一种感觉,就是很多歌都似曾相识,但是仔细一想,又哪一首都 ...
- 最近在做一些改变,想听听你的意见
这是学习笔记的第 2131 篇文章 今天对之前的投票数据做了下分析,还是蛮有意思的. 最近也在做一些转变,所以想借此机会收集下大家的需求,继续完善下. 帮忙做一下下面的问卷,有4个小问题,大概不到一分 ...
- Python爬虫+FineBI分析,2019年你想看的A股牛市都在这里了!
在过去的2018年这一年时间里,股票市场的表现可谓是令广大股民心力交瘁,股价一路走低.不少股民们也是因此对股票丧失了信心,纷纷撤出市场. 但是仍然有一部分股民们仍然坚守着信念,继续奋战在持续走低的股票 ...
- 【恒指早盘分析】期货交易绝非你想的那么简单
对期货而言,这个市场是绝对平等的.它不需要八面玲珑的关系,不靠权势,只凭借勤奋努力来实现梦想,实现真正的财务自由.因此,对每一位立志于靠智慧生活的人来说,期货投资是一个极好的发展领域.从平时的练习和实 ...
- 牛市该理智还是疯狂?python+BI可视化的股票分析,都是你想看的
最近的市场行情有点好,很多人都出来梭哈了,无论是互联网公司的腾讯员工,还传统企业的大爷大妈,有的甚至拿出自己的积蓄,一下子都投入.... 我觉得这个哥们离去拼多多工作不远了... 在高点的时候选择加入 ...
最新文章
- Java面试题汇总2021最新(集合泛型含答案下载)
- 监控目前所有连接SQL SERVER的用户信息
- jsonwebtoken中文文档
- mysql 长连接 has gone away_MySQL server has gone away报错原因分析/
- 利用github协作开发步骤
- MUI+Htmlplus开发APP实现页面之间传值
- PHP_框架储备资料
- pytorch实现 求协方差、皮尔森相关系数(Pearson product-moment correlation coefficient)
- 干货!纯干货! 手把手教你做云专线互联网备援接入-上集
- 模数转换器(ADC)
- 并发编程(三)---共享模型之管程
- python中def fun()是什么意思_python学习函数
- selenium使用代理IP
- 深度对比:电子合同与纸质合同到底有哪些差异?
- 概率统计-方差与正态分布(高斯分布)
- 一个毕业两年IT民工
- 西门子S71200系列PLC数据采集方案
- linux 系统下开源软件 ngspice 仿真实例,调侃Spice历史和GNU/Linux下做Spice电路仿真...
- linux 系统业务迁移,linux系统迁移
- 【转】百度编辑器UEditor
热门文章
- automake 框架_升级autoconf automake libtool
- 一道反证法证明极限无穷大题目
- android listview 滑动黑屏,Android 跨进程启动Activity黑屏(白屏)的三种解决方案
- 开启docker并搭建三台机greenp6lum集群
- Microsoft SQL Server Management Studio ------- 附加数据库 对于 服务器“xxxamp;amp;quot;失败(错误码5120)
- 微信公众平台升级9大高级接口功能解读
- 数据处理Pandas学习笔记(二)
- 「Do.020」程序员该如何在寒冬中自处
- 信息收集之目录扫描-dirbuster
- NBA最强的状元:詹姆斯上榜,他保持了20年的稳定