一、主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱:豆瓣電影數據評分
2.主題式網絡爬蟲爬取的內容:豆瓣電影的榜單數字、名稱、評星、評分、評論數量。
3.設計方案概述:
實現思路:使用requests爬取網頁,然后實現數據解析,借助pandas將數據寫出到Excel;把數據進行清洗處理;然后對清洗的數據進行分析,進行相關的可視化;最后,將這些代碼進行整理。
技術難點:網頁內容繁雜,剛開始接觸,不太好懂;對數據的解析有些漫長;可視化中,數據不匹配。
二、主題頁面的結構特征分析
1.打開開發者工具,查找我所需的內容,以及它所在的標簽;在 div class="item" 中查找。
2.進行頁面解析
3分析節點
三、網絡爬蟲程序設計
1.數據爬取與采集
#獲取頁面 import requests from bs4 import BeautifulSoup import pandas as pd # 構造分頁數字列表 page_indexs = range(0, 250, 25) list(page_indexs) def download_all_htmls(): """ 下載所有列表頁面的HTML,用於后續的分析 """ htmls = [] for idx in page_indexs: url = f"https://movie.douban.com/top250?start={idx}&filter=" print("craw html:", url) r = requests.get(url, headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"}) if r.status_code != 200: raise Exception("error") htmls.append(r.text) return htmls htmls = download_all_htmls() htmls[0] def parse_single_html(html): """ 解析單個HTML,得到數據 @return list({"link", "title", [label]}) """ soup = BeautifulSoup(html, 'html.parser') article_items = ( soup.find("div", class_="article") .find("ol", class_="grid_view") .find_all("div", class_="item") ) datas = [] for article_item in article_items: rank = article_item.find("div", class_="pic").find("em").get_text() info = article_item.find("div", class_="info") title = info.find("div", class_="hd").find("span", class_="title").get_text() stars = ( info.find("div", class_="bd") .find("div", class_="star") .find_all("span") ) rating_star = stars[0]["class"][0] rating_num = stars[1].get_text() comments = stars[3].get_text() datas.append({ "rank":rank, "title":title, "rating_star":rating_star.replace("rating","").replace("-t",""), "rating_num":rating_num, "comments":comments.replace("人評價", "") }) return datas import pprint pprint.pprint(parse_single_html(htmls[0])) # 執行所有的HTML頁面的解析 all_datas = [] for html in htmls: all_datas.extend(parse_single_html(html)) all_datas len(all_datas) df = pd.DataFrame(all_datas) df.to_excel("豆瓣電影TOP250.xlsx")
#保存成功
2.對數據進行清洗和處理
#數據讀取
df= pd.read_excel('D:\python\\豆瓣電影TOP250.xlsx',encoding='gbk')
print(df.head(10))
#刪除無效行列
df.drop('Unnamed: 0',axis=1,inplace=True)
print(df.head(10))
#重復值處理
print(df.duplicated())
#異常值處理
print(df.describe())
4.數據分析與可視化
#導入各庫 import numpy as np import pandas as pd import matplotlib.pyplot as plt import sklearn import seaborn as sns from sklearn.linear_model import LinearRegression from mpl_toolkits.mplot3d import Axes3D
(1)
#繪制垂直柱狀圖 x = df.title[:6] y = df.comments[:6]#由於數據太多,只列了前幾個 plt.bar(x,y,color="b") plt.xlabel("title") plt.ylabel("comments") plt.title('影片與評價人數柱狀圖') plt.show()
(2)
#散點圖 x = df.rating_num y = df.comments plt.scatter(x,y,color="g",label="散點") plt.xlabel("rating_num") plt.ylabel("comments") plt.title('評分與評價人數散點圖') plt.show()
(3)
#繪制3D散點圖 fig=plt.figure() ax=Axes3D(fig) x=df.rating_num y=df.rating_star z=df.comments ax.scatter(x,y,z) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z')
plt.show() #由於評價人數過多,所以數據比較貼近
(4)
#繪制折線圖 x = df.title[:6] y = df.comments[:6] #探究前幾影片評價人數的關系 plt.scatter(x,y) plt.xlabel("title") plt.ylabel("comments") plt.plot(x,y,'y-*') plt.title('影片與評價人數折線圖') plt.show()
(5)
#繪制盒圖 x = df.rating_num y = df.comments sns.boxplot(x='rating_num',y='comments',data=df)
(6)
#繪制直方圖
sns.distplot(df['rating_num'])
(7)
#繪制單變量小提琴圖 sns.violinplot(df['rating_num'])
(8)
#繪制熱力圖 data=df.pivot('comments','rating_num','rating_star') sns.heatmap(data)
5.根據數據之間的關系,分析兩個變量之間的相關系數,畫出散點圖,並建立變量之間的回歸方程
df= pd.read_excel('D:\python\\豆瓣電影TOP250.xlsx',encoding='gbk') df.drop('title',axis=1,inplace=True) #由於title里的文字無法進行數據分析,所以進行刪除 X=df.drop("rating_num",axis=1) predict_model=LinearRegression() predict_model.fit(X,df['rating_num'])#訓練模型 print("回歸系數為:",predict_model.coef_)#判斷相關性 #呈現回歸圖 sns.regplot(df.comments ,df.rating_num)
7.將以上各部分的代碼匯總,附上完整程序代碼
import requests from bs4 import BeautifulSoup import pandas as pd # 構造分頁數字列表 page_indexs = range(0, 250, 25) list(page_indexs) def download_all_htmls(): """ 下載所有列表頁面的HTML,用於后續的分析 """ htmls = [] for idx in page_indexs: url = f"https://movie.douban.com/top250?start={idx}&filter=" print("craw html:", url) r = requests.get(url, headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"}) if r.status_code != 200: raise Exception("error") htmls.append(r.text) return htmls htmls = download_all_htmls() htmls[0] def parse_single_html(html): """ 解析單個HTML,得到數據 @return list({"link", "title", [label]}) """ soup = BeautifulSoup(html, 'html.parser') article_items = ( soup.find("div", class_="article") .find("ol", class_="grid_view") .find_all("div", class_="item") ) datas = [] for article_item in article_items: rank = article_item.find("div", class_="pic").find("em").get_text() info = article_item.find("div", class_="info") title = info.find("div", class_="hd").find("span", class_="title").get_text() stars = ( info.find("div", class_="bd") .find("div", class_="star") .find_all("span") ) rating_star = stars[0]["class"][0] rating_num = stars[1].get_text() comments = stars[3].get_text() datas.append({ "rank":rank, "title":title, "rating_star":rating_star.replace("rating","").replace("-t",""), "rating_num":rating_num, "comments":comments.replace("人評價", "") }) return datas import pprint pprint.pprint(parse_single_html(htmls[0])) # 執行所有的HTML頁面的解析 all_datas = [] for html in htmls: all_datas.extend(parse_single_html(html)) all_datas len(all_datas) df = pd.DataFrame(all_datas) df.to_excel("豆瓣電影TOP250.xlsx") #數據清洗 import pandas as pd
df= pd.read_excel('D:\python\\豆瓣電影TOP250.xlsx',encoding='gbk') print(df.head(10))
#刪除無效行列
df.drop('Unnamed: 0',axis=1,inplace=True) print(df.head(10))
#重復值處理
print(df.duplicated())
#異常值處理
print(df.describe()) #數據分析與可視化
#導入所需的庫 import numpy as np import pandas as pd import matplotlib.pyplot as plt import sklearn import seaborn as sns from sklearn.linear_model import LinearRegression #繪制垂直柱狀圖 x = df.title[:6] y = df.comments[:6]#由於數據太多,只列了前幾個 plt.bar(x,y,color="b") plt.xlabel("title") plt.ylabel("comments") plt.title('影片與評價人數柱狀圖') plt.show() #散點圖 x = df.rating_num y = df.comments plt.scatter(x,y,color="g",label="散點") plt.xlabel("rating_num") plt.ylabel("comments") plt.title('評分與評價人數散點圖') plt.show() #繪制3D散點圖 fig=plt.figure() ax=Axes3D(fig) x=df.rating_num y=df.rating_star z=df.comments ax.scatter(x,y,z) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') #由於評價人數過多,所以數據比較貼近 plt.show() #繪制折線圖 x = df.title[:6] y = df.comments[:6] #探究前幾影片評價人數的關系 plt.scatter(x,y) plt.xlabel("title") plt.ylabel("comments") plt.plot(x,y,'y-*') plt.title('影片與評價人數折線圖') plt.show() #繪制盒圖 x = df.rating_num y = df.comments sns.boxplot(x='rating_num',y='comments',data=df) #繪制直方圖 sns.distplot(df['rating_num']) #繪制單變量小提琴圖 sns.violinplot(df['rating_num']) #繪制熱力圖 data=df.pivot('comments','rating_num','rating_star') sns.heatmap(data) df= pd.read_excel('D:\python\\豆瓣電影TOP250.xlsx',encoding='gbk') df.drop('title',axis=1,inplace=True) #由於title里的文字無法進行數據分析,所以進行刪除 X=df.drop("rating_num",axis=1) predict_model=LinearRegression() predict_model.fit(X,df['rating_num'])#訓練模型 print("回歸系數為:",predict_model.coef_)#判斷相關性 #呈現回歸圖 sns.regplot(df.comments ,df.rating_num)
四、結論
1.結論:經過這次的作業,我知曉了電影行業評價好的,基本熱議度高,但也有一些不一定。我學習到了,每次輸出結果報錯,可以上網搜一下它錯的原因,這樣就會對自己的代碼錯誤有了更清晰的認識。不要怕有錯誤,及時修改就好。
2.小結:對於這次的作業,作為一個純純的新手來說,真的不容易。我也花了不少時間去研究它,慢慢的學習,發現python也挺不簡單的。不過,我也收獲不少,希望以后的學習中可以有所進步。