当前位置:   article > 正文

方法教程 | Python爬虫:爬取某易云数据并且可视化展示_爬虫加可视化展示摄影图片

爬虫加可视化展示摄影图片

  “项目说明

    某易云音乐歌单数据获取,获取某一歌曲风格的所有歌单,进入每个歌单获取歌单名称、创建者、播放量、页面链接、收藏数、转发数、评论数、标签、介绍、收录歌曲数、部分收录歌名,并统计播放量前十的歌单,将播放量前十的歌单以及对应的所有信息进行另外存储,对其进行可视化展示。

    在做这个爬虫的时候,对于如何翻页问题和身边的人进行了探讨,有人说用selenium模拟点击,但是通过观察网页,我发现即使是不用模拟点击翻页也能历遍爬完歌单的信息,接下来我就带着大家一起如何爬取数据。

    代码框架

    第三方库说明

    在项目中用到的一些第三方库的介绍:

  1. # bs4
  2. '''
  3. BS4全称是Beautiful Soup,它提供一些简单的、
  4. python式的函数用来处理导航、搜索、修改分析树等功能。
  5. 它是一个工具箱,通过解析文档为Beautiful Soup自动将输入文档转换为
  6. Unicode编码,输出文档转换为utf-8编码。
  7. '''
  8. # requests
  9. '''
  10. 用requests库来访问网页,获取网页内容,支持HTTP特性
  11. '''
  12. # time
  13. '''
  14. Time库是与时间处理有关的模块,
  15. 在这个项目中是用来强制网页访问间隔时间的。
  16. '''
  17. # random
  18. '''
  19. Random库主要功能是提供随机数,在项目中和time库配合使用,
  20. 生产随机强制访问的间隔时间的
  21. '''
  22. # xlwt
  23. '''
  24. Python访问Excel时的库,其功能是写入xls文件,
  25. 在本项目中是用于写入爬取的数据
  26. '''
  27. # pandas
  28. '''
  29. Pandas库是基于NumPy的一种工具,用于读取文本文件的,
  30. 可以快速便捷的处理数据的库。
  31. '''
  32. # pyecharts.charts
  33. '''
  34. pyecharts.charts是用于数据可视化的库,其中包含很多种画图工具,
  35. 在本项目中应用到的是画柱状图是Bar,圆饼图是Pie
  36. '''
  37. # matplotlib.pyplot
  38. '''
  39. matplotlib也是可视化的库,由各种可视化的类构成,
  40. matplotlib.pyplot是绘制各类可视化图形的命令子库
  41. '''
 

    内容爬取说明

爬取链接:https://某易云音乐官网网址//discover/playlist/?cat=

    页面详情

    观察网页内容是我们进行爬虫项目的首要步骤,这里我选择了华语类型的歌单来观察一下;

 

 

 

    华语风格的歌单总共有37页,每页有35个歌单,那总共大约有1295个歌单。一个风格的歌单是代表不了全部的,我们在做爬虫的时候要避免以偏概全,多看一个页面,找出规律,这样才能写出结构化的爬虫,当网页的内容发生变化,但总体框架没有变化时,我们的代码就能继续运行,这也是考验代码健壮性的一方面(跑偏了)。

    在选择其他歌单类别后,可以看到每个类别的歌单基本都是用37或38个页面来存放歌单,每个页面有35个歌单,那如何历遍每一个页面呢?

我当时面对这个问题的时候也是想了很久,又不想用selenium模拟点击,那我们就要多观察源代码,看看有没有蛛丝马迹。

 

 

    在源代码中,我们可以看到每个页面对应的链接是有规律的,

例如:“https://某易云音乐官网网址//#/discover/playlist/?order=hot&cat=%E5%8D%8E%E8%AF%AD&limit=35&offset=35

 

    通过网页链观察,我发现对于网页翻页的重点在于“&limit=35&offset=35”的数字35,每个页面是以链接后面的数字决定当前是在第几个页面,是以0为首页面,35为倍数的规律,第一个页面为 “&limit=0&offset=0”, 第二个页面为 “&limit=35&offset=35”,第三个页面为 “&limit=35&offset=70”,以此类推,只要知道当前类别的歌单有多少个页面,就可以通过for循环来循环翻页,遍历每一个页面。

    既然我们已经知道了翻页的规律了,那现在的重点就是获取歌单的页数。我们可以在箭头指引的地方,用开发者选项自带的复制方式,直接右键选择copy,copy selector直接复制CSS选择器语句;

  1. 标签:#m-pl-pager > div > a:nth-child(11)
  2. #获取歌单网页的页数
  3. result = bs.select('#m-pl-pager > div > a:nth-child(11)')

   那接下来就是对单个歌单进行内容爬取了,由于我们爬取的内容较多,所以这里就不一一列举了,大家可以自行对比参照,不懂可以私信。

    获取歌单名称

    进入每一个页面,获取该页面的每一个歌单,进入单个歌单中,歌单名称,创建者,播放量等数据都存放在网页的同一个div内,

