一、选题的背景

  QQ音乐是隶属于腾讯音乐娱乐集团的音乐流媒体平台。自2005年创立,QQ音乐注册用户总量已达8亿。QQ音乐以优质内容为核心,以大数据与互联网技术为推动力 ,致力于打造“智慧声态”的“立体”泛音乐生态圈,为用户提供多元化的音乐生活体验。通过对qq音乐热播榜的爬取与数据可视化分析,能够更好了解当代青年所关注的社会热点,了解当代青年的情感寄托等。

二、主题式网络爬虫设计方案

1.主题式网络爬虫名称:爬取qq音乐热播榜数据并数据分析及可视化

2.主题式网络爬虫爬取的内容与数据特征分析:

对qq音乐热播榜的“排名”,“时长”,“作者”,“歌名”四个数据进行爬取

3.主题式网络爬虫设计方案概述:

实现思路:登录qq音乐,进入qq音乐热播榜,进入网页开发人员工具,得到网页源代码,查找所需标签的代码,进行数据采集,完成后对数据进行相应的分析整理并存入文档中。读取文件进行数据清洗和数据可视化,绘制图形进行数据分析。接下来分析排行和时长的数据拟合分析,最后进行数据持久化。

技术难点:爬取信息时对标签的寻找,回归方程运用得不够熟练等。

三、主题页面的结构特征分析

1.主题页面的结构与特征分析

通过对页面结构的分析,发现<div class="main">元素中,发现所需要的数据。并进行查找,在标签<class="songlist_number">,<class="songlist_time">,<class="playlist_author">,<a>分别找到排名,时长,作者,歌名的数据。

url为https://y.qq.com/n/ryqq/toplist/26

网址首页

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据

 

 

2.Htmls 页面解析

通过查找网页源代码,浏览其中元素,并对其中元素进行解析

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据_02

 

 

 

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_QQ音乐数据可视化项目做了哪些模块_03

 

 

3.节点(标签)查找方法与遍历方法

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据可视化_04

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_QQ音乐数据可视化项目做了哪些模块_05

 

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据可视化_06

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_QQ音乐数据可视化项目做了哪些模块_07

 

四、网络爬虫程序设计

1.数据爬取与采集

#网页的爬取

1 #导入相关库
 2 import requests
 3 #引入pandas用于数据可视化
 4 import pandas as pd
 5 import numpy as np
 6 import matplotlib.pyplot as plt
 7 import matplotlib
 8 import csv
 9 import scipy as sp
10 import seaborn as sns
11 from sklearn.linear_model import LinearRegression
12 from bs4 import BeautifulSoup
13 from pandas import DataFrame
14 from scipy.optimize import leastsq
15 #搜索网址
16 url='https://y.qq.com/n/ryqq/toplist/26'
17 #伪装爬虫
18 headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}
19 
20 r = requests.get(url,  headers=headers,timeout=10)
21 
22 def getHTMLText(url,timeout = 30):
23     try:
24         #用requests抓取网页信息
25         r = requests.get(url, timeout = 30)       
26         #可以让程序产生异常时停止程序
27         r.raise_for_status()                      
28         #设置编码标准
29         r.encoding = r.apparent_encoding          
30         return r.text
31     except:
32         return '产生异常'
33 
34     
35 #统一编码
36 html=r.text
37 #html.parser表示用BeautifulSoup库解析网页
38 soup=BeautifulSoup(html,'html.parser')
39 #基于bs4库HTML的格式输出,让页面更友好的显示
40 print(soup.prettify())

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据_08

 

 

1 #爬取数据
 2 #爬取排行
 3 rank=[]
 4 for m in soup.find_all(class_="songlist__number"):
 5     rank.append(m.get_text().strip()) 
 6 print(rank)
 7 
 8 #爬取时长
 9 time=[]
10 for n in soup.find_all(class_="songlist__time"):
11     time.append(n.get_text().strip()) 
12     
13 print(time)
14 
15 #爬取歌曲名
16 song=[]
17 for n in soup.find_all("a",class_=""):
18     song.append(n.get_text().strip()) 
19 print(song)
20 
21 #爬取作者
22 name=[]
23 for n in soup.find_all(class_="playlist__author"):
24     name.append(n.get_text().strip()) 
25 print(name)
1 #将数据整理成表格
 2 num=20
 3 lst = []
 4 print('{:^5}\t{:^40}\t{:^10}\t{:^20}'.format('排名','时长','作者','歌名'))
 5 for i in range(num):
 6     
 7     print('{:^5}\t{:^40}\t{:^10}\t{:^20}'.format(i+1, time[i], name[i], song[i]))
 8     lst.append([i+1, time[i], name[i], song[i]])
 9 df = pd.DataFrame(lst,columns=['排名','时长','作者','歌名'])
10 
11 #将数据存入excel表
12 A = r'song.xlsx'
13 df.to_excel(A)

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_html_09

 

 

2.对数据进行清洗和处理

1 #读取excel表
 2 df=pd.DataFrame(pd.read_excel('song.xlsx'))
 3 print(df)

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据_10

1 #数据清洗及处理
2 print('\n====各列是否有空值情况如下:====')
3 df.isnull() 
4 df.isna().head()

 

 

 

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据_11

 

 

1 print('\n====各列是否有重复值情况如下:====')
2 print(df.duplicated())

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_QQ音乐数据可视化项目做了哪些模块_12

 

 

1 #数据汇总
2 print(df.describe())
3 # 查找异常值
4 df.describe()

 

 

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_html_13

 

 

4.数据分析与可视化

1 #数据分析
2 #数据可视化
3 import seaborn as sns
4 plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
5 plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
6 sns.set(style='white')
7 plt.grid()
8 sns.regplot(df.排名,df.时长)

 

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据可视化_14

 

1 #画出散点图
 2 # 用来正常显示中文标签
 3 plt.rcParams['font.sans-serif'] = ['SimHei'] 
 4 # 用来正常显示负号
 5 plt.rcParams['axes.unicode_minus'] = False  
 6 N=20
 7 x=np.random.rand(N)
 8 y=np.random.rand(N)
 9 size=50
10 plt.grid()
11 plt.xlabel("排名")
12 plt.ylabel("热度")
13 plt.scatter(x,y,size,color='r',alpha=0.5,marker="o")
14 #散点图  kind='reg'
15 sns.jointplot(x="排名",y="时长",data=df,kind='reg')
16 #  kind='hex'
17 sns.jointplot(x="排名",y="时长",data=df,kind='hex')
18 # kind='kde'
19 sns.jointplot(x="排名",y="时长",data=df,kind="kde")

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_html_15

 

 

 

1 import requests
 2 from bs4 import BeautifulSoup
 3 import bs4
 4 #引入pandas用于数据可视化
 5 import pandas as pd   
 6 from pandas import DataFrame
 7 import seaborn as sns
 8 import numpy as np
 9 import matplotlib.pyplot as plt
10 from scipy.optimize import leastsq
11 from sklearn.linear_model import LinearRegression
12 #绘制
13 plt.rcParams['font.sans-serif']=['SimHei'] 
14 a = df.排名
15 b = df.时长
16 plt.bar(a,b, color='b',label='时长')
17 plt.xlabel("排名")
18 plt.ylabel("时长")
19 plt.title('排名与时长数据柱状图')
20 plt.legend(loc=1)
21 plt.grid()
22 plt.show()

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据可视化_16

 

 

1 #绘制盒图
 2 import seaborn as sns
 3 def box():
 4     plt.title('时长指数盒图')
 5     a = df.排名
 6     b = df.时长
 7     sns.boxplot(a,b)
 8     plt.xlabel("排名")
 9     plt.ylabel("时长")
