用Python挖掘网易云音乐的热门歌单

论坛 期权论坛 期权     
Python中文社区   2019-6-9 21:26   5233   0

图片来源于网络

伪文艺Boy,Python、R、Java爱好者,喜欢新鲜感,一个简单、纯粹的IT小伙
博客:https://blog.csdn.net/striver6
本文作者已加入Python中文社区专栏作者计划
一、目标网站介绍
网易云音乐是一款由网易开发的音乐产品,是网易杭州研究院的成果,依托专业音乐人、DJ、好友推荐及社交功能,在线音乐服务主打歌单、社交、大牌推荐和音乐指纹,以歌单、DJ节目、社交、地理位置为核心要素,主打发现和分享。
2017年11月17日,网易云用户突破4亿。知乎上有这样一个问题:你为什么用网易云其中,有一条是这样说的:
成年人的生活里有太多无奈。
我之前把情绪和秘密写在QQ留言板里,被朋友们发现。
后来写在人人网上,被朋友们发现。
后来写在微博里,被朋友们发现。
后来写在知乎里,被朋友们发现。
后来淹没在网易云强大的评论区里。
我需要一个地方,一个可以光明正大写出来的地方。
不用担心被任何人看到,不需要任何解释。
网易云可以把所有的悲伤,变成段子。
出于大众对网易云音乐的喜爱,这次文本挖掘我放在了这里,希望能发现些有趣的东西。
二、所需工具
  • Anaconda 3.5.0
  • Pycharm
  • Node.js
  • Mongodb
  • Studio 3T
  • RStudio
三、数据爬取
3.1 环境搭建
本文基于Scrapy框架爬取数据。使用pip install 来安装scrapy需要安装大量的依赖库:
  • Wheel
  1. pip install wheel
复制代码
  • lxml
  1. pip install D:\Downloads\Scrapy\lxml-4.3.0-cp36-cp36m-win_amd64.whl
复制代码
  • PyOpenssl]
  1. pip install D:\Downloads\Scrapy\pyOpenSSL-18.0.0-py2.py3-none-any.whl
复制代码
  • Twisted
  1. pip install D:\Downloads\Scrapy\Twisted-18.9.0-cp36-cp36m-win_amd64.whl
复制代码
  • Pywin32
    可执行文件,挑选与Python对应版本安装就好。
  • Scrapy
  1. pip install scrapy
复制代码
这里我使用了Anaconda来安装scrapy,安装时只需要一条语句:
  1. conda install scrapy
复制代码
3.2 网站分析
网易云音乐首页:


图3.1 网易云官网首页.png
爬取思路有两种:
1.基于网页原代码,利用正则表达式、XPath等获取数据;
2.基于每次请求的API,直接获取所需数据;
本文采用第二种,针对电视剧《旋风少女》插曲的评论做简单说明:


图3.2 《旋风少女》主题曲评论.png
查看NetWork,发起请求,我们可以看到,数据保存在这里:


图3.3 网页数据.png
请求地址为:
  1. https://music.163.com/weapi/v1/resource/comments/R_SO_4_28936510?csrf_token=
复制代码


image.png
但是Request HEaders里的Cookie值、FromData里的params、encSecKey都是加密过的。开始解密:


图3.4 知乎.png
  1. http://music.163.com/api/v1/resource/comments/R_SO_4_28936510
复制代码


图3.5 网页.png
很好,但是很不巧的是网易云设置了反爬虫,根本不了手,爬虫时会出现以下错误:
  1. 1.{"code":-460,"msg":"Cheating"}
复制代码
这是网上存在的解决办法:
更换动态IP的:
  • 我跟网易云音乐爬虫不得不说的故事
复制请求头的:
  • Python爬网易云音乐的那些事
说明:上面两种方法在现在是行不通的,网易云加强了反爬虫机制,对请求头中的Cookie值进行了加密,所以有了下面这些对请求头中的Cookie值进行解密的:
  • 如何爬网易云音乐的评论数?
  • 用Python代码来下载任意指定网易云歌曲(超详细版)
