查看原文
其他

赵雷到底在唱什么

Ahab Ahab杂货铺 2019-02-16

击上方“Ahab杂货铺”,选择“置顶公众号”

技术分享第一时间送达!



写这篇文章的原因是之前在朋友圈看到我分析了42万字的歌词,为了搞清楚民谣歌手们在唱些什么 那是第一次听说爬虫,从那天起萌生了学习python爬虫的想法,幻想自己有一天也能写一个类似的程序,今天完成了那个时候的小目标。


程序介绍

这是一个词语频率统计程序,基于python3 ,爬取网易云赵雷所有歌曲的歌词统计出现次数较多的词语生成词云 。

  • 自动批量爬取赵雷歌曲的歌词 

  • 提取出现次数的词语生成词云

工作流程

  1. main.py负责爬取歌词,生成txt文件

  2. wordcloud.py 统计爬取的歌词生成词云

具体实现

第一部分:爬取数据


发起响应:


def get_html(url):
    headers = {'User-Agent':
    'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
    try:
        response = requests.get(url, headers=headers)
        html = response.content
        return html
    except:
        print('request error')
        pass

按照歌手id,发起请求,解析网页,提取歌曲id

def get_music_ids_by_musician_id(singer_id):
singer_url = \
'http://music.163.com/artist?id={}'\
.format(singer_id)
r = get_html(singer_url)
soupObj = BeautifulSoup(r,'lxml')
song_ids = soupObj.find('textarea').text
jobj = json.loads(song_ids)
ids = {}
for item in jobj:
print(item['id'])
ids[item['name']] = item['id']
return ids

创建文件夹,在文件夹下存储每首歌的歌词

def download_lyric(uid):
try:
os.mkdir(str(uid))
except:
pass
   
os.chdir(str(uid))
music_ids = \
get_music_ids_by_musician_id(uid)
for key in music_ids:
text = \
download_by_music_id(music_ids[key])
file = open(key+'.txt', 'a')
file.write(key+'\n')
file.write(str(text))
file.close()


第二部分:数据分析


利用jieba分词包进行分词,用set()去掉每首歌里的重复的词,同时去掉停用词(如的、和、吗等无意义的虚词),统计词频,然后以词云图显示。


小科普:

jieba(https://github.com/fxsjy/jieba)

“结巴”中文分词:做最好的 Python 中文分词组件

"Jieba" (Chinese for "to stutter") Chinese text segmentation: built to be the best Python Chinese word segmentation module.

  • Scroll down for English documentation.

特点:

  • 支持三种分词模式:

    • 精确模式,试图将句子最精确地切开,适合文本分析;

    • 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;

    • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

  • 支持繁体分词

  • 支持自定义词典

  • MIT 授权协议


读取文件,分词,生成all_words列表

all_words=[]
outstr = ''
for filename in os.listdir('6731'):
with open('6731/'+filename) as f:
lyrics=f.read()
data=jieba.cut(lyrics)
all_words.extend(set(data))
for word in all_words:
if word not in stopwords:
if word != '\t':
outstr += word
outstr += " "
all_words_new= outstr.split(" ")

对all_words中的词计数,并按照词频排序

count=Counter(all_words_new)
result=sorted(count.items(),
   key=lambda x: x[1], reverse=True)
print(result)

将频率变成字典,使matplotlib模块能显示中文,解决保存图像是负号'-'显示为方块的问题。

word_dic=dict(count.items())
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
color_mask=imread('5.jpg')

定义词云的格式

cloud=WordCloud(
font_path=
'D:\PycharmProjects\music\SIMYOU.TTF',
   width=600,
   height=480,
   background_color='black',
   mask=color_mask,
   max_words=250,
   max_font_size=150)
world_cloud=cloud.fit_words(word_dic)
world_cloud.to_file('lei.jpg')
plt.imshow(world_cloud)


在这遇到一个坑,如下图

忘记设置字体格式出现了上图的乱码情况,进行调整之后生成新的词云






欢迎您的点赞和分享

▲长按关注此公众号


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存