词云工具WordCloud
- 使用
pip install wordcloud
安装工具后就可以创建词云,构造方法主要的构造参数如下:
wc = WordCloud(
background_color='white',
mask=backgroud_Image,
font_path='./SimHei.ttf',
max_words=100,
stopwords=STOPWORDS,
max_font_size=150,
width=2000,
height=1200,
random_state=30
)
- 创建好 WordCloud 类之后,就可以使用 wordcloud=generate(text) 方法生成词云,传入的参数 text 代表你要分析的文本
- 最后使用 wordcloud.tofile(“a.jpg”) 函数,将得到的词云图像直接保存为图片格式文件。
- 也可以使用Matplotlib进行显示
plt.imshow(wordcloud).
plt.axis("off")
plt.show()
歌词制作词云
- 我们主要使用 Python 爬虫获取 HTML,用 XPath 对歌曲的 ID、名称进行解析,
- 通过网易云音乐的 API 接口获取每首歌的歌词,将所有的歌词合并得到一个变量。
- 创建 WordCloud 词云类,分析得到的歌词文本,
- 可视化展示。
import requests
import sys
import re
import os
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import jieba
from PIL import Image
import numpy as np
from lxml import etree
headers = {
'Referer' :'http://music.163.com',
'Host' :'music.163.com',
'Accept' :'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'User-Agent':'Chrome/10'
}
def get_song_lyric(headers, lyric_url):
res = requests.request('GET', lyric_url, headers=headers)
if 'lrc' in res.json():
lyric = res.json()['lrc']['lyric']
new_lyric = re.sub(r'[\d:.[\]]','',lyric)
return new_lyric
else:
return ''
print(res.json())
def remove_stop_words(f):
stop_words = ['作词', '作曲', '编曲', 'Arranger', '录音', '混音', '人声', 'Vocal', '弦乐', 'Keyboard', '键盘', '编辑', '助理', 'Assistants', 'Mixing', 'Editing', 'Recording', '音乐', '制作', 'Producer', '发行', 'produced', 'and', 'distributed']
for stop_word in stop_words:
f = f.replace(stop_word, '')
return f
def create_word_cloud(f):
print('根据词频,开始生成词云!')
f = remove_stop_words(f)
cut_text = " ".join(jieba.cut(f,cut_all=False, HMM=True))
wc = WordCloud(
font_path="./wc.ttf",
max_words=100,
width=2000,
height=1200,
)
print(cut_text)
wordcloud = wc.generate(cut_text)
wordcloud.to_file("wordcloud.jpg")
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
def get_songs(artist_id):
page_url = 'https://music.163.com/artist?id=' + artist_id
res = requests.request('GET', page_url, headers=headers)
html = etree.HTML(res.text)
href_xpath = "//*[@id='hotsong-list']//a/@href"
name_xpath = "//*[@id='hotsong-list']//a/text()"
hrefs = html.xpath(href_xpath)
names = html.xpath(name_xpath)
song_ids = []
song_names = []
for href, name in zip(hrefs, names):
song_ids.append(href[9:])
song_names.append(name)
print(href, ' ', name)
return song_ids, song_names
artist_id = '3695'
[song_ids, song_names] = get_songs(artist_id)
all_word = ''
for (song_id, song_name) in zip(song_ids, song_names):
lyric_url = 'http://music.163.com/api/song/lyric?os=pc&id=' + song_id + '&lv=-1&kv=-1&tv=-1'
lyric = get_song_lyric(headers, lyric_url)
all_word = all_word + ' ' + lyric
print(song_name)
create_word_cloud(all_word)
- get_songs 函数,得到指定歌手页面中热门前 50 的歌曲 ID,歌曲名。在这个函数里,使用 requests.request 函数获取歌手页面的 HTML。这里需要传入指定的请求头(headers),否则获取不到完整的信息。然后用 XPath 解析并获取指定的内容,这个模块中,我想获取的是歌曲的链接和名称。
- 其中歌曲的链接类似 /song?id=536099160 这种形式,你能看到字符串第 9 位之后,就是歌曲的 ID。
- 一般来说,XPath 解析 99% 的可能都是以 // 开头,因为你需要获取所有符合这个 XPath 的内容。我们通过分析 HTML 代码,能看到一个关键的部分:id=‘hotsong-list’。这个代表热门歌曲列表,也正是我们想要解析的内容。我们想要获取这个热门歌曲列表下面所有的链接,XPath 解析就可以写成 //*[@id=‘hotsong-list’]//a。然后你能看到歌曲链接是 href 属性,歌曲名称是这个链接的文本。
- 获得歌曲 ID 之后,我们还需要知道这个歌曲的歌词,对应代码中的 get_song_lyric 函数,在这个函数里调用了网易云的歌词 API 接口,比如http://music.163.com/api/song/lyric?os=pc&id=536099160&lv=-1&kv=-1&tv=-1
- 能看到歌词文件里面还保存了时间信息,我们需要去掉这部分。因此我使用了 re.sub 函数,通过正则表达式匹配,将[]中数字信息去掉,方法为 re.sub(r’[\d:.[]]’,’’,lyric)。
- 我们还需要设置一些歌词中常用的停用词,比如“作词”“作曲”“编曲”等,编写 remove_stop_words 函数,将歌词文本中的停用词去掉
- 最后编写 create_word_cloud 函数,通过歌词文本生成词云文件