id='content-operation'

    通过selector选择器选择各个内容的,由于是在网易云的网页版,因此在歌单内的歌曲并没有显示所有歌曲,只显示了10条歌曲,因此在爬取的时候每个歌单只获取了10条歌曲。如果还想要爬取每天歌曲更多详细内容,可以进入歌曲的url链接,获取更多的内容。

    完整代码

    这里我会定义一个内容类Content 和 网页信息类Website,进行结构化爬虫,如果不是很理解的话,可以看看我之前发过的内容,

    爬取三联生活周刊新闻

 

  1. class Content:
  2. def __init__(self, url, name, creator, play, collect, transmit, comment, tag,
  3. introduce, sing_num, sing_name):
  4. self.url = url
  5. self.name = name
  6. self.creator = creator
  7. self.play = play
  8. self.collect = collect
  9. self.transmit = transmit
  10. self.comment = comment
  11. self.tag = tag
  12. self.introduce = introduce
  13. self.sing_num = sing_num
  14. self.sing_name = sing_name
  15. def print(self):
  16. print("URL: {}".format(self.url))
  17. print("NAME:{}".format(self.name))
  18. print("CRAETOR:{}".format(self.creator))
  19. print("PLAY:{}".format(self.play))
  20. print("COLLECT:{}".format(self.collect))
  21. print("TRANSMIT:{}".format(self.transmit))
  22. print("COMMENT:{}".format(self.comment))
  23. print("TAG:{}".format(self.tag))
  24. print("INTRODUCE:{}".format(self.introduce))
  25. print("SING_NUM:{}".format(self.sing_num))
  26. print("SING_NAME:{}".format(self.sing_name))
  27. class Website:
  28. def __init__(self, searchUrl, resultUrl, pUrl, absoluterUrl, nameT, creatorT, playT, collectT, transmitT,
  29. commentT, tagT, introduceT, sing_numT, sing_nameT):
  30. self.resultUrl = resultUrl
  31. self.searchUrl = searchUrl
  32. self.absoluterUrl = absoluterUrl
  33. self.pUrl = pUrl
  34. self.nameT = nameT
  35. self.creatorT = creatorT
  36. self.playT = playT
  37. self.collectT = collectT
  38. self.transmitT = transmitT
  39. self.commentT = commentT
  40. self.tagT = tagT
  41. self.introduceT = introduceT
  42. self.sing_numT = sing_numT
  43.         self.sing_nameT = sing_nameT
