爬取豆瓣電影評分top250數據分析


一、主題式網絡爬蟲設計方案(15分)
1.主題式網絡爬蟲名稱

豆瓣電影TOP250數據分析
2.主題式網絡爬蟲爬取的內容與數據特征分析

分析豆瓣電影電影的相關類容
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)

思路:網頁內容的選取  對所選取網頁進行html解析 ,單擊鼠標右鍵查看網頁源代碼,找到關鍵內容的索引標簽,對標簽進行分析理解,提取關鍵字眼。導入第三方庫,再將所爬取到的內容進行數據清洗.分析,繪制圖形方程,以及可視化處理。

難點:對於數據的處理有較高的技術要求

二、主題頁面的結構特征分析(15分)
1.主題頁面的結構及特征分析

打開爬取網站https://movie.douban.com  下面內容得

肖申克的救贖

導演: 弗蘭克·德拉邦特 Frank Darabont   主演: 蒂姆·羅賓斯 Tim Robbins /...
1994 / 美國 / 犯罪 劇情

9.7 2149682人評價

希望讓人自由。

   

# <span property="v:itemreviewed">  肖申克的救贖 The Shawshank Redemption</span>
# <a href="/celebrity/1047973/" rel="v:directedBy">  弗蘭克·德拉邦特</a>
# <a href="/celebrity/1054521/" rel="v:starring">  蒂姆·羅賓斯</a>


2.Htmls頁面解析

三、網絡爬蟲程序設計(60分)
爬蟲程序主體要包括以下各部分,要附源代碼及較詳細注釋,並在每部分程序后面提供輸出結果的截圖。
1.數據爬取與采集(20)

復制代碼
import requests
from bs4 import BeautifulSoup
import re
import pandas
from matplotlib import pyplot as plt
import numpy as np
import scipy as sp
import pandas as pd
from matplotlib import pyplot as plt
import matplotlib
import seaborn as sns
from scipy.optimize import leastsq

headers = {
    'Host':'movie.douban.com',
    'Origin':'movie.douban.com',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
}
base_url = 'https://movie.douban.com/top250?start={}&filter='





response = requests.get('https://movie.douban.com/top250?start=0&filter=', headers = headers, allow_redirects=False)
if response.status_code == 200:
    # print(response.text)
    pass

pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">', re.S) # 去掉所有換行符,並用正則表達式去匹配每一個頁面的具體電影
urls = re.findall(pattern1, response.text)

directors = []# 導演名

names = []# 電影名稱

stars = []# 主演人物

countrys = []# 電影的拍攝地

languages = []# 電影語言種類

typs = []# 電影類型

sorces = []# 評分

# <span property="v:itemreviewed">  肖申克的救贖 The Shawshank Redemption</span>
# <a href="/celebrity/1047973/" rel="v:directedBy">  弗蘭克·德拉邦特</a>
# <a href="/celebrity/1054521/" rel="v:starring">  c蒂姆·羅賓斯</a>
def base_urls(base_url):
    urls = []

    # for i in range(0, 250, 25):
    #     true_url = base_url.format(i)
    #     print(true_url)
    for i in range(0, 50, 25):
        true_url = base_url.format(i)

        response = requests.get(true_url, headers=headers, allow_redirects=False)
        if response.status_code == 200:
            # print(response.text)

            pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">',re.S)
            # 去掉所有換行符
            url = re.findall(pattern1, response.text

            for i in url:
                urls.append(i)
    return urls

def parse_url(urls):
    
    for i in range(0, 50, 1):
        res = requests.get(urls[i], headers = headers, allow_redirects=False)
        if res.status_code == 200:
            soup = BeautifulSoup(res.text, 'lxml')
            # 爬取電影名稱
            name = soup.find('span', property="v:itemreviewed")
            names.append(name.text)            

            # 爬取導演名
            director = soup.find('a', rel="v:directedBy")
            directors.append(director.text)
           
            #爬取類型
            typ =soup.find('span', property="v:genre")[1:]
           typs.append(typ.text)
            
            # 爬取明星
            star_save = []
            for star in soup.find_all('a', rel="v:starring"):
                star_save.append(star.text)
                stars.append(star_save)


            # 爬取制片國家
            #<span class="pl">制片國家/地區:</span> 美國<br>
            country = soup.find('span', text='制片國家/地區:').next_sibling[1:]
            countrys.append(country)


            # 爬取影片語言
            # <span class="pl">語言:</span>
            language = soup.find('span', text='語言:').next_sibling[1:]
            languages.append(language)
            
            #爬取評分
            sorce = soup.find('span', class_="rating_num")
            sorces.append(sorce.text)

# print(directors)
# print(true_director)
# print(a)
if __name__ == '__main__':
    base = base_urls(base_url)
    parse_url(base)
    print(countrys)
    print(directors)
    print(languages)
    print(names)
    print(typs)
    print(sorces)
    #
    # 最后我們將數據寫入到一個excel表格里
    info ={'Filmname':names, 'Directors':directors, 'Country':countrys, 'Languages':languages, 'typs':typs, "sorce":sorces}
    pdfile = pandas.DataFrame(info)
   
    pdfile.to_excel('DoubanFilm.xlsx', sheet_name="豆瓣電影")
復制代碼

 

 


2.對數據進行清洗和處理(10)復制代碼df = pd.DataFrame(pd.read_excel('DoubanFilm.xlsx'),columns=['Numbers','Filmname','Directors','Country','Languages','typs','score'])print(df.head())

# 讀取excel文件 df.drop('Filmname', axis=1, inplace = True) df.drop('Directors', axis=1, inplace = True) df.drop('Languages', axis=1, inplace = True) print(df.head()) # 刪除無效行與列
print(df.isnull().sum()) print(df.isna().head()) # 統計缺失值 print(df.isna().head()) # 查找重復值
復制代碼

得到下面的數據



4.數據分析與可視化(例如:數據柱形圖、直方圖、散點圖、盒圖、分布圖)(15分)

復制代碼
plt.rcParams['font.sans-serif']=['STSong']
# 顯示中文
plt.rcParams['axes.unicode_minus']=False
# 用來正常顯示負號

x = df.typs
y = df['Numbers'][:50]
plt.xlabel('類型')
plt.ylabel('排名')
plt.plot()
plt.scatter(x,y)
plt.title("排名與類型比較圖")
plt.show()
#散點圖

sns.lmplot(x='score',y='Numbers',data=df)
#線性圖
復制代碼

5.根據數據之間的關系,分析兩個變量之間的相關系數,畫出散點圖,並建立變量之間的回歸方程(一元或多元)(10分)。

復制代碼
X = df.score
Y = df.Numbers  
def func(params, x):
        a, b, c = params
        return a*x*x+b*x+c
def error(params,x,y):
     return func(params,x)-y    
def main(a,b,c):
    p0 = [0,0,0]
    Para=leastsq(error,p0,args=(X,Y))
    a,b,c=Para[0]    
    print("a=",a,"b=",b,"c=",c) 
    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.grid()
    plt.show()
main()
#一元二次回歸方程
復制代碼


7.將以上各部分的代碼匯總,附上完整程序代碼

復制代碼
  1 import requests
  2 from bs4 import BeautifulSoup
  3 import re
  4 import pandas
  5 from matplotlib import pyplot as plt
  6 import numpy as np
  7 import scipy as sp
  8 import pandas as pd
  9 from matplotlib import pyplot as plt
 10 import matplotlib
 11 import seaborn as sns
 12 from scipy.optimize import leastsq
 13 
 14 headers = {
 15     'Host':'movie.douban.com',
 16     'Origin':'movie.douban.com',
 17     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36',
 18 }
 19 base_url = 'https://movie.douban.com/top250?start={}&filter='
 25 response = requests.get('https://movie.douban.com/top250?start=0&filter=', headers = headers, allow_redirects=False)
 26 if response.status_code == 200:
 27     # print(response.text)
 28     pass
 29 
 30 pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">', re.S) # 去掉所有換行符,並用正則表達式去匹配每一個頁面的具體電影
 31 urls = re.findall(pattern1, response.text)
 32 
 33 directors = [] # 導演名
 34 
 35 names = [] # 電影名稱
 36 
 37 stars = [] # 主演人物
 38 
 39 countrys = [] # 電影拍攝地

 41 languages = [] # 電影語言種類
 42 
 43 typs = [] # 電影類型
 44 
 45 sorces = [] #評分
 46 
 47 # <span property="v:itemreviewed">肖申克的救贖 The Shawshank Redemption</span>
 48 # <a href="/celebrity/1047973/" rel="v:directedBy">弗蘭克·德拉邦特</a>
 49 # <a href="/celebrity/1054521/" rel="v:starring">蒂姆·羅賓斯</a>
 50 def base_urls(base_url):
 51     urls = []
 52 
 53     # for i in range(0, 250, 25):
 54     #     true_url = base_url.format(i)
 55     #     print(true_url)
 56     for i in range(0, 50, 25):
 57         true_url = base_url.format(i)
 58 
 59         response = requests.get(true_url, headers=headers, allow_redirects=False)
 60         if response.status_code == 200:
 61             # print(response.text)
 62 
 63             pattern1 = re.compile('<div.*?class="item">.*?<div.*?class="pic">.*?<a.*?href="(.*?)">',re.S)
 64             # 去掉所有換行符,並用正則表達式去匹配每一個頁面的具體電影
 65             url = re.findall(pattern1, response.text)
 66             # 因為這里是用findall,他返回的是一個列表,如果我們直接append,會導致列表嵌套,故我們這里用個for循環提取出列表的元素再append進去
 67 
 68             for i in url:
 69                 urls.append(i)
 70     return urls
 71 
 72 def parse_url(urls):
 73     
 74     for i in range(0, 50, 1):
 75         res = requests.get(urls[i], headers = headers, allow_redirects=False)
 76         if res.status_code == 200:
 77             soup = BeautifulSoup(res.text, 'lxml')
 78             # 爬取電影名
 79             name = soup.find('span', property="v:itemreviewed")
 80             names.append(name.text)            
 81 
 82             # 爬取導演
 83             director = soup.find('a', rel="v:directedBy")
 84             directors.append(director.text)
 85            
 86             #爬取類型
 87             typ =soup.find('span', property="v:genre")[1:]
 88             typs.append(typ.text)
 89             
 90             # 爬取明星
 91             star_save = []
 92             for star in soup.find_all('a', rel="v:starring"):
 93                 star_save.append(star.text)
 94                 stars.append(star_save)
 95 
 96 
 97             # 爬取制片國家
 98             #<span class="pl">制片國家/地區:</span> 美國<br>
 99             country = soup.find('span', text='制片國家/地區:').next_sibling[1:]
100             countrys.append(country)
101 
102 
103             # 爬取影片語言
104             # <span class="pl">語言:</span>
105             language = soup.find('span', text='語言:').next_sibling[1:]
106             languages.append(language)
107             
108             #爬取評分
109             sorce = soup.find('span', class_="rating_num")
110             sorces.append(sorce.text)
111 
112 # print(directors)
113 # print(true_director)
114 # print(a)
115 if __name__ == '__main__':
116     base = base_urls(base_url)
117     parse_url(base)
118     print(countrys)
119     print(directors)
120     print(languages)
121     print(names)
122     print(typs)
123     print(sorces)
124     125     # 最后我們將數據寫入到一個excel表格里
126     info ={'Filmname':names, 'Directors':directors, 'Country':countrys, 'Languages':languages, 'typs':typs, "sorce":sorces}
127     pdfile = pandas.DataFrame(info)
128    
129     pdfile.to_excel('DoubanFilm.xlsx', sheet_name="豆瓣電影")
130 
131 #讀取excel
132 df = pd.DataFrame(pd.read_excel('DoubanFilm.xlsx'),columns=['Numbers','Filmname','Directors','Country','Languages','typs','score'])
133 print(df.head())
134 
135 # 刪除無效行與列
136 df.drop('Filmname', axis=1, inplace = True)
137 df.drop('Directors', axis=1, inplace = True)
138 df.drop('Languages', axis=1, inplace = True)
139 print(df.head())
140 
141 print(df.isnull().sum())
142 # 返回0,表示沒有空值
143 print(df.isna().head())
144 # 統計缺失值
145 print(df.isna().head())
146 # 查找重復值
147 plt.rcParams['font.sans-serif']=['STSong']
148 # 顯示中文
149 plt.rcParams['axes.unicode_minus']=False
150 # 用來正常顯示負號
151 
152 x = df.typs
153 y = df['Numbers'][:50]
154 plt.xlabel('類型')
155 plt.ylabel('排名')
156 plt.bar(x,y)
157 plt.title("排名與類型比較圖")
158 plt.show()
159 #柱狀圖
160 
161 x = df.typs
162 y = df['Numbers'][:50]
163 plt.xlabel('類型')
164 plt.ylabel('排名')
165 plt.plot()
166 plt.scatter(x,y)
167 plt.title("排名與類型比較圖")
168 plt.show()
169 #散點圖
170 
171 sns.lmplot(x='score',y='Numbers',data=df)
172 #線性圖
173 
174 X = df.score
175 Y = df.Numbers  
176 def func(params, x):
177         a, b, c = params
178         return a*x*x+b*x+c
179 def error(params,x,y):
180      return func(params,x)-y    
181 def main(a,b,c):
182     p0 = [0,0,0]
183     Para=leastsq(error,p0,args=(X,Y))
184     a,b,c=Para[0]    
185     print("a=",a,"b=",b,"c=",c) 
186     plt.scatter(X,Y,color="green",label=u"評分分布",linewidth=2)
187     x=np.linspace(0,30,20)
188     y=a*x*x+b*x+c
189     plt.plot(x,y,color="red",label=u"回歸方程直線",linewidth=2)     
190     plt.title("電影排名和評分關系圖")
191     plt.legend()
192     plt.grid()
193 plt.show() 194 main() #一元二次回歸方程
復制代碼

 

四、結論(10分)
1.經過對主題數據的分析與可視化,可以得到哪些結論?

經過對主題數據的分析與可視化可以更直觀的了解數據
2.對本次程序設計任務完成的情況做一個簡單的小結。

通過此次作業了解到了對於函數熟悉應用重要性以及

通過對代碼不斷的修改,對於python有進一步的認識


免責聲明!

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



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