愛奇藝排行榜爬取及分析


一、選題背景

       隨着社會的發展、人類生活方式的變化,電影給我們的是生活的體驗,是對人類生活的一種追溯。電影已經成為現代人類生活當中不可缺少的一部分。電影是人們無聊時的消遣,一部好的電影會使人陶醉其中,發泄我們的情緒,升華情感,讓人翱翔在充滿藝術與美的空間里。所以我通過爬取愛奇藝排行榜更好的了解當下人們的關注的電影

二、設計方案 

1.主題式網絡爬蟲名稱:

    python網絡爬蟲之愛奇藝排行榜的爬取及分析

2.主題式網絡爬蟲爬取的內容與數據特征分析:

    爬取網頁電影排名,標題,熱度值。

3.方案概述:

訪問網頁得到狀態碼200,分析網頁源代碼,找出所需要的的標簽,逐個提取標簽保存到相同路徑csv文件中,讀取改文件,進行數據清洗,數據模型分析,數據可視化處理,繪制分布圖,用最小二乘法分析兩個變量間的二次擬合方程和繪制擬合曲線。

技術難點:做數據分析,即求回歸系數,因為標題是文字,無法與數字作比較,需要把標題這一列刪除才可。由於不明原因,輸出結果經常會顯示超出列表范圍。

三、主題頁面的結構特征分析

1.主題頁面的結構與特征分析:標題標簽為' div.rvi__tit1 '.熱度標簽 ' span.rvi__index__num'

url=https://www.iqiyi.com/ranks1/-1/0

2.頁面解析

首頁

 

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

 

 

 

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

 

 

 

 網頁爬取

 1 #導入庫
 2 import requests
 3 import pandas as pd
 4 import numpy as np
 5 import matplotlib.pyplot as plt
 6 import matplotlib
 7 import csv
 8 import scipy as sp
 9 import seaborn as sns
10 from sklearn.linear_model import LinearRegression
11 from bs4 import BeautifulSoup
12 from pandas import DataFrame
13 from scipy.optimize import leastsq
14 
15 #填入要請求的服務器地址
16 url="https://www.iqiyi.com/ranks1/-1/0"#愛奇藝熱播榜影視榜單
17 
18 #requests抓取網頁信息
19 def getHTMLText(url,timeout=30):
20     try:
21         r=requests.get(url,timeout=30) #用requests抓取網頁信息 
22         r.raise_for_status()           #異常捕捉  
23         r.encoding=r.apparent_encoding
24         return r.text
25     except:
26         return'產生異常'
27     
28 #html.parser表示用BeautifulSoup庫解析網頁
29 html=getHTMLText(url)
30 soup=BeautifulSoup(html,'html.parser')
31 
32 print(soup.prettify())
33  #按照標准縮進格式的結構輸出
34  
35 r=requests.get(url)
36 #請求網絡
37 r.encoding=r.apparent_encoding
38 #統一編碼
39 html = r.text
40 soup = BeautifulSoup(html,'lxml')
41 #type(soup)
42 print(soup.prettify())
43 #基於bs4庫HTML的格式輸出,讓頁面更友好的顯示
1 #獲取標題
2 title1=[]
3 for i in soup.find_all('div',
4                        class_='rvi__tit1'):
5     title1.append(i.get_text().strip())
6 title1
1 #獲取熱度
2 b1=[]
3 for i in soup.find_all('span', 
4                        class_='rvi__index__num'):
5     b1.append(i.get_text().strip())
6 b1
 1 #整合獲取內容
 2 print('{:^50}'.format('愛奇藝熱播榜'))
 3 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '名稱', '熱度'))
 4 for i in range(25):
 5     print('{:^5}\t{:^40}\t{:^10}'.format(i+1, title1[i], b1[i]))
 6 lit1=[]
 7 for i in range(25):
 8     lit1.append([i+1, title1[i], b1[i]])
 9 df1 = pd.DataFrame(lit1,columns=['排名', '名稱', '熱度'])
