一、主題式網絡爬蟲設計方案(15分)
1.主題式網絡爬蟲名稱
豆瓣電影TOP250數據分析
2.主題式網絡爬蟲爬取的內容與數據特征分析
分析豆瓣電影電影的相關類容
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
思路:網頁內容的選取 對所選取網頁進行html解析 ,單擊鼠標右鍵查看網頁源代碼,找到關鍵內容的索引標簽,對標簽進行分析理解,提取關鍵字眼。導入第三方庫,再將所爬取到的內容進行數據清洗.分析,繪制圖形方程,以及可視化處理。
難點:對於數據的處理有較高的技術要求
二、主題頁面的結構特征分析(15分)
1.主題頁面的結構及特征分析
打開爬取網站https://movie.douban.com 下面內容得
導演: 弗蘭克·德拉邦特 Frank Darabont 主演: 蒂姆·羅賓斯 Tim Robbins /...
1994 / 美國 / 犯罪 劇情
希望讓人自由。
-
導演: 陳凱歌 Kaige Chen 主演: 張國榮 Leslie Cheung / 張豐毅 Fengyi Zha...
1993 / 中國大陸 中國香港 / 劇情 愛情 同性風華絕代。
-
導演: 羅伯特·澤米吉斯 Robert Zemeckis 主演: 湯姆·漢克斯 Tom Hanks / ...
1994 / 美國 / 劇情 愛情一部美國近現代史。
-
導演: 呂克·貝松 Luc Besson 主演: 讓·雷諾 Jean Reno / 娜塔莉·波特曼 ...
1994 / 法國 美國 / 劇情 動作 犯罪怪蜀黍和小蘿莉不得不說的故事。
-
導演: 詹姆斯·卡梅隆 James Cameron 主演: 萊昂納多·迪卡普里奧 Leonardo...
1997 / 美國 / 劇情 愛情 災難失去的才是永恆的。
-
導演: 羅伯托·貝尼尼 Roberto Benigni 主演: 羅伯托·貝尼尼 Roberto Beni...
1997 / 意大利 / 劇情 喜劇 愛情 戰爭最美的謊言。
-
導演: 宮崎駿 Hayao Miyazaki 主演: 柊瑠美 Rumi Hîragi / 入野自由 Miy...
2001 / 日本 / 劇情 動畫 奇幻最好的宮崎駿,最好的久石讓。
-
導演: 史蒂文·斯皮爾伯格 Steven Spielberg 主演: 連姆·尼森 Liam Neeson...
1993 / 美國 / 劇情 歷史 戰爭拯救一個人,就是拯救整個世界。
-
導演: 克里斯托弗·諾蘭 Christopher Nolan 主演: 萊昂納多·迪卡普里奧 Le...
2010 / 美國 英國 / 劇情 科幻 懸疑 冒險諾蘭給了我們一場無法盜取的夢。
-
導演: 萊塞·霍爾斯道姆 Lasse Hallström 主演: 理查·基爾 Richard Ger...
2009 / 美國 英國 / 劇情永遠都不能忘記你所愛的人。
# <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有進一步的認識