但是,这种解密方法繁琐复杂,本文采用@Binaryify团队开发的[NeteaseCloudMusicApi]获取请求,这是一个相当便利、好用的API,感谢Binaryify。
3.3 功能特性
此次爬虫,下面的所有功能,都可以实现:
  1. 获取用户信息 , 歌单,收藏,mv, dj 数量
  2. 获取用户歌单
  3. 获取用户电台
  4. 获取用户关注列表
  5. 获取用户粉丝列表
  6. 获取用户动态
  7. 获取用户播放记录
  8. 获取精品歌单
  9. 获取歌单详情
  10. 搜索
  11. 搜索建议
  12. 获取歌词
  13. 歌曲评论
  14. 收藏单曲到歌单
  15. 专辑评论
  16. 歌单评论
  17. mv 评论
  18. 电台节目评论
  19. banner
  20. 获取歌曲详情
  21. 获取专辑内容
  22. 获取歌手单曲
  23. 获取歌手 mv
  24. 获取歌手专辑
  25. 获取歌手描述
  26. 获取相似歌手
  27. 获取相似歌单
  28. 相似 mv
  29. 获取相似音乐
  30. 获取最近 5 个听了这首歌的用户
  31. 获取每日推荐歌单
  32. 获取每日推荐歌曲
  33. 私人 FM
  34. 喜欢音乐
  35. 歌单 ( 网友精选碟 )
  36. 新碟上架
  37. 热门歌手
  38. 最新 mv
  39. 推荐 mv
  40. 推荐歌单
  41. 推荐新音乐
  42. 推荐电台
  43. 推荐节目
  44. 独家放送
  45. mv 排行
  46. 获取 mv 数据
  47. 播放 mv/视频
  48. 排行榜
  49. 歌手榜
  50. 云盘
  51. 电台 - 推荐
  52. 电台 - 分类
  53. 电台 - 分类推荐
  54. 电台 - 订阅
  55. 电台 - 详情
  56. 电台 - 节目
  57. 获取动态
  58. 获取热搜
  59. 发送私信
  60. 发送私信歌单
  61. 新建歌单
  62. 收藏/取消收藏歌单
  63. 歌单分类
  64. 收藏的歌手列表
  65. 订阅的电台列表
  66. 相关歌单推荐
  67. 付费精选接口
  68. 音乐是否可用检查接口
  69. 获取视频数据
  70. 发送/删除评论
  71. 热门评论
  72. 视频评论
  73. 所有榜单
  74. 所有榜单内容摘要
  75. 收藏视频
  76. 收藏 MV
  77. 视频详情
  78. 相关视频
  79. 关注用户
  80. 新歌速递
  81. 喜欢音乐列表(无序)
  82. 收藏的 MV 列表
复制代码
本文以其中几个为例,进行数据爬取和文本挖掘:
3.4 歌单
我们找到歌单页面为下:


图3.6 歌单.png
可以看到:
语种有:华语、欧美、日语、韩语、小语种;
风格有:流行、摇滚、民谣、电子、舞曲、说唱、轻音乐、说唱、爵士、乡村、古典、民族、英伦、金属、朋克、蓝调、雷鬼、世界音乐、拉丁、古风等;还有对歌单的场景、情感、主题分类。
我们不对其进行帅选,爬取所有种类的歌单。当每页为35个歌单的时候,一共有38页;当每页为20个歌单的时候,一共有66页,我们把66页一共1306个的歌单信息爬取下来:
  1. 1.class MenuSpider(scrapy.Spider):
  2. 2.    name = 'menu'
  3. 3.    allowed_domains = ['localhost:3000']
  4. 4.    start_urls = ['http://localhost:3000/']
  5. 5.    allplaylist_url = 'http://localhost:3000/top/playlist?order=hot&cat=%E5%85%A8%E9%83%A8&limit=20&offset={offset}'
  6. 6.
  7. 7.    def start_requests(self):
  8. 8.        for i in range(0, 66):
  9. 9.            yield Request(self.allplaylist_url.format(offset=i * 20), callback=self.parse_allplaylist)
  10. 10.
  11. 11.    def parse_allplaylist(self, response):
  12. 12.        result = json.loads(response.text)
  13. 13.        item = MusicmenuItem()
  14. 14.        for field in item.fields:
  15. 15.            if field in result.keys():
  16. 16.                item[field] = result.get(field)
  17. 17.                yield item