10 df1

 

 

 1 #愛奇藝必看榜影視榜單
 2 url="https://www.iqiyi.com/ranks1/-1/-6"
 3 def getHTMLText(url,timeout=30):
 4     try:
 5         r=requests.get(url,timeout=30) #用requests抓取網頁信息 
 6         r.raise_for_status()           #異常捕捉  
 7         r.encoding=r.apparent_encoding
 8         return r.text
 9     except:
10         return'產生異常'
11 html=getHTMLText(url)
12 soup=BeautifulSoup(html,'html.parser')
13 print(soup.prettify())
14 r=requests.get(url)
15 r.encoding=r.apparent_encoding
16 html = r.text
17 soup = BeautifulSoup(html,'lxml')
18 print(soup.prettify())
19 title2=[]
20 for i in soup.find_all('div', class_='rvi__tit1'):
21     title2.append(i.get_text().strip())
22 title2
23 b2=[]
24 for i in soup.find_all('span', 
25                        class_='rvi__index__num'):
26     b2.append(i.get_text().strip())
27 b2
28 print('{:^50}'.format('愛奇藝必看榜'))
29 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '名稱', '熱度'))
30 for i in range(25):
31     print('{:^5}\t{:^40}\t{:^10}'.format(i+1, title2[i], b2[i]))
32 lit2=[]
33 for i in range(25):
34     lit2.append([i+1, title2[i], b2[i]])
35 df2 = pd.DataFrame(lit2,columns=['排名', '名稱', '熱度'])
36 df2

 

 

1 #對獲取的數據進行持久化存儲
2 df1= pd.DataFrame(lit1,columns=['排名','名稱','熱度'])
3 df1.to_excel('D:/python/python1.xlsx')
4 df2= pd.DataFrame(lit2,columns=['排名','名稱','熱度'])
5 df2.to_excel('D:/python/python2.xlsx')
1 #讀取熱播榜excel文件
2 rank1=pd.DataFrame(pd.read_excel('D:/python/python1.xlsx'))
3 print(rank1)

 

 

1 #讀取必看榜excel文件
2 rank2=pd.DataFrame(pd.read_excel('D:/python/python2.xlsx'))
3 print(rank2)

 

 

1 #數據清
2 #1.刪除無效列
3 rank1.drop('名稱',axis=1,inplace=True)
4 print(rank1)
5 rank2.drop('名稱',axis=1,inplace=True)
6 print(rank2)

 

 

1 #2.檢查是否有重復值
2 print(rank1.duplicated()) 
3 print(rank2.duplicated())

 

 

1 #3.檢查是否有空值
2 print(rank1['熱度'].isnull().value_counts())
3 print(rank2['熱度'].isnull().value_counts())

 

 

1 #4.異常值處理
2 print(rank1.describe())
3 print(rank2.describe())

 

 

 1 #數據分析
 2 from sklearn.linear_model import LinearRegression
 3 X = df1.drop("名稱",axis=1)
 4 predict_model = LinearRegression()
 5 predict_model.fit(X,df1['熱度'])
 6 print("回歸系數為:",predict_model.coef_)
 7 X = df2.drop("名稱",axis=1)
 8 predict_model = LinearRegression()
 9 predict_model.fit(X,df2['熱度'])
10 print("回歸系數為:",predict_model.coef_)

 

 

 

 

1 #繪制排名與熱度的回歸圖
2 import seaborn as sns
3 plt.rcParams['font.sans-serif'] = ['SimHei']
4 plt.rcParams['axes.unicode_minus'] = False
5 sns.regplot(rank1.排名,rank1.熱度,label="熱播榜")
6 sns.regplot(rank2.排名,rank2.熱度,label="必看榜")

 

 

 1 #畫出散點圖
 2 # 用來正常顯示中文標簽
 3 plt.rcParams['font.sans-serif'] = ['SimHei']  
 4  # 用來正常顯示負號
 5 plt.rcParams['axes.unicode_minus'] = False 
 6 N=10
 7 x=np.random.rand(N)
 8 y=np.random.rand(N)
 9 size=50
10 plt.xlabel("排名")
11 plt.ylabel("熱度")
12 plt.scatter(x,y,size,color='r',alpha=0.5,marker="o")

 

 