10 
11 box()

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_html_17

 

1 #绘制折线图
 2 plt.rcParams['font.sans-serif']=['SimHei'] 
 3 a = df.排名
 4 b = df.时长
 5 plt.plot(a,b, color='r',label='时长')
 6 plt.xlabel("排名")
 7 plt.ylabel("时长")
 8 plt.title('排名与时长数据折线图')
 9 plt.legend(loc=1)
10 plt.grid()
11 plt.show()

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据可视化_18

 

 

1 #绘制直方图
 2 plt.figure(dpi=100)
 3 a = df.排名
 4 b = df.时长
 5 plt.bar(a,b,color='y')
 6 plt.title("排名与时长数据直方图")
 7 plt.xlabel("排名")
 8 plt.ylabel("时长")
 9 plt.grid()
10 plt.show()

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_QQ音乐数据可视化项目做了哪些模块_19

 

 

5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变

量之间的回归方程

1 #构建数据分析模型
 2 import numpy as np
 3 import pandas as pd
 4 import sklearn
 5 from sklearn import datasets
 6 from sklearn.linear_model import LinearRegression
 7 X = df[["排名"]]
 8 predict_model = LinearRegression()
 9 predict_model.fit(X, df[['时长']])
10 
11 print("回归系数为{}".format(predict_model.coef_))
12 print("回归方程截距:{}".format(predict_model.intercept_))

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据可视化_20

 

 

1 #选择排名和热度两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
 2 colnames=[" ","排名","时长","作者","歌名"]
 3 df = pd.read_excel('song.xlsx',skiprows=1,names=colnames)
 4 X = df.排名
 5 Y = df.时长
 6 Z = df.作者
 7 P = df.歌名
 8 def A():
 9     plt.scatter(X,Y,color="blue",linewidth=2)
10     plt.title("分析图",color="blue")
11     plt.grid()
12     plt.show()
13 def B():
14     plt.scatter(X,Y,color="green",linewidth=2)
15     plt.title("分析图",color="blue")
16     plt.grid()
17     plt.show()
18 def func(p,x):
19     a,b,c=p
20     return a*x*x+b*x+c
21 def error(p,x,y):
22     return func(p,x)-y
23 def main():
24     plt.figure(figsize=(10,6))
25     p0=[0,0,0]
26     Para = leastsq(error,p0,args=(X,Y))
27     a,b,c=Para[0]
28     print("a=",a,"b=",b,"c=",c)
29     plt.scatter(X,Y,color="blue",linewidth=2)
30     x=np.linspace(0,20,20)
31     y=a*x*x+b*x+c
32     plt.plot(x,y,color="blue",linewidth=2,)
33     plt.title("分析图")
34     plt.grid()
35     plt.show()
36 print(A())
37 print(B())
38 print(main())

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据_21

 

 

6.数据持久化

1 #数据持久化
2 A = r'song.xlsx'
3 df.to_excel(A)

QQ音乐数据可视化项目做了哪些模块 qq音乐数据中心在哪里_数据_22

 

 

7.将以上各部分的代码汇总,附上完整程序代码 

