一.主題式網絡主題式網絡爬蟲設計方案
1.爬蟲名稱:爬取愛奇藝電影熱播榜
2.爬蟲爬取的內容:爬取愛奇藝電影熱播榜數據。
3.網絡爬蟲設計方案概述:
實現思路:通過訪問網頁源代碼,使用soup.find_all正則表達爬取數據,對數據進行保存數據,再對數據進行清洗和處理,數據分析與可視化處理。
技術難點:對一些庫的使用還不太了解,爬取的內容需要分析處理。
二、主題頁面的結構特征分析
1.主題頁面的結構與特征分析:通過頁面的結構分析,可以得到各個數據之間的便簽都有關聯的關系,電影名標簽分布在p class="site-piclist_info_title"中,評分標簽分布在span class="score"中,電影描述標簽分布在p class="site-piclist_info_describe"中。
2.Htmls頁面解析
網頁url = 'http://www.iqiyi.com/dianying_new/i_list_paihangbang.html'
三、網絡爬蟲程序設計
1.數據爬取與采集
import requests from bs4 import BeautifulSoup import pandas as pd def get_html(url): headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'}#偽裝爬蟲 try: #發送get請求 html = requests.get(url,headers = headers) #配置編碼 html.encoding = html.apparent_encoding if html.status_code == 200: print("成功過獲取源代碼") except Exception as e: print("獲取源代碼失敗:%s"% e) return html.text url = 'http://www.iqiyi.com/dianying_new/i_list_paihangbang.html' html = get_html(url) #提取HTML並解析想獲取的數據 soup = BeautifulSoup(html, 'html.parser') #爬取電影名 #建立一個電影名列表Film_name Film_name = [] a = soup.find_all('a', pos = '2') for name in a: Film_name.append(name.text) #爬取評分 #建立一個評分列表Score Score = [] b = soup.find_all('span', class_ = 'score') for score in b: Score.append(score.text) #爬取電影描述 #建立一個電影描述列表Describe Describe = [] c = soup.find_all('p', class_ = 'site-piclist_info_describe') for describe in c: Describe.append(describe.text) #創建一個空列表lt lt = [] #爬取前25組電影數據,保存到列表lt中 print("{:^4}\t{:^5}\t{:^7}\t{:^8}".format('排名', '電影名', '評分', '電影描述')) for i in range(25): #輸出前25組數據 print("{:^4}\t{:^5}\t{:^7}\t{:^8}".format(i+1, Film_name[i], Score[i], Describe[i])) lt.append([i+1, Film_name[i], Score[i], Describe[i]]) #創建DateFrame df = pd.DataFrame(lt,columns = ['排名', '電影名', '評分', '電影描述']) #保存文件,數據持久化 df.to_csv('愛奇藝電影熱播榜.csv')
csv文件保存成功
2.對數據進行清洗和處理
#讀取csv文件 df = pd.DataFrame(pd.read_csv('愛奇藝電影熱播榜.csv')) df
截取前十幾組數據
#刪除無效列與行 df.drop('電影名', axis=1, inplace = True) df.drop('電影描述', axis=1, inplace = True) df.head()
#檢查是否有重復值 df.duplicated()
#缺失值處理 df[df.isnull().values==True]#返回無缺失值
#用describe()命令顯示描述性統計指標 df.describe()
3.數據分析與可視化
#數據分析與可視化 X = df.drop("電影名",axis=1) predict_model = LinearRegression() predict_model.fit(X,df['評分']) print("回歸系數為:",predict_model.coef_) #繪制排名與評分的回歸圖 matplotlib.rcParams['font.sans-serif']=['SimHei']#顯示黑體中文 sns.regplot(df.排名,df.評分)
# 繪制柱狀圖 plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號 plt.bar(df.排名, df.評分, label="排名與評分柱狀圖") plt.xlabel("排名") plt.ylabel("評分") plt.title('排名與評分柱狀圖') plt.show()
#繪制散點圖 def scatter(): plt.scatter(df.排名, df.評分, color='green', s=25, marker="o") plt.xlabel("排名") plt.ylabel("評分") plt.title("排名與評分散點圖") plt.show() scatter()
#繪制盒圖 def box_diagram(): plt.title('繪制排名與評分-箱體圖') sns.boxplot(x='排名',y='評分', data=df) box_diagram()
#繪制折線圖 def line_diagram(): x = df['排名'] y = df['評分'] plt.xlabel('排名') plt.ylabel('評分') plt.plot(x,y) plt.scatter(x,y) plt.title("排名與評分折線圖") plt.show() line_diagram()
#繪制分布圖 sns.jointplot(x="排名",y='評分',data = df) sns.jointplot(x="排名",y='評分',data = df, kind='reg') sns.jointplot(x="排名",y='評分',data = df, kind='hex') sns.jointplot(x="排名",y='評分',data = df, kind='kde', color='r') sns.kdeplot(df['排名'], df['評分'])
4.根據數據之間的關系,分析兩個變量之間的相關系數,畫出散點圖,並建立變量之間的回歸方程
#繪制一元一次回歸方程 def main(): colnames = ["排名", "電影名", "評分", "電影描述"] df = pd.read_csv('愛奇藝電影熱播榜.csv',skiprows=1,names=colnames) X = df.排名 Y = df.評分 r=sts.pearsonr(X,Y) #相關性r print('相關性r',r) def func(p, x): k, b = p return k * x + b def error_func(p, x, y): return func(p,x)-y p0 = [0,0] #使用leastsq()函數對數據進行擬合 Para = leastsq(error_func, p0, args = (X, Y)) k, b = Para[0] print("k=",k,"b=",b) plt.figure(figsize=(10,6)) plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) x=np.linspace(0,30,30) y=k*x+b plt.plot(x,y,color="red",label=u"回歸方程直線",linewidth=2) plt.title("電影排名和評分關系圖") plt.xlabel('排名') plt.ylabel('評分') plt.legend() plt.show() main()
在繪制一元一次回歸方程的基礎上,繪制一元二次回歸方程。
#繪制一元二次回歸方程 def main2(): colnames = ["排名", "電影名", "評分", "電影描述"] df = pd.read_csv('愛奇藝電影熱播榜.csv',skiprows=1,names=colnames) X = df.排名 Y = df.評分 r=sts.pearsonr(X,Y) #相關性r print('相關性r',r) def func(p, x): a, b, c = p return a * x * x + b * x + c def error_func(p, x, y): return func(p,x)-y p0 = [0,0,0] #使用leastsq()函數對數據進行擬合 Para = leastsq(error_func, p0, args = (X, Y)) a, b, c = Para[0] print("a=", a,"b=", b,"c=", c) plt.figure(figsize=(10,6)) plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) x = np.linspace(0,30,30) y = a * x * x + b * x + c plt.plot(x,y,color="red",label=u"一元二次回歸方程直線",linewidth=2) plt.title("電影排名和評分關系圖") plt.xlabel('排名') plt.ylabel('評分') plt.legend() plt.show() main2()
5.將以上各部分的代碼匯總,附上完整程序代碼
1 import requests 2 from bs4 import BeautifulSoup 3 import pandas as pd 4 import numpy as np 5 from sklearn.linear_model import LinearRegression 6 import seaborn as sns 7 import matplotlib.pyplot as plt 8 import matplotlib 9 from scipy.optimize import leastsq 10 import scipy.stats as sts 11 12 def get_html(url): 13 headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'}#偽裝爬蟲 14 15 try: 16 #發送get請求 17 html = requests.get(url,headers = headers) 18 #配置編碼 19 html.encoding = html.apparent_encoding 20 if html.status_code == 200: 21 print("成功過獲取源代碼") 22 23 except Exception as e: 24 print("獲取源代碼失敗:%s"% e) 25 26 return html.text 27 28 29 url = 'http://www.iqiyi.com/dianying_new/i_list_paihangbang.html' 30 html = get_html(url) 31 32 #提取HTML並解析想獲取的數據 33 soup = BeautifulSoup(html, 'html.parser') 34 35 #爬取電影名 36 #建立一個電影名列表Film_name 37 Film_name = [] 38 a = soup.find_all('a', pos = '2') 39 40 for name in a: 41 Film_name.append(name.text) 42 43 #爬取評分 44 #建立一個評分列表Score 45 Score = [] 46 b = soup.find_all('span', class_ = 'score') 47 48 for score in b: 49 Score.append(score.text) 50 51 #爬取電影描述 52 #建立一個電影描述列表Describe 53 Describe = [] 54 c = soup.find_all('p', class_ = 'site-piclist_info_describe') 55 56 for describe in c: 57 Describe.append(describe.text) 58 59 #創建一個空列表lt 60 lt = [] 61 62 #爬取前25組電影數據,保存到列表lt中 63 print("{:^4}\t{:^5}\t{:^7}\t{:^8}".format('排名', '電影名', '評分', '電影描述')) 64 65 for i in range(25): 66 #輸出前25組數據 67 print("{:^4}\t{:^5}\t{:^7}\t{:^8}".format(i+1, Film_name[i], Score[i], Describe[i])) 68 lt.append([i+1, Film_name[i], Score[i], Describe[i]]) 69 70 71 #創建DateFrame 72 df = pd.DataFrame(lt,columns = ['排名', '電影名', '評分', '電影描述']) 73 74 #保存文件,數據持久化 75 df.to_csv('愛奇藝電影熱播榜.csv') 76 77 #讀取csv文件 78 df = pd.DataFrame(pd.read_csv('愛奇藝電影熱播榜.csv')) 79 df 80 81 82 #刪除無效列與行 83 #df.drop('電影名', axis=1, inplace = True) 84 df.drop('電影描述', axis=1, inplace = True) 85 df.head() 86 87 88 #檢查是否有重復值 89 df.duplicated() 90 91 92 #缺失值處理 93 df[df.isnull().values==True]#返回無缺失值 94 95 96 #用describe()命令顯示描述性統計指標 97 df.describe() 98 99 100 101 102 #數據分析與可視化 103 104 X = df.drop("電影名",axis=1) 105 predict_model = LinearRegression() 106 predict_model.fit(X,df['評分']) 107 print("回歸系數為:",predict_model.coef_) 108 109 110 #繪制排名與評分的回歸圖 111 matplotlib.rcParams['font.sans-serif']=['SimHei']#顯示黑體中文 112 sns.regplot(df.排名,df.評分) 113 114 115 # 繪制柱狀圖 116 plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號 117 plt.bar(df.排名, df.評分, label="排名與評分柱狀圖") 118 plt.xlabel("排名") 119 plt.ylabel("評分") 120 plt.title('排名與評分柱狀圖') 121 plt.show() 122 123 #繪制散點圖 124 def scatter(): 125 plt.scatter(df.排名, df.評分, color='green', s=25, marker="o") 126 plt.xlabel("排名") 127 plt.ylabel("評分") 128 plt.title("排名與評分散點圖") 129 plt.show() 130 scatter() 131 132 133 #繪制盒圖 134 def box_diagram(): 135 plt.title('繪制排名與評分-箱體圖') 136 sns.boxplot(x='排名',y='評分', data=df) 137 box_diagram() 138 139 140 #繪制折線圖 141 def line_diagram(): 142 x = df['排名'] 143 y = df['評分'] 144 plt.xlabel('排名') 145 plt.ylabel('評分') 146 plt.plot(x,y) 147 plt.scatter(x,y) 148 plt.title("排名與評分折線圖") 149 plt.show() 150 line_diagram() 151 152 153 #繪制分布圖 154 sns.jointplot(x="排名",y='評分',data = df) 155 156 sns.jointplot(x="排名",y='評分',data = df, kind='reg') 157 158 sns.jointplot(x="排名",y='評分',data = df, kind='hex') 159 160 sns.jointplot(x="排名",y='評分',data = df, kind='kde', color='r') 161 162 sns.kdeplot(df['排名'], df['評分']) 163 164 165 #繪制一元一次回歸方程 166 def main(): 167 colnames = ["排名", "電影名", "評分", "電影描述"] 168 df = pd.read_csv('愛奇藝電影熱播榜.csv',skiprows=1,names=colnames) 169 170 X = df.排名 171 Y = df.評分 172 r=sts.pearsonr(X,Y) #相關性r 173 print('相關性r',r) 174 def func(p, x): 175 k, b = p 176 return k * x + b 177 178 def error_func(p, x, y): 179 return func(p,x)-y 180 181 p0 = [0,0] 182 #使用leastsq()函數對數據進行擬合 183 Para = leastsq(error_func, p0, args = (X, Y)) 184 k, b = Para[0] 185 print("k=",k,"b=",b) 186 187 plt.figure(figsize=(10,6)) 188 plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) 189 x=np.linspace(0,30,30) 190 y=k*x+b 191 plt.plot(x,y,color="red",label=u"回歸方程直線",linewidth=2) 192 193 plt.title("電影排名和評分關系圖") 194 plt.xlabel('排名') 195 plt.ylabel('評分') 196 plt.legend() 197 plt.show() 198 main() 199 200 #繪制一元二次回歸方程 201 def main2(): 202 colnames = ["排名", "電影名", "評分", "電影描述"] 203 df = pd.read_csv('愛奇藝電影熱播榜.csv',skiprows=1,names=colnames) 204 205 X = df.排名 206 Y = df.評分 207 r=sts.pearsonr(X,Y) #相關性r 208 print('相關性r',r) 209 def func(p, x): 210 a, b, c = p 211 return a * x * x + b * x + c 212 213 def error_func(p, x, y): 214 return func(p,x)-y 215 216 p0 = [0,0,0] 217 #使用leastsq()函數對數據進行擬合 218 Para = leastsq(error_func, p0, args = (X, Y)) 219 a, b, c = Para[0] 220 print("a=", a,"b=", b,"c=", c) 221 222 plt.figure(figsize=(10,6)) 223 plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) 224 225 x = np.linspace(0,30,30) 226 y = a * x * x + b * x + c 227 228 plt.plot(x,y,color="red",label=u"一元二次回歸方程直線",linewidth=2) 229 plt.title("電影排名和評分關系圖") 230 plt.xlabel('排名') 231 plt.ylabel('評分') 232 plt.legend() 233 plt.show() 234 main2()
四、結論
1.經過對主題數據的分析與可視化,得到結論:通過數據分析與可視化,了解到了電影排名與評分的關系,數據分析可以使內容更客觀的體現出來,可視化體現了數據的變化規律。
2.小結:通過此次任務的完成,我學到了許多庫的使用,這次任務同時提高了我對python的興趣,提升了我的操作能力。