1 #散點圖  kind='reg'
2 sns.jointplot(x="排名",y="熱度",
3               data=rank1,kind='reg',color='g')
4 sns.jointplot(x="排名",y="熱度",
5               data=rank2,kind='reg',color='r')

 

 

 

1 #  kind='hex'
2 sns.jointplot(x="排名",y="熱度",
3               data=rank1,kind='hex',color='g')
4 sns.jointplot(x="排名",y="熱度",
5               data=rank2,kind='hex',color='r')

 

 

 

1 # kind='kde'
2 sns.jointplot(x="排名",y="熱度",
3               data=rank1,kind="kde",space=0,color='g')
4 sns.jointplot(x="排名",y="熱度",
5               data=rank2,kind="kde",space=0,color='r')

 

 

 

 

 1 #選擇排名和最高熱度兩個特征變量,繪制分布圖,用最小二乘法分析兩個變量間的二次擬合方程和擬合曲線
 2 colnames=[" ","排名","名稱","最高熱度"]
 3 df1 = pd.read_excel('D:/python/python1.xlsx',skiprows=1,names=colnames)
 4 df2 = pd.read_excel('D:/python/python2.xlsx',skiprows=1,names=colnames)
 5 
 6 X1 = df1.排名
 7 Y1 = df1.最高熱度
 8 Z1 = df1.名稱
 9 
10 X2 = df2.排名
11 Y2 = df2.最高熱度
12 Z2 = df2.名稱
13 #最高熱度與排名關系圖
14 matplotlib.rcParams['font.sans-serif']=['SimHei']
15 plt.plot(X1,Y1,color="g", linewidth=2,label="熱播榜")
16 plt.plot(X2,Y2,color="r", linewidth=2,label="必看榜")
17 plt.legend(loc=1)
18 plt.xlabel("排名")
19 plt.ylabel("熱度")
20 plt.title('熱度與排名關系圖')
21 plt.show()

 

 

1 #最高熱度與排名柱狀關系圖
2 plt.bar(X2,Y2,color="r", linewidth=2,label="必看榜")
3 plt.bar(X1,Y1,color="g", linewidth=2,label="熱播榜")
4 plt.legend(loc=1)
5 plt.xlabel("排名")
6 plt.ylabel("熱度")
7 plt.title('熱度與排名柱狀關系圖')
8 plt.show()

 

 

 1 #畫出散點圖
 2 def A():
 3     plt.scatter(X1,Y1,color="g"
 4                 ,linewidth=2,label='必看榜')
 5     plt.scatter(X2,Y2,color="r"
 6                 ,linewidth=2,label='熱播榜')
 7     plt.legend(loc=1)
 8     plt.title("散點圖",color="blue")
 9     plt.grid()
10     plt.xlabel("排名")
11     plt.ylabel("最高熱度")
12     plt.show()
13       
14 def func(p,x):
15     a,b,c=p
16     return a*x*x+b*x+c
17 
18 def error(p,x,y):
19     return func(p,x)-y
20 
21 print(A())

 

 

 1 def main1():
 2     plt.figure(figsize=(10,6))
 3     p0=[0,0,0]
 4     Para = leastsq(error,p0,args=(X1,Y1))
 5     a,b,c=Para[0]
 6     print("a=",a,"b=",b,"c=",c)
 7     plt.scatter(X1,Y1,color="g",
 8                 linewidth=2,label='必看榜熱度值分布')
 9     plt.legend(loc=1)
10     x1=np.linspace(0,20,20)
11     y1=a*x1*x1+b*x1+c
12     plt.plot(x1,y1,color="red",
13              linewidth=2,label="必看榜擬合曲線")
14     plt.legend(loc=1)
15     plt.title("必看榜一元二次方程關系圖")
16     plt.xlabel("排名")
17     plt.ylabel("熱度")
18     plt.grid()
19     plt.show()
20     
21 print(main1())

 

 

 1 def main2():
 2     plt.figure(figsize=(10,6))
 3     p0=[0,0,0]
 4     Para = leastsq(error,p0,args=(X2,Y2))
 5     a,b,c=Para[0]
 6     print("a=",a,"b=",b,"c=",c)
 7     plt.scatter(X2,Y2,color="blue",
 8                 linewidth=2,label='熱播榜熱度值分布')
 9     plt.legend(loc=1)
10     x2=np.linspace(0,20,20)
11     y2=a*x2*x2+b*x2+c
12     plt.plot(x2,y2,color="red",
13              linewidth=2,label="熱播榜擬合曲線")
14     plt.legend(loc=1)
15     plt.title("熱播榜一元二次方程關系圖")
16     plt.xlabel("排名")
17     plt.ylabel("熱度")
18     plt.grid()
19     plt.show()
20 print(main2())

 

 四、全部代碼

  1 #導入庫
  2 import requests
  3 import pandas as pd
  4 import numpy as np
  5 import matplotlib.pyplot as plt
  6 import matplotlib
  7 import csv
  8 import scipy as sp
  9 import seaborn as sns
 10 from sklearn.linear_model import LinearRegression
 11 from bs4 import BeautifulSoup
 12 from pandas import DataFrame
 13 from scipy.optimize import leastsq
 14 
 15 #填入要請求的服務器地址
 16 url="https://www.iqiyi.com/ranks1/-1/0"#愛奇藝影視榜單
 17 
 18 #requests抓取網頁信息
 19 def getHTMLText(url,timeout=30):
 20     try:
 21         r=requests.get(url,timeout=30) #用requests抓取網頁信息 
 22         r.raise_for_status()           #異常捕捉  
 23         r.encoding=r.apparent_encoding
 24         return r.text
 25     except:
 26         return'產生異常'
 27     
 28 #html.parser表示用BeautifulSoup庫解析網頁
 29 html=getHTMLText(url)
 30 soup=BeautifulSoup(html,'html.parser')
 31 
 32 print(soup.prettify())
 33  #按照標准縮進格式的結構輸出
 34 r=requests.get(url)
 35 #請求網絡
 36 r.encoding=r.apparent_encoding
 37 #統一編碼
 38 html = r.text
 39 soup = BeautifulSoup(html,'lxml')
 40 #type(soup)
 41 print(soup.prettify())
 42 #基於bs4庫HTML的格式輸出,讓頁面更友好的顯示
 43 #獲取標題
 44 title1=[]
 45 for i in soup.find_all('div',
 46                        class_='rvi__tit1'):
 47     title1.append(i.get_text().strip())
 48 #獲取熱度
 49 b1=[]
 50 for i in soup.find_all('span', 
 51                        class_='rvi__index__num'):
 52     b1.append(i.get_text().strip())
 53 #整合獲取內容
 54 print('{:^50}'.format('愛奇藝熱播榜'))
 55 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '名稱', '熱度'))
 56 for i in range(25):
 57     print('{:^5}\t{:^40}\t{:^10}'.format(i+1, title1[i], b1[i]))
 58 lit1=[]
 59 for i in range(25):
 60     lit1.append([i+1, title1[i], b1[i]])
 61 df1 = pd.DataFrame(lit1,columns=['排名', '名稱', '熱度'])
 62 #愛奇藝熱播榜影視榜單
 63 url="https://www.iqiyi.com/ranks1/-1/-6"
 64 def getHTMLText(url,timeout=30):
 65     try:
 66         r=requests.get(url,timeout=30) #用requests抓取網頁信息 
 67         r.raise_for_status()           #異常捕捉  
 68         r.encoding=r.apparent_encoding
 69         return r.text
 70     except:
 71         return'產生異常'
 72 html=getHTMLText(url)
 73 soup=BeautifulSoup(html,'html.parser')
 74 print(soup.prettify())
 75 r=requests.get(url)
 76 r.encoding=r.apparent_encoding
 77 html = r.text
 78 soup = BeautifulSoup(html,'lxml')
 79 print(soup.prettify())
 80 title2=[]
 81 for i in soup.find_all('div', class_='rvi__tit1'):
 82     title2.append(i.get_text().strip())
 83 b2=[]
 84 for i in soup.find_all('span', 
 85                        class_='rvi__index__num'):
 86     b2.append(i.get_text().strip())
 87 print('{:^50}'.format('愛奇藝必看榜'))
 88 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '名稱', '熱度'))
 89 for i in range(25):
 90     print('{:^5}\t{:^40}\t{:^10}'.format(i+1, title2[i], b2[i]))
 91 lit2=[]
 92 for i in range(25):
 93     lit2.append([i+1, title2[i], b2[i]])
 94 df2 = pd.DataFrame(lit2,columns=['排名', '名稱', '熱度'])
 95 #對獲取的數據進行持久化存儲
 96 df1= pd.DataFrame(lit1,columns=['排名','名稱','熱度'])
 97 df1.to_excel('D:/python/python1.xlsx')
 98 df2= pd.DataFrame(lit2,columns=['排名','名稱','熱度'])
 99 df2.to_excel('D:/python/python2.xlsx')
100 #讀取必看榜excel文件
101 rank1=pd.DataFrame(pd.read_excel('D:/python/python1.xlsx'))
102 #讀取熱播榜excel文件
103 rank2=pd.DataFrame(pd.read_excel('D:/python/python2.xlsx'))
104 #數據清
105 #1.刪除無效列
106 rank1.drop('名稱',axis=1,inplace=True)
107 rank2.drop('名稱',axis=1,inplace=True)
108 #2.檢查是否有重復值
109 print(rank1.duplicated()) 
110 print(rank2.duplicated())
111 #3.檢查是否有空值
112 print(rank1['熱度'].isnull().value_counts())
113 print(rank2['熱度'].isnull().value_counts())
114 #4.異常值處理
115 print(rank1.describe())
116 print(rank2.describe())
117 #數據分析
118 from sklearn.linear_model import LinearRegression
119 X = df1.drop("名稱",axis=1)
120 predict_model = LinearRegression()
121 predict_model.fit(X,df1['熱度'])
122 print("回歸系數為:",predict_model.coef_)
123 X = df2.drop("名稱",axis=1)
124 predict_model = LinearRegression()
125 predict_model.fit(X,df2['熱度'])
126 print("回歸系數為:",predict_model.coef_)
127 #繪制排名與熱度的回歸圖
128 import seaborn as sns
129 plt.rcParams['font.sans-serif'] = ['SimHei']
130 plt.rcParams['axes.unicode_minus'] = False
131 sns.regplot(rank1.排名,rank1.熱度,label="熱播榜")
132 sns.regplot(rank2.排名,rank2.熱度,label="必看榜")
133 plt.legend(loc=1)
134 #畫出散點圖
135 # 用來正常顯示中文標簽
136 plt.rcParams['font.sans-serif'] = ['SimHei']  
137  # 用來正常顯示負號
138 plt.rcParams['axes.unicode_minus'] = False 
139 N=10
140 x=np.random.rand(N)
141 y=np.random.rand(N)
142 size=50
143 plt.xlabel("排名")
144 plt.ylabel("熱度")
145 plt.scatter(x,y,size,color='r',alpha=0.5,marker="o")
146 #散點圖  kind='reg'
147 sns.jointplot(x="排名",y="熱度",
148               data=rank1,kind='reg',color='g')
149 sns.jointplot(x="排名",y="熱度",
150               data=rank2,kind='reg',color='r')
151 #  kind='hex'
152 sns.jointplot(x="排名",y="熱度",
153               data=rank1,kind='hex',color='g')
154 sns.jointplot(x="排名",y="熱度",
155               data=rank2,kind='hex',color='r')
156 # kind='kde'
157 sns.jointplot(x="排名",y="熱度",
158               data=rank1,kind="kde",space=0,color='g')
159 sns.jointplot(x="排名",y="熱度",
160               data=rank2,kind="kde",space=0,color='r')
161 #選擇排名和最高熱度兩個特征變量,繪制分布圖,用最小二乘法分析兩個變量間的二次擬合方程和擬合曲線
162 colnames=[" ","排名","名稱","最高熱度"]
163 df1 = pd.read_excel('D:/python/python1.xlsx',skiprows=1,names=colnames)
164 df2 = pd.read_excel('D:/python/python2.xlsx',skiprows=1,names=colnames)
165 
166 X1 = df1.排名
167 Y1 = df1.最高熱度
168 Z1 = df1.名稱
169 
170 X2 = df2.排名
171 Y2 = df2.最高熱度
172 Z2 = df2.名稱
173 #最高熱度與排名關系圖
174 matplotlib.rcParams['font.sans-serif']=['SimHei']
175 plt.plot(X1,Y1,color="g", linewidth=2,label="熱播榜")
176 plt.plot(X2,Y2,color="r", linewidth=2,label="必看榜")
177 plt.legend(loc=1)
178 plt.xlabel("排名")
179 plt.ylabel("熱度")
180 plt.title('熱度與排名關系圖')
181 plt.show()
182 #最高熱度與排名柱狀關系圖
183 plt.bar(X2,Y2,color="r", linewidth=2,label="必看榜")
184 plt.bar(X1,Y1,color="g", linewidth=2,label="熱播榜")
185 plt.legend(loc=1)
186 plt.xlabel("排名")
187 plt.ylabel("熱度")
188 plt.title('熱度與排名柱狀關系圖')
189 plt.show()
190 #畫出散點圖
191 def A():
192     plt.scatter(X1,Y1,color="g"
193                 ,linewidth=2,label='必看榜')
194     plt.scatter(X2,Y2,color="r"
195                 ,linewidth=2,label='熱播榜')
196     plt.legend(loc=1)
197     plt.title("散點圖",color="blue")
198     plt.grid()
199     plt.xlabel("排名")
200     plt.ylabel("最高熱度")
201     plt.show()
202       
203 def func(p,x):
204     a,b,c=p
205     return a*x*x+b*x+c
206 
207 def error(p,x,y):
208     return func(p,x)-y
209 
210 print(A())
211 def main1():
212     plt.figure(figsize=(10,6))
213     p0=[0,0,0]
214     Para = leastsq(error,p0,args=(X1,Y1))
215     a,b,c=Para[0]
216     print("a=",a,"b=",b,"c=",c)
217     plt.scatter(X1,Y1,color="g",
218                 linewidth=2,label='必看榜熱度值分布')
219     plt.legend(loc=1)
220     x1=np.linspace(0,20,20)
221     y1=a*x1*x1+b*x1+c
222     plt.plot(x1,y1,color="red",
223              linewidth=2,label="必看榜擬合曲線")
224     plt.legend(loc=1)
225     plt.title("必看榜一元二次方程關系圖")
226     plt.xlabel("排名")
227     plt.ylabel("熱度")
228     plt.grid()
229     plt.show() 
230 print(main1())
231 
232 def main2():
233     plt.figure(figsize=(10,6))
234     p0=[0,0,0]
235     Para = leastsq(error,p0,args=(X2,Y2))
236     a,b,c=Para[0]
237     print("a=",a,"b=",b,"c=",c)
238     plt.scatter(X2,Y2,color="blue",
239                 linewidth=2,label='熱播榜熱度值分布')
240     plt.legend(loc=1)
241     x2=np.linspace(0,20,20)
242     y2=a*x2*x2+b*x2+c
243     plt.plot(x2,y2,color="red",
244              linewidth=2,label="熱播榜擬合曲線")
245     plt.legend(loc=1)
246     plt.title("熱播榜一元二次方程關系圖")
247     plt.xlabel("排名")
248     plt.ylabel("熱度")
249     plt.grid()
250     plt.show()
print(main2())

五、總結

1.經過對數據的分析和可視化,從回歸方程和擬合曲線可以看出散點大部分都落在曲線上,說明熱度是隨着排名的遞減而遞減的。又從散點圖可以看出熱播榜的熱度大部分停留在4-8千之間,必看榜的熱度大部分停留在9-1萬之間。必看榜的熱度明顯高於熱播榜的熱度。

 2.在這次對愛奇藝排行榜的分析的過程中,我從中學會了不少函數及用法。很多次都卡在一個點上,絞盡腦汁去想解決問題的辦法,通過觀看b站的視頻,百度搜索等方法去找尋答案。這兩個星期來也養成了耐心和獨立思考的習慣,並且提高了我對Python的興趣。

 


免責聲明!

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



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