1 #导入相关库
  2 import requests
  3 #引入pandas用于数据可视化
  4 import pandas as pd
  5 import numpy as np
  6 import matplotlib.pyplot as plt
  7 import matplotlib
  8 import csv
  9 import scipy as sp
 10 import seaborn as sns
 11 from sklearn.linear_model import LinearRegression
 12 from bs4 import BeautifulSoup
 13 from pandas import DataFrame
 14 from scipy.optimize import leastsq
 15 #搜索网址
 16 url='https://y.qq.com/n/ryqq/toplist/26'
 17 #伪装爬虫
 18 headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62'}
 19 
 20 r = requests.get(url,  headers=headers,timeout=10)
 21 
 22 def getHTMLText(url,timeout = 30):
 23     try:
 24         #用requests抓取网页信息
 25         r = requests.get(url, timeout = 30)       
 26         #可以让程序产生异常时停止程序
 27         r.raise_for_status()                      
 28         #设置编码标准
 29         r.encoding = r.apparent_encoding          
 30         return r.text
 31     except:
 32         return '产生异常'
 33 
 34     
 35 #统一编码
 36 html=r.text
 37 #html.parser表示用BeautifulSoup库解析网页
 38 soup=BeautifulSoup(html,'html.parser')
 39 #基于bs4库HTML的格式输出,让页面更友好的显示
 40 print(soup.prettify())
 41 
 42 #爬取数据
 43 #爬取排行
 44 rank=[]
 45 for m in soup.find_all(class_="songlist__number"):
 46     rank.append(m.get_text().strip()) 
 47 print(rank)
 48 
 49 #爬取时长
 50 time=[]
 51 for n in soup.find_all(class_="songlist__time"):
 52     time.append(n.get_text().strip()) 
 53     
 54 print(time)
 55 
 56 #爬取歌曲名
 57 song=[]
 58 for n in soup.find_all("a",class_=""):
 59     song.append(n.get_text().strip()) 
 60 print(song)
 61 
 62 #爬取作者
 63 name=[]
 64 for n in soup.find_all(class_="playlist__author"):
 65     name.append(n.get_text().strip()) 
 66 print(name)
 67 
 68 #将数据整理成表格
 69 num=20
 70 lst = []
 71 print('{:^5}\t{:^40}\t{:^10}\t{:^20}'.format('排名','时长','作者','歌名'))
 72 for i in range(num):
 73     
 74     print('{:^5}\t{:^40}\t{:^10}\t{:^20}'.format(i+1, time[i], name[i], song[i]))
 75     lst.append([i+1, time[i], name[i], song[i]])
 76 df = pd.DataFrame(lst,columns=['排名','时长','作者','歌名'])
 77 
 78 #将数据存入excel表
 79 A = r'song.xlsx'
 80 df.to_excel(A)
 81 
 82 #读取excel表
 83 df=pd.DataFrame(pd.read_excel('song.xlsx'))
 84 df
 85 
 86 #数据清洗及处理
 87 print('\n====各列是否有空值情况如下:====')
 88 df.isnull() 
 89 df.isna().head()
 90 print('\n====各列是否有重复值情况如下:====')
 91 print(df.duplicated())
 92 # 查找异常值
 93 df.describe()
 94 #数据汇总
 95 print(df.describe())
 96 
 97 #数据分析
 98 #数据可视化
 99 import seaborn as sns