复制代码
3.5 歌曲
这是一个歌单下面的几十首歌曲,每首歌都有歌曲名称、歌手、时长、所属专辑、发行时间、评论等。像这个歌单《一个人在外漂泊,记得按时听歌呀》一共有40首歌。


图3.7 歌单.png
我们选择爬取歌曲评论信息的时候一并把歌曲信息爬下来。
3.6 歌曲评论
我们的目的是获取K个歌单下面的M首歌曲的前N页评论信息。


图3.8 歌曲评论.png
接下来,连接数据库,提取上面所爬歌单的id,根据id值获得每个歌单下面的歌曲id,再根据歌曲id值获得每首歌下面的评论信息。执行翻页操作,从而最终获取1306个歌单下面的前30首歌曲的前10页评论:
  1. 1.# -*- coding: utf-8 -*-  
  2. 2.import time
  3. 3.import scrapy
  4. 4.from scrapy import Spider,Request
  5. 5.import io
  6. 6.import sys
  7. 7.import json
  8. 8.import pandas as pd
  9. 9.import pymongo
  10. 10.from wangyiyun.items import WangyiyunCommentItem
  11. 11.from wangyiyun.items import WangyiyunPlaylistItem
  12. 12.from wangyiyun.items import WangyiyunAllPlaylistItem
  13. 13.
  14. 14.sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改变标准输出的默认编码  
  15. 15.
  16. 16.class MusiccommentsSpider(scrapy.Spider):
  17. 17.    name = 'musiccomments'
  18. 18.    allowed_domains = ['localhost:3000']
  19. 19.    start_urls = ['http://localhost:3000/comment/music?id=296883/']
  20. 20.    allplaylist_url = 'http://localhost:3000/top/playlist?order=hot&cat=%E5%85%A8%E9%83%A8&limit=20&offset={offset}'
  21. 21.    playlist_url = 'http://localhost:3000/playlist/detail?id={id}'
  22. 22.    comment_url = 'http://localhost:3000/comment/music?id={id}&offset={offset}&limit=20'
  23. 23.    num_comment = 0
  24. 24.    num_page = 0
  25. 25.    song_id = 0
  26. 26.    results = ''
  27. 27.
  28. 28.
  29. 29.    def start_requests(self):
  30. 30.        client = pymongo.MongoClient(host='localhost', port=27017)
  31. 31.        db = client['music']
  32. 32.        collection = db['menu']
  33. 33.        # 将数据库数据转为dataFrame  
  34. 34.        menu = pd.DataFrame(list(collection.find()))
  35. 35.        num = menu['playlists']
  36. 36.        result = pd.DataFrame(num.iloc[0])
  37. 37.        for i in range(1, 66):
  38. 38.            data2 = pd.DataFrame(num.iloc[i])
  39. 39.            result = pd.concat([result, data2], ignore_index=True)
  40. 40.        print(result.shape)
  41. 41.        id = result['id']
  42. 42.        for i in range(0, 1000):
  43. 43.            yield Request(self.playlist_url.format(id=id.iloc[i]), callback=self.parse_playlist)
  44. 44.
  45. 45.    def parse_playlist(self, response):
  46. 46.        result = json.loads(response.text)
  47. 47.        item = WangyiyunPlaylistItem()
  48. 48.        for field in item.fields:
  49. 49.            if field in result.keys():
  50. 50.                item[field] = result.get(field)
  51. 51.                yield item
  52. 52.
  53. 53.        for j in range(0, 30):
  54. 54.            for k in range(0,10):
  55. 55.                yield Request(
  56. 56.                    self.comment_url.format(id=result.get('playlist').get('tracks')[j].get('id'), offset=k * 20),
  57. 57.                    callback=self.parse_comment, dont_filter=True)
  58. 58.
  59. 59.    def parse_comment(self, response):
  60. 60.        result = json.loads(response.text)
  61. 61.        item = WangyiyunCommentItem()
  62. 62.        #print(response.text.encode('utf-8','ignore'))  
  63. 63.        for field in item.fields:
  64. 64.            if field in result.keys():
  65. 65.                item[field] = result.get(field)
  66. 66.                yield item
复制代码
获取了13943个文档。由于爬取时歌曲信息和评论信息保存到了一张表里,去掉其中的歌曲信息,评论信息约有12000*20=24万条。


图3.9 评论.png
说明:由于爬取的时候IP被ban,这24万条评论并非所有,这一问题在后文中处理。


image.png
并且,IP被ban还导致我网易云音乐的评论是看不了的,加载不出来的。。。


图3.10 bug.png
3.7 网易云音乐用户
爬取思路:我们从网易云音乐的大V云音乐小秘书开始,爬取其关注和粉丝,再爬取其关注者的关注和粉丝,粉丝的关注和粉丝,以此类推,不断递归,雪球会越滚越大,从而完成操作。
代码奉上:
  1. 1.# -*- coding: utf-8 -*-  
  2. 2.import time
  3. 3.import scrapy
  4. 4.import json
  5. 5.from scrapy import Spider, Request
  6. 6.from WangyiyunUser.items import WangyiyunuserItem
  7. 7.
  8. 8.class UserSpider(scrapy.Spider):
  9. 9.    name = 'user'
  10. 10.    allowed_domains = ['localhost:3000']
  11. 11.    start_urls = ['http://localhost:3000/']
  12. 12.    user_url = 'http://localhost:3000/user/detail?uid={uid}'
  13. 13.    follows_url = 'http://localhost:3000/user/follows?uid={uid}&offset={offset}&limit={limit}'
  14. 14.    followers_url = 'http://localhost:3000/user/followeds?uid={uid}&offset={offset}&limit={limit}'
  15. 15.    start_uid = '9003'
  16. 16.    follows_next_page=0
  17. 17.    followers_next_page=0
  18. 18.
  19. 19.    def start_requests(self):
  20. 20.        yield Request(self.user_url.format(uid=self.start_uid), self.parse_user,dont_filter = True)
  21. 21.
  22. 22.        yield Request(self.follows_url.format(uid=self.start_uid, limit=30, offset=0),
  23. 23.                      self.parse_follows,dont_filter = True)
  24. 24.
  25. 25.        yield Request(self.followers_url.format(uid=self.start_uid, limit=30, offset=0),self.parse_followers,dont_filter = True)
  26. 26.
  27. 27.
  28. 28.    def parse_user(self, response):
  29. 29.        result = json.loads(response.text)
  30. 30.        item = WangyiyunuserItem()
  31. 31.
  32. 32.        for field in item.fields:
  33. 33.            if field in result.keys():
  34. 34.                item[field] = result.get(field)
  35. 35.        yield item
  36. 36.        #print(result.get('profile').get('userId'))  
  37. 37.
  38. 38.        yield Request(
  39. 39.          self.follows_url.format(uid=result.get('profile').get('userId'), limit=30, offset=0),
  40. 40.            self.parse_follows,dont_filter = True)
  41. 41.
  42. 42.        yield Request(
  43. 43.            self.followers_url.format(uid=result.get('profile').get('userId'), limit=30, offset=0),
  44. 44.            self.parse_followers,dont_filter = True)
  45. 45.
  46. 46.    def parse_follows(self, response):
  47. 47.        results = json.loads(response.text)
  48. 48.        print('正在判断关注者:')
  49. 49.        if 'follow' in results.keys():
  50. 50.            for result in results.get('follow'):
  51. 51.                yield Request(self.user_url.format(uid=result.get('userId')),
  52. 52.                              self.parse_user,dont_filter = True)
  53. 53.
  54. 54.
  55. 55.        if results.get('more') == True:
  56. 56.            self.follows_next_page = self.follows_next_page+1
  57. 57.            yield Request(self.follows_url.format(uid=self.start_uid, limit=30, offset=self.follows_next_page*30),
  58. 58.                          self.parse_follows,dont_filter = True)
  59. 59.
  60. 60.
  61. 61.    def parse_followers(self, response):
  62. 62.        results = json.loads(response.text)
  63. 63.
  64. 64.        if 'followeds' in results.keys():
  65. 65.            for result in results.get('followeds'):
  66. 66.                yield Request(self.user_url.format(uid=result.get('userId')),
  67. 67.                              self.parse_user,dont_filter = True)
  68. 68.
  69. 69.
  70. 70.        if results.get('more') == True:
  71. 71.            self.followers_next_page=self.followers_next_page+1
  72. 72.            yield Request(self.followers_url.format(uid=self.start_uid, limit=30, offset=self.followers_next_page*30),
  73. 73.                          self.parse_followers,dont_filter = True)
