对薛之谦歌曲的分析
薛之谦(Joker Xue),1983年7月17日出生于上海,华语流行乐男歌手、影视演员、音乐制作人,毕业于格里昂酒店管理学院。
作为薛之谦的一名早期粉丝,我相信每个人都有固定的习惯。歌手、作家也一样,我在想薛之谦写了那么多的歌,会不会有固定的套路,说不定我找到套路了之后,也就可以写出薛之谦风格的歌曲了,哈哈哈!!!
既然是做数据分析的,首先就要把老薛的歌词都下载下来。于是我就写了歌曲爬虫。
第一步要对网站进行解码,这里我是增加了浏览器头部。
第二步:通过Xpth的方法,获取当前网页每首歌的歌词的herf 地址连接。
第三步获取当前网页的歌曲名字
第四步:设置主函数,执行,保存了之后,
第五步,建一个文件夹进行保存所有的歌词txt文本。
第六部:我手动删除了相同的歌曲文件。总计61首歌,因为有的是带电视剧名字的歌曲,就2-3首,尴尬。还是手动的快。
有了数据文本,就可以进行清洗分析了,这一步最让人头疼,每个文档的内容格式都不是固定的,我是将文本每一行作为读取的对象,去掉哪些包含无效数据的行,这里面会遇到一个尴尬的是,英文的句子是一个大坑,后面再说。
将所有的文档的数据存放到一个列表里面。接下来用词频分析进行统计,用jieba
精确模式分词。这里就要说一下前面的大坑了,jieba分词英文歌,进行统计的时候好多单词,还有单个的字母,数据存在字典中,我处理的是把字典存储在excel中,在excel中筛选删除啊,大哥,我是没办法了,
import jieba
import collections # 词频统计库
def cleaning(data):
object_list = []
for i in range(len(data)):
single_word = jieba.cut(data[i], cut_all=False) # 精确模式分词,需要遍历出来
##去掉\n
for each in single_word:
object_list.append(each) # 分词追加到列表
# object_list.remove('\n')
word_counts = collections.Counter(object_list) # 对分词做词频统计
print(" 词频统计完成")
return word_counts
生成excel的代码:
from openpyxl import Workbook
wb=Workbook()
#@2.使用第一张工作表
sheet=wb.active
#3给表起个名称
sheet.title='词频'
sheet.append('关键字,词频'.split(','))
for i in word_counts.items():
sheet.append(i) ### 将字典存入excel中,这样做词云就不用每次运行了
wb.save('WordCloud.xlsx')
我将出现频率最高的前几个做了柱形图。
有了效果好的数据就好处理, 为了效果更加好看一些,我做了个词云。词云的背景图真的难找,用的是默认的,从上面的图上可以找到老薛经常用的词语,嘿嘿。。
该展示的展示了,从词云上我感觉,下一首歌叫《那么我们还是爱自己》比较对老薛的口味。
有了歌名,也有了大量的词语库,下次用机器学习的方式,让机器写歌词吧。。
敬请期待。。。。
附:爬虫的代码
# @File : music-scarpy.py
# @Author: Jie Wei
#@time: 2019/3/29 12:51
####网站准备好了,,下面根据网站爬去相应的歌词
import requests
import chardet
import time
##定义一个函数,存放解码歌词网站的html。。
def get_info_url(url):
url = url
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"}
reponse = requests.get(url, headers)
code = chardet.detect(reponse.content)["encoding"]
reponse.encoding = code
html_text = reponse.text
return html_text
## 定义一个函数用来提取歌词
from scrapy.selector import Selector
def get_music_word(html_music):
selector = Selector(text=html_music)
music_text = selector.xpath('//p[@id="txt"]/text()').extract() # 有结果了,是歌词,
data = []
for each in music_text:
data.append(each.strip())
return data
## 定义一个函数用来保存歌词的txt
import os
def save_txt(data, music_name):
while '' in data:
data.remove('')
newtext = open("./薛之谦" + str(music_name )+ ".txt", "w")
newtext.writelines(line + "\n" for line in data)
print("正在保存:" + music_name + ".txt")
#本地的 头文件
'''
#headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"}
'''
def first_page(url):
headers={"User-Agent":"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"}
reponse=requests.get(url,headers)
code = chardet.detect(reponse.content)["encoding"]
reponse.encoding=code
html_text=reponse.text
return html_text
#print(html_text) #有内容了
#获取了 网址的html文本。导入xpth包,用xpth来找内容
from scrapy.selector import Selector
## 找到音乐名称和歌词地址
def get_info(page_http):
selector=Selector(text=page_http)
li=selector.xpath('//div[@class="rec"]/ul/li') #[<Selector xpath='//div[@class="rec"]/ul/li' data='<li><a href="/geci/99384.html">天份</a></l'>]
li.pop(0) #把第一行表头的名称去掉
https=[]
music_name=[] ## 是歌的名字。。
for each in li:
music_name+=each.xpath("./a/text()").extract() ##返回的本身是个列表 ['天份', '最好', '怪咖']
https.append( "https://www.90lrc.cn"+each.xpath("./a/@href").extract()[0] ) ## 用两种方法
return (music_name,https)
import random
if __name__ == '__main__':
if os.path.exists("薛之谦"):
os.chdir("薛之谦")
else:
os.mkdir("薛之谦")
os.chdir("薛之谦")
#url = "https://www.90lrc.cn/geshou/100626.html?id=100626&id=100626&page=1" #这是第一页的网址
ur1="https://www.90lrc.cn/geshou/100626.html?id=100626&id=100626&id=100626&page=2" #这是第二页的网址
page_http = get_info_url(ur1)
music_name, html_sum = get_info(page_http)
for i, each_url in enumerate(html_sum): # each_url 里面存放的是每个单个的歌曲的网址
html_music = get_info_url(each_url) ##获取解码,可以爬取歌词的网站文本。
## 解码之后就要获取歌词了
data = get_music_word(html_music) # 返回带有['天份', '薛之谦', '',]这样的列表
time.sleep(random.randint(10,20)) #不然会被服务器封掉,,
## 保存文件 txt
save_txt(data, music_name[i]) # music_name[i] 提取对应的歌名,作为文件名