【Python实战】爬取⽹易云⾳乐⽤户听歌排⾏,来制作⼀张Ta最爱歌⼿的词云
图
前⾔
⼤家好,我是Samaritan。
平时写代码的时候,作为云村⽤户的⼀员,我当然也是最爱开着⽹易云⾳乐(以下简称⽹易云)。
⼤家都知道在⽹易云⾥你可以查看好友或是任意⽤户的听歌排⾏(假使Ta设置全部可见),但是如果想知道Ta喜欢哪些歌⼿,其中⼜有哪⼏个是Ta的最爱呢?很可惜,⽹易云并没有直接提供信息。
如果不会编程,你将怎么做?
⼀、⽹易云和词云
想知道Ta在⽹易云所有时间喜爱和最爱的歌⼿,逻辑上讲:
你可以基于Ta的所有时间听歌排⾏,⼿动记录他排⾏中前100⾸听得最多的歌曲的歌⼿/⾳乐⼈(以下统称为歌⼿),然后根据记录的信息统计重复出现的歌⼿次数,以此可以推断出Ta更喜欢的歌⼿,⽽余下
这些不重复⼈名也都是Ta喜欢的歌⼿。
不过显然这样⽤眼睛看、记录、⽐对⾮常的⿇烦,⼏乎不具有可⾏性。但是我们⽤python去实现上述逻辑,就没有很⼤的难度,这⾥会⽤到爬⾍技术来代替我们去看、去记录,再使⽤词云图展⽰和对⽐出Ta喜爱的歌⼿。
词云是什么?
简单介绍⼀下:“词云”,英⽂’wordle’,这个概念由美国西北⼤学新闻学副教授、新媒体专业主任⾥奇·⼽登(Rich Gordon)提出。他⼀直很关注⽹络内容发布的最新形式——即那些只有互联⽹可以采⽤⽽报纸、⼴播、电视等其它媒体都望尘莫及的传播⽅式。“词云”就是通过形成“关键词云层”或“关键词渲染”,对⽹络⽂本中出现频率较⾼的“关键词”的视觉上的突出。
如何截图词云图过滤掉⼤量的⽂本信息,使浏览⽹页者只要⼀眼扫过⽂本就可以领略⽂本的主旨。
来看⼀种最简单的词云图:
是不是还蛮有趣的?
⽹上能做词云图的⼯具不少,虽然它们看起来也很好⽤,可功能都有些单⼀,适⽤范围有限。选择⽤Python来制作词云,不仅上⼿简单便利,⽽将各种模块组合起来合理调⽤,更是功能强⼤且⾃定义⼴。
看完了这篇⽂章,你马上就能做出⼀张⽐上⾯⽰例图更好看的词云图。
说完了思路,现在来跟着我动⼿吧~
⼆、⽤户听歌排⾏
在正式开始之前,先说明⼀下,博主使⽤的IDE是pycharm,如果你⽤vscode或者jupyter notebook之类的都是没影响的,如有软件操作问题,请⾃⾏百度解决哦。
回到正题,我们先来看⽹易云:
进⼊随便⼀个⽤户:
Selenium模块
简介:Selenium是⼀个⽤于测试⽹站的⾃动化测试⼯具,⽀持各种浏览器包括Chrome、Firefox、Safari等主流界⾯浏览器,同时也⽀持phantomJS⽆界⾯浏览器。简单来说它可以模拟⼈对浏览器的操作包括点击,输⼊删除⽂字,或是滚动屏幕等等。
要使⽤它,你需要先pip install selenium安装该模块,并且拥有上述浏览器中的⼀种,然后下载安装对应的驱动webdriver⽂件。具体安装细节,不会的朋友请⾃⾏搜索教程,⾮常简单,本篇不再赘述。
Tip:使⽤selenium可以异步加载动态⽹页,将它变成静态⽹页后再交由bs4解析,是我常⽤的好搭档。
回到正题,我们有了url,也决定了使⽤什么⽅法爬取,接着我们来每⼀⾸⾳乐的歌⼿在⽹页的位置:
开局⼀个F12,所有标签全靠ctrl+f~
打开开发者⼯具(F12)后,到Elements⾥歌⼿信息位置:
使⽤⼯具⾥箭头选中歌⼿名字看到:
标出来的标签和属性都是可以⽅便我们等下定位到歌⼿信息的,⽽且到⼀个就可以到全部了,所有的歌⼿信息最后都藏在< li >⾥:
现在url、爬取⽅法、信息标签定位都已经齐全,可以开始写代码了!
三、爬取歌⼿代码
以我⽤的chrome浏览器为例写代码。
先来导⼊模块,我们先要⽤到selenium、bs4和time模块:
import time
from selenium import webdriver
from bs4 import BeautifulSoup
构建url以及设置等下要⽤到的变量名:
uid ='41209xxxx'#随时可替换⽤户id
url_recd ='music.163/#/user/songs/rank?id='+uid#构建爬取url
unknown ='未知'#特殊情况下错误提⽰⽤
asingerlist =[]#储存所有时间排⾏中所有歌⼿的列表
start = time.time()#设置计时器
samaritan =webdriver.Chrome()#webdriver实例化
接着创建⼀个负责爬取⽬标⽤户所有时间听歌排⾏的⽅法好像就可以成功了?因为我们刚刚已经定位到了歌⼿⽂本信息。可是这⾥有个坑~如果你直接⽤selenium定位或bs4解析定位尝试刚才的标签的话会什么都不到。
因为仔细看elements⾥:
这⾥是iframe页⾯嵌套,如果不能进⼊iframe⾥⾯,是不能定位到任何在它⾥⾯的标签的。
幸运的是这对selenium来说仍然不是问题:
def get_record():#创建获取歌⼿信息的⽅法
马剑越向王源道歉<(url_recd)
#实例化对象访问url
samaritan.switch_to.frame('g_iframe')
#到指定iframe标签(这⾥是g_iframe)然后跳⼊
samaritan.implicitly_wait(10)#隐式等待
checkall = samaritan.find_element_by_id('songsall')
#定位到切换到所有时间的按钮标签
checkall.click()
#模拟⿏标点击查看所有时间下的听歌排⾏
samaritan.implicitly_wait(10)#隐式等待
time.sleep(0.5)#这⾥还需要强制等待加载时间,⼀般⼀秒内就可以了
馄饨的做法htmlrec = samaritan.page_source
#此时⽹页成为静态页⾯,获取所有页⾯信息
pagerec = BeautifulSoup(htmlrec,'html.parser')#使⽤bs4解析静态⽹页
allrec = pagerec.find(class_="g-wrap p-prf").find(class_="m-record").find(class_="j-flag").find_all('li')
#定位该位置下所有<li>的标签
try:#使⽤try except结构防⽌意外报错中断运⾏
for i in allrec:
#遍历刚才位置下每⼀个<li>标签内信息
asinger = i.find(class_="s-fc8").place('-','')
#定位并获取歌⼿⽂本信息,再⽤replace⽅法清洗⽂本去掉歌名和各种之间连结的'-'
asingerlist.append(asinger)
#将⼲净的歌⼿⽂本加⼊列表
except:
print(unknown)
#如遇到意外,提⽰'未知'。
最后调⽤⽅法以及查看结果:
get_record()#调⽤爬取⽅法
a货包samaritan.close()#关闭浏览器
end = time.time()#结束计时
print(asingerlist)#打印所有歌⼿列表
print(f'总共⽤时:{end-start}秒')#打印程序⽤时
输出结果:
[' Matteo',' Russ',' 永彬Ryan.B/AY楊佬叁',' DP龙猪/宝楽CNBALLER/CLOUDWANG\xa0王云',
' ⾳阙诗听',' Deep\xa0Chills/IVIE',' ⽩⼩⽩',' Fly\xa0Project',' ⾦志⽂'......#以下省略]
总共⽤时:4.079788398742676秒
只要四秒钟,我们就完成了对⽬标⽤户所有时间听歌排⾏的歌⼿爬取。
但是这样⼀点看不清啊,⽽且怎么知道哪些歌⼿更被偏爱呢?
接下去我们就要把这个歌⼿列表⾥的内容制作成⼀⽬了然的词云图了~
四、制作歌⼿词云
制作词云我们还需要⽤到以下模块:
os
PIL
numpy
matplotlib
wordcloud
这些模块的安装使⽤也不在本篇讲解了,只是展⽰给⼤家这种实战情况下如何调⽤,有兴趣的⼀样可以⾃⾏搜索深⼊学习。开始制作词云,依旧先导⼊模块:
from os import path
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
光良疑似宣布结婚from wordcloud import WordCloud
我们⽤wordcloud的⽅法处理⽂本,以⽣成词云。
⽆论是你从表格⽂件还是txt⽂本还是直接爬取到的数据,只要是字符串就可以给他处理,所以这⼀步先要将刚才的歌⼿列表变成wordcloud可以处理的字符串:
astext =','.join(asingerlist)
#将列表所有元素依序合并成字符串,并⽤'逗号'连接
是的你没看错,⼀⾏代码就ok了!因为我们在加⼊列表前已经做了数据清洗。
我之前说了,这个词云图要做出⽐上⾯举例的那张好看才⾏,所以我们给它戴⼀个’⾯具’mask:
模板图⽚love.png
d = path.dirname(__file__)
#获取当前⽂件路径
alice_mask = np.array(Image.open(path.join(d,"love.png")))
#读取模板的图⽚
⾮常简单,就两⾏代码。这⾥我⽤了PIL模块读取的图⽚,也可以使⽤别的模块⽐如imageio、opencv等等都⼀样的。读取以后等下我们会在wordcloud参数设置⾥套⽤上它。
现在我们再来美化⼀下这个词云,我可以使它的颜⾊在丰富⼀些:
color_list=['r','g','b','y','pink','purple','orange','black']
#建⽴颜⾊数组,列表中的颜⾊可以随便改动,除了常⽤颜⾊英⽂名外,也可以直接使⽤RGB⾊值,例如'#FDF5E6'
colormap=colors.ListedColormap(color_list)
#调⽤颜⾊数组
天天向上田源老婆万事俱备啦,现在设置wordcloud对象参数:
发布评论