qq音樂熱播榜的爬取和數據分析


一、選題的背景

  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

網址首頁

 

 

2.Htmls 頁面解析

通過查找網頁源代碼,瀏覽其中元素,並對其中元素進行解析

 

 

 

 

 

3.節點(標簽)查找方法與遍歷方法

 

 

四、網絡爬蟲程序設計

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())

 

 

 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)

 

 

2.對數據進行清洗和處理
 1 #讀取excel表
 2 df=pd.DataFrame(pd.read_excel('song.xlsx'))
 3 print(df)

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

 

 

 

 

 

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

 

 

1 #數據匯總
2 print(df.describe())
3 # 查找異常值
4 df.describe()

 

 

 

 

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.時長)

 

 

 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")

 

 

 

 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()

 

 

 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()

 

 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()

 

 

 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()

 

 

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_))

 

 

 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())

 

 

6.數據持久化
1 #數據持久化
2 A = r'song.xlsx'
3 df.to_excel(A)

 

 

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散點圖等圖表制作的不熟練導致頻頻失誤,最后只好放棄,改用其他圖表。但在此次設計的重重“劫難”中也讓我學到了許多知識。首先,為了這次設計,我不得不求學於我的課本以及之前上的網課,回憶重溫之前的教學內容,除了令我對老師深厚的教學水准深感敬佩外,還鞏固了我的課內知識。其次,在遇到課本也解決不了的問題的時候,我學會了去利用同學 與網絡渠道去解決疑惑。這既鍛煉了我的交流能力,同時也讓我學習了頗多的課外知識,真是令我受益匪淺啊。此次作業,或許有很多不足,但是,這也令我意識到了自己的水平是多么的有限,對python這一門課程的理解是多么的有限。但是,這些不足也激起了我對python這門課程研究的動力。最后,我希望通過此次經歷,會使我在以后的學習中,更加努力的提高自己的能力,掌握更深的知識。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM