爬取豆瓣電影及可視化


一、主題式網絡爬蟲設計方案

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也挺不簡單的。不過,我也收獲不少,希望以后的學習中可以有所進步。

 


免責聲明!

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



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