复制代码
最终在IP被ban之前获得了14974条详情。


图3.10 详情.png
四、数据分析
4.1 歌单
4.1.1 播放数量最多的TOP20歌单
导入包,设置中文字体支持
  1. 1.import pymongo
  2. 2.import pandas as pd
  3. 3.import numpy as np
  4. 4.import matplotlib.pyplot as plt
  5. 5.from pylab import mpl
  6. 6.#设置图片显示字体对汉字的支持  
  7. 7.mpl.rcParams['font.sans-serif'] = ['SimHei']
  8. 8.client = pymongo.MongoClient(host='localhost', port=27017)
复制代码
从数据库导入数据
  1. 1.db = client['music']
  2. 2.collection = db['menu']
  3. 3.# 将数据库数据转为dataFrame  
  4. 4.data = pd.DataFrame(list(collection.find()))
复制代码
查看数据维度
  1. 1.print(data.shape)
复制代码
每页的歌单保存为一个文档,66页的歌单,一共有66个文档。
取其中一页歌单,查看内容
  1. 1.num=data['playlists']
  2. 2.print(num.iloc[0])
复制代码
为方便观察,对其做json解析。限于篇幅,取其中一个歌单的内容显示如下:
  1. 1.[{
  2. 2.    'name': '你是个成熟的成年人了,你该戒掉情绪了。',
  3. 3.    'id': 2468145627,
  4. 4.    'trackNumberUpdateTime': 1540176152147,
  5. 5.    'status': 0,
  6. 6.    'userId': 49341371,
  7. 7.    'createTime': 1539449979814,
  8. 8.    'updateTime': 1540176152147,
  9. 9.    'subscribedCount': 58406,
  10. 10.    'trackCount': 43,
  11. 11.    'cloudTrackCount': 0,
  12. 12.    'coverImgUrl': 'http://p2.music.126.net/qXN1QIV_mGUV1BusdRX1CA==/109951163602371733.jpg',
  13. 13.    'coverImgId': 109951163602371730,
  14. 14.    'description': '-\n\n你要做一个不动声色的大人了。不准情绪化,不准偷偷想念,不准回头看。去过自己另外的生活。\n\n以前的你,哭着哭着就笑了。\n\n现在的你,笑着笑着就哭了。\n\n到了一定的年纪,眼泪越来越少,因为身边再也没有一个能帮你擦眼泪的人。\n\n在成年人的世界里,最让人想哭的三个字是:不要哭。\n\n-\n\n人生还有眼泪也冲刷不干净的巨大悲伤,还有难忘的痛苦让你们即使想哭也不能流泪。\n\n怀揣着痛苦和悲伤,即使如此也要带上它们笑着前行。\n\n-\n\n如果可以,往后请让笑容比眼泪多。就算要哭,每一滴眼泪的名字也应该是——喜极而泣。\n\n-\n\n封面:站酷插画师Y_jianjian',
  15. 15.    'tags': ['华语', '流行', '治愈'],
  16. 16.    'playCount': 4370831,
  17. 17.    'trackUpdateTime': 1546744947197,
  18. 18.    'specialType': 0,
  19. 19.    'totalDuration': 0,
  20. 20.    'creator': {
  21. 21.        'defaultAvatar': False,
  22. 22.        'province': 440000,
  23. 23.        'authStatus': 0,
  24. 24.        'followed': False,
  25. 25.        'avatarUrl': 'http://p1.music.126.net/NbMIANWbmL6PVBmduaDzqA==/109951163776645958.jpg',
  26. 26.        'accountStatus': 0,
  27. 27.        'gender': 1,
  28. 28.        'city': 441500,
  29. 29.        'birthday': 845481600000,
  30. 30.        'userId': 49341371,
  31. 31.        'userType': 200,
  32. 32.        'nickname': '一点波澜-',
  33. 33.        'signature': '激不起一点波澜。',
  34. 34.        'description': '',
  35. 35.        'detailDescription': '',
  36. 36.        'avatarImgId': 109951163776645950,
  37. 37.        'backgroundImgId': 109951163373553600,
  38. 38.        'backgroundUrl': 'http://p1.music.126.net/O3aDHMNl_VW7GgK2VnGz9Q==/109951163373553592.jpg',
  39. 39.        'authority': 0,
  40. 40.        'mutual': False,
  41. 41.        'expertTags': ['华语', '流行', '欧美'],
  42. 42.        'experts': None,
  43. 43.        'djStatus': 10,
  44. 44.        'vipType': 11,
  45. 45.        'remarkName': None,
  46. 46.        'avatarImgIdStr': '109951163776645958',
  47. 47.        'backgroundImgIdStr': '109951163373553592',
  48. 48.        'avatarImgId_str': '109951163776645958'
  49. 49.    },
  50. 50.    'tracks': None,
  51. 51.    'subscribers': [{
  52. 52.        'defaultAvatar': False,
  53. 53.        'province': 440000,
  54. 54.        'authStatus': 0,
  55. 55.        'followed': False,
  56. 56.        'avatarUrl': 'http://p1.music.126.net/_XE9wV7-4JlWUPf51pnM_w==/109951163772509594.jpg',
  57. 57.        'accountStatus': 0,
  58. 58.        'gender': 2,
  59. 59.        'city': 440700,
  60. 60.        'birthday': -2209017600000,
  61. 61.        'userId': 515582083,
  62. 62.        'userType': 0,
  63. 63.        'nickname': '小心我锤爆你',
  64. 64.        'signature': '',
  65. 65.        'description': '',
  66. 66.        'detailDescription': '',
  67. 67.        'avatarImgId': 109951163772509600,
  68. 68.        'backgroundImgId': 109951163772503820,
  69. 69.        'backgroundUrl': 'http://p1.music.126.net/DQiWNBKXye4i_pbaSzUi9A==/109951163772503826.jpg',
  70. 70.        'authority': 0,
  71. 71.        'mutual': False,
  72. 72.        'expertTags': None,
  73. 73.        'experts': None,
  74. 74.        'djStatus': 0,
  75. 75.        'vipType': 0,
  76. 76.        'remarkName': None,
  77. 77.        'avatarImgIdStr': '109951163772509594',
  78. 78.        'backgroundImgIdStr': '109951163772503826',
  79. 79.        'avatarImgId_str': '109951163772509594'
  80. 80.    }],
  81. 81.    'subscribed': None,
  82. 82.    'commentThreadId': 'A_PL_0_2468145627',
  83. 83.    'newImported': False,
  84. 84.    'adType': 0,
  85. 85.    'highQuality': False,
  86. 86.    'privacy': 0,
  87. 87.    'ordered': True,
  88. 88.    'anonimous': False,
  89. 89.    'shareCount': 520,
  90. 90.    'coverImgId_str': '109951163602371733',
  91. 91.    'commentCount': 403,
  92. 92.    'alg': 'alg_sq_topn_lr'
  93. 93.},
复制代码
我们将第一个文档,即第一页歌单数据转化为数据框,并查看其数据维度:
  1. 1.print(pd.DataFrame(num.iloc[0]).shape)
复制代码
结果:
  1. 1.(20, 33)
复制代码
一共有20行,33列。即第一页的20个歌单中,每个歌单都有33个字段。将66页的所有歌单合并到一起,查看数据维度:
  1. 1.result=pd.DataFrame(num.iloc[0])
  2. 2.for i in range(1,66):
  3. 3.    data2=pd.DataFrame(num.iloc[i])
  4. 4.    result=pd.concat([result,data2],ignore_index=True)
  5. 5.print(result.shape)
复制代码
结果:
  1. 1.(1306, 33)
复制代码
所有全部歌单一共有1306个,每个歌单33个字段。查看行名:
  1. 1.print(result.columns.values.tolist())
复制代码
33个字段为下所示:
  1. 1.['adType', 'alg', 'anonimous', 'cloudTrackCount', 'commentCount', 'commentThreadId', 'coverImgId', 'coverImgId_str', 'coverImgUrl', 'createTime', 'creator', 'description', 'highQuality', 'id', 'name', 'newImported', 'ordered', 'playCount', 'privacy', 'shareCount', 'specialType', 'status', 'subscribed', 'subscribedCount', 'subscribers', 'tags', 'totalDuration', 'trackCount', 'trackNumberUpdateTime', 'trackUpdateTime', 'tracks', 'updateTime', 'userId']
复制代码
播放数量最多的TOP20歌单:
  1. 1.result1=result.sort_values(by=['playCount'],ascending = False)
  2. 2.result1['playCount']
  3. 3.result2=pd.concat([result1['name'],result1['playCount']],axis=1,ignore_index=False)
  4. 4.print((pd.DataFrame(result2)).shape)
  5. 5.print((pd.DataFrame(result2)).head)
  6. 6.data=result2
  7. 7.data.index=data['name']
  8. 8.colors = '#6D6D6D' # 设置标题颜色为灰色  
  9. 9.color_line = '#CC2824'
  10. 10.fontsize_title = 20
  11. 11.from IPython.core.pylabtools import figsize # import figsize  
  12. 12.figsize(12.5, 4) # 设置 figsize  
  13. 13.plt.rcParams['savefig.dpi'] = 200 #图片像素  
  14. 14.#plt.rcParams['figure.dpi'] = 200 #分辨率  
  15. 15.# 默认的像素:[6.0,4.0],分辨率为100,图片尺寸为 600&400  
  16. 16.# 指定dpi=200,图片尺寸为 1200*800  
  17. 17.# 指定dpi=300,图片尺寸为 1800*1200  
  18. 18.# 设置figsize可以在不改变分辨率情况下改变比例  
  19. 19.# 我们使用R语言中ggplot的风格  
  20. 20.plt.style.use('ggplot')
  21. 21.data[1:21].plot(kind='barh',color=color_line).invert_yaxis()
  22. 22.#使用 pd.Series把dataframe转成Series  
  23. 23.#data = pd.Series(data['playCount'].values)  
  24. 24.#for y,x in enumerate(list(data['playCount'].values[1:21])):  
  25. 25.for y,x in enumerate(list(data.iloc[:,1][1:21].values)):
  26. 26.    plt.text(x+1600000,y+0.3,'%s' %round(x,1),ha='center',color=colors)
  27. 27.    #plt.text(x-20,y+0.3,'%s' %x,color=colors)  
  28. 28.plt.xlabel('播放数量')
  29. 29.plt.ylabel('歌单名称')
  30. 30.plt.title('播放数量最多的TOP20歌单', color = colors, fontsize=fontsize_title)
  31. 31.plt.tight_layout()
  32. 32.plt.savefig('播放数量最多的TOP20歌单.png',dpi=200)
  33. 33.plt.show()
复制代码
结果:


图4.1 播放歌单TOP20.png
显示为文本:
  1. 1.name
  2. 2.听说你也在找好听的华语歌                  41094772
  3. 3.那些喜欢到循环播放的歌                   37185064
  4. 4.失恋必听歌单 | 因为你突然听懂了很多歌          31393852
  5. 5.2018年度最热新歌TOP100              30460302
  6. 6.别急,甜甜的恋爱马上就轮到你了               27107300
  7. 7.温柔暴击 | 沉溺于男友音的甜蜜乡             18519378
  8. 8.最是粤语最为情深 也唯独你最难忘怀             17338788
  9. 9.提神醒脑 疯狂抖腿魔性摇头.GIF             15403695
  10. 10.Hip-hop | 少女心狙击手              12368797
  11. 11.你最想对暗恋的人 说的一句话是什么             11561604
  12. 12.风月无憾 | 你是我有关青春 最美的句读           9827816
  13. 13.新的一年,希望你喜欢的人也喜欢你               8841251
  14. 14.【2018年度电影精选| Ready Story 】     8747021
  15. 15."若是心怀旧梦 就别再无疾而终"               8706438
  16. 16.“长大”这两个字,孤独得连偏旁都没有             8587671
  17. 17.如何用手机铃声惊艳四座? 日语篇               8059432
  18. 18.再见大侠:武侠小说泰斗金庸逝世                7993862
  19. 19.KTV必点:有没有一首歌,唱着唱着就泪奔           7890135
  20. 20.你放弃过一个爱了很久的人吗?                 7818393
  21. 21.欧美·耳朵怀孕 | 盘点那些流行歌手             7497257
复制代码
播放量第一的为《听说你也在找好听的华语歌 》,播放数高达4109万多。第二为《那些喜欢到循环播放的歌》,播放量为3718万多。前20个歌单的播放量最少的也在749万以上。究其原因,有以下几点:
  • 歌单名本身很具诱惑力,很适合没有固定听歌意向的群体,较为大众化,是绝大多数人的首选。像《别急,甜甜的恋爱马上就轮到你了》《温柔暴击 | 沉溺于男友音的甜蜜乡》《你最想对暗恋的人 说的一句话是什么》《风月无憾 | 你是我有关青春 最美的句读》等,光听名字就很吸引人。
  • 创建人鹿白川,有网易云达人认证,粉丝数也高达9万多,实打实的大V。标签:音乐(华语、流行、欧美)、资讯(生活);其创建的歌单播放量动辄上百万,上千万,看来属于网易云音乐中的主力人物。他的主页:


图4.2 个人主页.png
  • 歌单下的歌曲本身质量就很高,这也是最重要的一点。
相反,查看播放量最少的20首:
  1. 1.中岛美嘉 Special Live 2019 广州/上海        85
  2. 2.霉霉丨泰勒斯威·夫特的Style        82
  3. 3.C95东方专辑收录(一专一首)        80
  4. 4.CLUB MIAMI HOHHOT 百大DJ-DENIZ KOYU        78
  5. 5.战歌舞曲        76
  6. 6.vlog         74
  7. 7.*我们自雪乡去往雾夏*(贰)        73
  8. 8.伴读喵自习室        71
  9. 9.细腻莫扎特        69
  10. 10.【开业歌曲】新店开业喜庆歌曲大全100首        67
  11. 11.邓丽君1982年香港伊丽莎白体育馆演唱会        65
  12. 12. 2019年精选电音 待制作 敬请期待        62
  13. 13. 一周日语新歌(12/29~01/04)        60
  14. 14.祺鑫时光轴2018年下        58
  15. 15.【纯音乐】你是否听过,那属于夏日的美好        49
  16. 16.方灿的Spotify歌单        42
  17. 17.冷门纯音| 轻叩心扉,静享惬意好时光        31
  18. 18.【我爱学习】学习解压轻音乐        29
  19. 19.【轻音乐】如何优雅地睡觉        24
  20. 20.思念的解药 即是归乡        19
复制代码
恰恰和上面三点条件都相反,也难怪不太受欢迎。
zhi

chi

zuo

zhe





长按扫码鼓励作者



热 门 推 荐
为你的Python程序加密
用Python开发计时器程序用Python爬取WordPress官网所有插件
用OpenCV和OCR识别图片中的表格数据
推荐Python中文社区旗下的几个服务类公众号

▼ 长按扫码上方二维码或点击下方阅读原文
免费成为社区注册会员,会员可以享受更多权益
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:200
帖子:40
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP