一.主題式網絡主題式網絡爬蟲設計方案
1.爬蟲名稱:爬取豆瓣電影 Top 250 數據
2.爬取內容:爬取電影排名,評分,介紹
3.網絡爬蟲設計方案概述:
思路:通過分析網頁源代碼,找出數據所在的標簽,通過爬蟲讀取數據保存到csv文件中,讀取文件,對數據進行清洗和處理,數據分析與可視化處理。
技術難點:數據量過少,所掌握的知識不夠使用。
二.主題頁面的結構特征分析
1.主題頁面的結構和特征分析:爬取數據都分布在標簽'<ol class="grid_view">'里面,電影名標簽為'span.title',評分標簽為'span.rating_num',介紹標簽為'span.inq'。
2.Htmls頁面解析:
三、網絡爬蟲程序設計
1.數據的爬取與采集:
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'}#偽裝爬蟲 resp = requests.get(url, headers = headers) return resp.text url = 'https://movie.douban.com/top250' html = get_html(url) soup = BeautifulSoup(html, 'html.parser') a = soup.find_all('div', class_='hd') #電影名 film_name = [] for i in a: film_name.append(i.a.span.text) #評分 rating_score = soup.find_all('span', class_='rating_num') #介紹 introduce = soup.find_all('span', class_='inq') lt = [] num = 20 for i in range(num): lt.append([i+1,film_name[i], rating_score[i].string, introduce[i].string]) df = pd.DataFrame(lt,columns = ['排名', '電影名', '評分', '介紹']) print(df) df.to_csv('豆瓣電影數據.csv') #保存文件,數據持久化
2.對數據進行清洗和處理:
#讀取csv文件 df = pd.DataFrame(pd.read_csv('豆瓣電影數據.csv')) df.head()
#刪除無效列與行 df.drop('電影名', axis=1, inplace = True) df.drop('介紹', axis=1, inplace = True) df.head()
#檢查是否有重復值 df.duplicated()
#空值處理 df.isnull().sum()#返回0,表示沒有空值
#缺失值處理 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_)
#繪制排名與熱度的回歸圖 plt.rcParams['font.sans-serif']=['STSong']#顯示中文 sns.regplot(df.排名,df.評分)
# 繪制垂直柱狀圖 plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號 plt.bar(df.排名, df.評分, label="排名與評分柱狀圖") plt.show()
# 繪制散點圖 def Scatter_point(): plt.scatter(df.排名, df.評分, color='red', s=25, marker="o") plt.xlabel("排名") plt.ylabel("評分") plt.title("排名與評分-散點圖") plt.show() Scatter_point()
#繪制排名與熱度折線圖 def draw(): x = df['排名'] y = df['評分'] plt.xlabel('排名') plt.ylabel('評分') plt.plot(x,y) plt.scatter(x,y) plt.title("繪制排名與評分折線圖") plt.show() draw()
#繪制排名與評分-箱體圖(盒圖) def draw1(): plt.figure(figsize=(10, 6)) plt.title('繪制排名與評分-箱體圖') sns.boxplot(x='排名',y='評分', data=df) draw1()
#繪制部分分布圖 sns.jointplot(x="排名",y='評分',data = df, kind='kde', color='r') sns.jointplot(x="排名",y='評分',data = df) sns.jointplot(x="排名",y='評分',data = df, kind='reg') sns.jointplot(x="排名",y='評分',data = df, kind='hex')
4.根據數據之間的關系,分析兩個變量之間的相關系數,畫出散點圖,並建立變量之間的回歸方程(一元或多元)
#繪制一元一次回歸方程 def main(): colnames = ["排名", "電影名", "評分", "介紹"] df = pd.read_csv('豆瓣電影數據.csv',skiprows=1,names=colnames) X = df.排名 Y = df.評分 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] 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,20) 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 one(): colnames = ["排名", "電影名", "評分", "介紹"] df = pd.read_csv('豆瓣電影數據.csv',skiprows=1,names=colnames) X = df.排名 Y = df.評分 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] Para=leastsq(error_func,p0,args=(X,Y)) a,b,c=Para[0] plt.figure(figsize=(10,6)) plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) x=np.linspace(0,30,20) y=a*x*x+b*x+c plt.plot(x,y,color="red",label=u"擬合直線",linewidth=2) plt.title("電影排名和評分一元二次回歸方程關系圖") plt.legend() plt.show() one()
5.將以上各部分的代碼匯總,附上完整程序代碼:
1 import requests 2 from bs4 import BeautifulSoup 3 import pandas as pd 4 from sklearn.linear_model import LinearRegression 5 import seaborn as sns 6 import numpy as np 7 import matplotlib.pyplot as plt 8 import matplotlib 9 from scipy.optimize import leastsq 10 11 def get_html(url): 12 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'}#偽裝爬蟲 13 resp = requests.get(url, headers = headers) 14 return resp.text 15 16 url = 'https://movie.douban.com/top250' 17 html = get_html(url) 18 soup = BeautifulSoup(html, 'html.parser') 19 20 21 a = soup.find_all('div', class_='hd') 22 #電影名 23 film_name = [] 24 for i in a: 25 film_name.append(i.a.span.text) 26 27 #評分 28 rating_score = soup.find_all('span', class_='rating_num') 29 30 #介紹 31 introduce = soup.find_all('span', class_='inq') 32 33 lt = [] 34 num = 20 35 for i in range(num): 36 lt.append([i+1,film_name[i], rating_score[i].string, introduce[i].string]) 37 df = pd.DataFrame(lt,columns = ['排名', '電影名', '評分', '介紹']) 38 df.to_csv('豆瓣電影數據.csv') #保存文件,數據持久化 39 40 #讀取csv文件 41 df = pd.DataFrame(pd.read_csv('豆瓣電影數據.csv')) 42 #print(df) 43 df.head() 44 45 46 #刪除無效列與行 47 48 df.drop('介紹', axis=1, inplace = True) 49 df.head() 50 51 #檢查是否有重復值 52 df.duplicated() 53 54 #空值處理 55 df.isnull().sum()#返回0,表示沒有空值 56 57 #缺失值處理 58 df[df.isnull().values==True]#返回無缺失值 59 60 #用describe()命令顯示描述性統計指標 61 df.describe() 62 63 #數據分析 64 X = df.drop("電影名",axis=1) 65 predict_model = LinearRegression() 66 predict_model.fit(X,df['評分']) 67 print("回歸系數為:",predict_model.coef_) 68 69 70 #繪制排名與評分的回歸圖 71 plt.rcParams['font.sans-serif']=['STSong']#顯示中文 72 sns.regplot(df.排名,df.評分) 73 74 # 繪制垂直柱狀圖 75 plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號 76 plt.bar(df.排名, df.評分, label="排名與評分柱狀圖") 77 plt.show() 78 79 # 繪制散點圖 80 def Scatter_point(): 81 82 plt.scatter(df.排名, df.評分, color='red', s=25, marker="o") 83 plt.xlabel("排名") 84 plt.ylabel("評分") 85 plt.title("排名與評分-散點圖") 86 plt.show() 87 88 Scatter_point() 89 90 #繪制排名與評分-折線圖 91 def draw(): 92 93 x = df['排名'] 94 y = df['評分'] 95 plt.xlabel('排名') 96 plt.ylabel('評分') 97 plt.plot(x,y) 98 plt.scatter(x,y) 99 plt.title("繪制排名與評分折線圖") 100 plt.show() 101 102 draw() 103 104 #繪制排名與評分-箱體圖(盒圖) 105 def draw1(): 106 107 plt.figure(figsize=(10, 6)) 108 plt.title('繪制排名與評分-箱體圖') 109 sns.boxplot(x='排名',y='評分', data=df) 110 111 draw1() 112 113 #繪制部分分布圖 114 sns.jointplot(x="排名",y='評分',data = df, kind='kde', color='r') 115 116 sns.jointplot(x="排名",y='評分',data = df) 117 118 sns.jointplot(x="排名",y='評分',data = df, kind='reg') 119 120 sns.jointplot(x="排名",y='評分',data = df, kind='hex') 121 122 123 #繪制一元一次回歸方程 124 def main(): 125 126 colnames = ["排名", "電影名", "評分", "介紹"] 127 df = pd.read_csv('豆瓣電影數據.csv',skiprows=1,names=colnames) 128 X = df.排名 129 Y = df.評分 130 131 def func(p, x): 132 k, b = p 133 return k * x + b 134 135 def error_func(p, x, y): 136 return func(p,x)-y 137 p0 = [0,0] 138 139 Para = leastsq(error_func, p0, args = (X, Y)) 140 k, b = Para[0] 141 print("k=",k,"b=",b) 142 143 plt.figure(figsize=(10,6)) 144 plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) 145 x=np.linspace(0,30,20) 146 y=k*x+b 147 plt.plot(x,y,color="red",label=u"回歸方程直線",linewidth=2) 148 149 plt.title("電影排名和評分關系圖") 150 plt.xlabel('排名') 151 plt.ylabel('評分') 152 plt.legend() 153 plt.show() 154 155 main() 156 157 158 #繪制一元二次回歸方程 159 def one(): 160 161 colnames = ["排名", "電影名", "評分", "介紹"] 162 df = pd.read_csv('豆瓣電影數據.csv',skiprows=1,names=colnames) 163 X = df.排名 164 Y = df.評分 165 166 def func(p,x): 167 a,b,c=p 168 return a*x*x+b*x+c 169 170 def error_func(p,x,y): 171 return func(p,x)-y 172 173 p0=[0,0,0] 174 Para=leastsq(error_func,p0,args=(X,Y)) 175 a,b,c=Para[0] 176 plt.figure(figsize=(10,6)) 177 plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2) 178 179 x=np.linspace(0,30,20) 180 y=a*x*x+b*x+c 181 plt.plot(x,y,color="red",label=u"擬合直線",linewidth=2) 182 plt.title("電影排名和評分一元二次回歸方程關系圖") 183 plt.legend() 184 plt.show() 185 186 one()
四、結論
1.結論:經過對主題數據的分析與可視化,突出了各數據間的關系和各數據呈現出來的分布,讓數據分析變的容易起來,解決了大部分人工計算繪圖等繁雜過程。
2.小結:通過這次做題任務,我明白了數據的分析與可視化,掌握了不少庫的使用,期間有在百度上等地方進行學習,此次任務有所收獲,加深了對python的熱愛。