100 plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
101 plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
102 sns.set(style='white')
103 plt.grid()
104 sns.regplot(df.排名,df.时长)
105 #画出散点图
106 # 用来正常显示中文标签
107 plt.rcParams['font.sans-serif'] = ['SimHei'] 
108 # 用来正常显示负号
109 plt.rcParams['axes.unicode_minus'] = False  
110 N=20
111 x=np.random.rand(N)
112 y=np.random.rand(N)
113 size=50
114 plt.grid()
115 plt.xlabel("排名")
116 plt.ylabel("热度")
117 plt.scatter(x,y,size,color='r',alpha=0.5,marker="o")
118 #散点图  kind='reg'
119 sns.jointplot(x="排名",y="时长",data=df,kind='reg')
120 #  kind='hex'
121 sns.jointplot(x="排名",y="时长",data=df,kind='hex')
122 # kind='kde'
123 sns.jointplot(x="排名",y="时长",data=df,kind="kde")
124 
125 import requests
126 from bs4 import BeautifulSoup
127 import bs4
128 #引入pandas用于数据可视化
129 import pandas as pd   
130 from pandas import DataFrame
131 import seaborn as sns
132 import numpy as np
133 import matplotlib.pyplot as plt
134 from scipy.optimize import leastsq
135 from sklearn.linear_model import LinearRegression
136 #绘制
137 plt.rcParams['font.sans-serif']=['SimHei'] 
138 a = df.排名
139 b = df.时长
140 plt.bar(a,b, color='b',label='时长')
141 plt.xlabel("排名")
142 plt.ylabel("时长")
143 plt.title('排名与时长数据柱状图')
144 plt.legend(loc=1)
145 plt.grid()
146 plt.show()
147 
148 #绘制盒图
149 import seaborn as sns
150 def box():
151     plt.title('热度指数盒图')
152     a = df.排名
153     b = df.时长
154     sns.boxplot(a,b)
155     plt.xlabel("排名")
156     plt.ylabel("时长")
157 
158 box()
159 
160 #绘制折线图
161 plt.rcParams['font.sans-serif']=['SimHei'] 
162 a = df.排名
163 b = df.时长
164 plt.plot(a,b, color='r',label='时长')
165 plt.xlabel("排名")
166 plt.ylabel("时长")
167 plt.title('排名与时长数据折线图')
168 plt.legend(loc=1)
169 plt.grid()
170 plt.show()
171 
172 #构建数据分析模型
173 import numpy as np
174 import pandas as pd
175 import sklearn
176 from sklearn import datasets
177 from sklearn.linear_model import LinearRegression
178 X = df[["排名"]]
179 predict_model = LinearRegression()
180 predict_model.fit(X, df[['时长']])
181 
182 print("回归系数为{}".format(predict_model.coef_))
183 print("回归方程截距:{}".format(predict_model.intercept_))
184 
185 #选择排名和热度两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线
186 colnames=[" ","排名","时长","作者","歌名"]
187 df = pd.read_excel('song.xlsx',skiprows=1,names=colnames)
188 X = df.排名
189 Y = df.时长
190 Z = df.作者
191 P = df.歌名
192 def A():
193     plt.scatter(X,Y,color="blue",linewidth=2)
194     plt.title("分析图",color="blue")
195     plt.grid()
196     plt.show()
197 def B():
198     plt.scatter(X,Y,color="green",linewidth=2)
199     plt.title("分析图",color="blue")
200     plt.grid()
201     plt.show()
202 def func(p,x):
203     a,b,c=p
204     return a*x*x+b*x+c
205 def error(p,x,y):
206     return func(p,x)-y
207 def main():
208     plt.figure(figsize=(10,6))
209     p0=[0,0,0]
210     Para = leastsq(error,p0,args=(X,Y))
211     a,b,c=Para[0]
212     print("a=",a,"b=",b,"c=",c)
213     plt.scatter(X,Y,color="blue",linewidth=2)
214     x=np.linspace(0,20,20)
215     y=a*x*x+b*x+c
216     plt.plot(x,y,color="blue",linewidth=2,)
217     plt.title("分析图")
218     plt.grid()
219     plt.show()
220 print(A())
221 print(B())
222 print(main())
223 
224 #数据持久化
225 A = r'song.xlsx'
226 df.to_excel(A)

五、总结

1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?

根据数据分析可以发现,排名会随时长不稳定变化,图表可以更为直观的表现出排名与时长的关系和变化和反映出各个两者之间的关系。同时,经过结合标签“标题”进行分析,可以发现当代青年的关注点大致分布在“快歌”“热歌”这些领域。

2.在完成此设计过程中,得到哪些收获?以及要改进的建议?

在完成此次设计的途中可谓是九九八十一难,无论是网站爬取,图表制作还是数据分析,都出现过大大小小的问题。例如在寻找要爬取的网站时,曾因为无法找到相关信息,出现乱码等,不得不反反复复更换十来个网站进行爬取。在绘制图表的过程中,也因为饼状图,堆叠图,3d散点图等图表制作的不熟练导致频频失误,最后只好放弃,改用其他图表。但在此次设计的重重“劫难”中也让我学到了许多知识。