'
运行

    爬取类 Crawler

  1. from bs4 import BeautifulSoup
  2. import re
  3. import requests
  4. import time
  5. import random
  6. import xlwt #进行excel操作
  7. class Crawler:
  8. #爬取网页函数
  9. def getWeb(self, url):
  10. try: #异常处理
  11. #请求头
  12. headers_ = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36',
  13. 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'}
  14. req = requests.get(url, headers = headers_)
  15. req.encoding = "utf-8" #网页格式化,避免出现乱码
  16. except requests.exceptions.RequestException:
  17. return None
  18. return BeautifulSoup(req.text, "html.parser")
  19. #爬取所需内容的函数
  20. def getContent(self, pageObj, selector):
  21. childObj = pageObj.select(selector)
  22. # print("\n".join(line.text for line in childObj))
  23. return "\n".join(line.text for line in childObj)
  24. #搜索函数,主函数
  25. def search(self, topic, site):
  26. # 爬取某种风格的歌单有多少页
  27. newurl = site.searchUrl + topic
  28. newurl = requests.utils.quote(newurl, safe=':/?=&') #对url链接上存在的中文字符进行处理
  29. bs = self.getWeb(newurl)
  30. result = bs.select('#m-pl-pager > div > a:nth-child(11)')
  31. num = int("\n".join(link.text for link in result)) #某种风格歌单的页数
  32. # 翻页,选取一种歌曲风格,有多个页面加载歌单,分别读取
  33. for i in range(0, num+1):
  34. j = 35*i
  35. url = site.searchUrl + topic + '&limit=35&offset=' + str(j) #构造每个页面的url链接
  36. url = requests.utils.quote(url, safe=':/?=&')
  37. bs = self.getWeb(url)
  38. searchResults = bs.select(site.resultUrl)
  39. for link in searchResults:
  40. url = link.attrs["href"]
  41. # 判断是否为绝对链接
  42. if(site.absoluterUrl):
  43. bs = self.getWeb(url)
  44. else:
  45. bs = self.getWeb(site.pUrl + url)
  46. # print(site.pUrl + url)
  47. if(bs is None):
  48. print("something was wrong with that page or URL. Skipping")
  49. return
  50. else:
  51. #爬取歌曲名称
  52. main = bs.find('ul',{'class':'f-hide'})
  53. sing_name = "\n".join(music.text for music in main.find_all('a'))
  54. # 爬取相关内容
  55. data = [] #申请一个数组,以歌单为单位,存储每个歌单里面所需要的内容
  56. url = site.pUrl + url
  57. data.append(url)
  58. # print(data)
  59. # 加入一个参数,判断目前读取的数据是字符串还是整数
  60. name = self.getContent(bs, site.nameT)
  61. data.append(name)
  62. creator = self.getContent(bs, site.creatorT)
  63. data.append(creator)
  64. play = self.getContent(bs, site.playT)
  65. data.append(play)
  66. collect = self.getContent(bs, site.collectT)
  67. data.append(collect)
  68. transmit = self.getContent(bs, site.transmitT)
  69. data.append(transmit)
  70. comment = self.getContent(bs, site.commentT)
  71. data.append(comment)
  72. tag = self.getContent(bs, site.tagT)
  73. data.append(tag)
  74. introduce = self.getContent(bs, site.introduceT)
  75. data.append(introduce)
  76. sing_num = self.getContent(bs, site.sing_numT)
  77. data.append(sing_num)
  78. # sing_name = self.getContent(bs, site.sing_nameT)
  79. data.append(sing_name)
  80. datalist.append(data) #以歌单为单位存入数组中
  81. # print(datalist)
  82. content = Content(url, name, creator, play, collect, transmit, comment, tag, introduce, sing_num, sing_name)
  83. # content.print()
  84. # return datalist
  85. #数据写入文档
  86. def saveData(self, datalist, savepath):
  87. print("保存到Excel文件中!")
  88. # xlwt.Workbook用来创建一个工作表,style_compression=0表示是否被压缩
  89. music = xlwt.Workbook(encoding = 'utf-8', style_compression=0)
  90. # 添加sheet表格,并允许重复修改
  91. sheet = music.add_sheet('某易云音乐数据爬取', cell_overwrite_ok=True)
  92. # 定义列名
  93. col = ("url", "歌单名称", "创建者", "播放量", "收藏量", "转发量",
  94. "评论量", "标签", "介绍", "歌曲数量", "歌曲名称" )
  95. for i in range(0,11):
  96. sheet.write(0, i, col[i]) #将列名写进表格
  97. for i in range(0, len(datalist)-1):
  98. # print("第{}行正在写入".format(i+1))
  99. data = datalist[i]
  100. for j in range(0, 11):
  101. sheet.write(i+1, j, data[j])
  102. music.save('E:/新建文件夹/Python爬虫/某易云音乐.xls')
  103. print("数据保存成功!")
  104. crawler = Crawler()
  105. # searchUrl, resultUrl, pUrl, absoluterUrl, nameT, creatorT, playT, collectT, transmitT,
  106. # commentT, tagT, introduceT, sing_numT, sing_nameT
  107. #对应website类的参数,将website定义的参数进行实例化
  108. siteData = [['https://某易云音乐官网网址/discover/playlist/?cat=''a.msk',
  109. 'https://某易云音乐官网网址/', False, 'div.tit h2.f-ff2.f-brk', 'span.name a',
  110. 'strong#play-count', 'a.u-btni.u-btni-fav i', 'a.u-btni.u-btni-share i',
  111. '#cnt_comment_count', 'div.tags.f-cb a i', 'p#album-desc-more',
  112. 'div.u-title.u-title-1.f-cb span.sub.s-fc3', 'span.txt a b']]
  113. sites = []
  114. datalist = []
  115. for row in siteData:
  116. sites.append(Website(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13]))
  117. topics = "华语" #选择自己想要的歌曲风格
  118. time.sleep(random.random()*3)
  119. for targetSite in sites:
  120. crawler.search(topics, targetSite)
  121. savepath = '某易云音乐.xls'
  122. crawler.saveData(datalist, savepath)
 

    爬取结果

    爬取的结果

    由于数据太多了,这里就只截取了一部分,有兴趣可以自己运行一下;

     内容可视化

    可视化代码

  1. import pandas as pd
  2. from pyecharts.charts import Pie #画饼图
  3. from pyecharts.charts import Bar #画柱形图
  4. from pyecharts import options as opts
  5. import matplotlib.pyplot as plt
  6. # 读入数据,需要更改
  7. #可视化
  8. data = pd.read_excel('某易云音乐.xls')
  9. #根据播放量排序,只取前十个
  10. df = data.sort_values('播放量',ascending=False).head(10)
  11. v = df['歌单名称'].values.tolist() #tolist()将数据转换为列表形式
  12. d = df['播放量'].values.tolist()
  13. #设置颜色
  14. color_series = ['#2C6BA0','#2B55A1','#2D3D8E','#44388E','#6A368B'
  15. '#7D3990','#A63F98','#C31C88','#D52178','#D5225B']
  16. # 实例化Pie类
  17. pie1 = Pie(init_opts=opts.InitOpts(width='1350px', height='750px'))
  18. # 设置颜色
  19. pie1.set_colors(color_series)
  20. # 添加数据,设置饼图的半径,是否展示成南丁格尔图
  21. pie1.add("", [list(z) for z in zip(v, d)],
  22. radius=["30%", "135%"],
  23. center=["50%", "65%"],
  24. rosetype="area"
  25. )
  26. # 设置全局配置项
  27. # TitleOpts标题配置项
  28. # LegendOpts图例配置项 is_show是否显示图例组件
  29. # ToolboxOpts()工具箱配置项 默认项为显示工具栏组件
  30. pie1.set_global_opts(title_opts=opts.TitleOpts(title='播放量top10歌单'),
  31. legend_opts=opts.LegendOpts(is_show=False),
  32. toolbox_opts=opts.ToolboxOpts())
  33. # 设置系列配置项
  34. # LabelOpts标签配置项 is_show是否显示标签;font_size字体大小;
  35. # position="inside"标签的位置,文字显示在图标里面;font_style文字风格
  36. # font_family文字的字体系列
  37. pie1.set_series_opts(label_opts=opts.LabelOpts(is_show=True, position="inside", font_size=12,
  38. formatter="{b}:{c}播放量", font_style="italic",
  39. font_weight="bold", font_family="Microsoft YaHei"
  40. ),
  41. )
  42. # 生成html文档
  43. pie1.render("E:/玫瑰图.html")
  44. print("玫瑰图保存成功!")
  45. print("-----"*15)
  46. # print(df['创建者'].values.tolist())
  47. bar = (
  48. Bar()
  49. .add_xaxis([i for i in df['创建者'].values.tolist()])
  50. .add_yaxis('播放量排名前十对应的评论量', df['评论量'].values.tolist())
  51. )
  52. bar.render("E:/条形图.html")
  53. print("柱形图保存成功!")
  54.     词云代码
  55. import wordcloud
  56. import pandas as pd
  57. import numpy as np
  58. data = pd.read_excel('某易云音乐.xls')
  59. #根据播放量排序,只取前十个
  60. data = data.sort_values('播放量',ascending=False).head(10)
  61. print(data["歌单名称"])
  62. #font_path指明用什么样的字体风格,这里用的是电脑上都有的微软雅黑
  63. w1 = wordcloud.WordCloud(width=1000,height=700,
  64. background_color='white',
  65. font_path='msyh.ttc')
  66. txt = "\n".join(i for i in data['歌单名称'])
  67. w1.generate(txt)
  68. w1.to_file('E:\\词云.png')`
 

玫瑰图

 

柱形图

 

    

这是保存下来的爬取某易云数据并且可视化展示,如有不足之处或更多技巧,欢迎指教补充。愿本文的分享对您之后爬虫有所帮助。谢谢~

编辑排版:筱筱   原创:Hundred°C

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/1015816
推荐阅读
相关标签
  

闽ICP备14008679号