一、主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱:
爬取豆瓣電影排名
2.主題式網絡爬蟲爬取的內容與數據特征分析:主要爬取 豆瓣電影評分
2.主題式網絡爬蟲爬取的內容與數據特征分析:主要爬取 豆瓣電影評分
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
實現思路為先對網頁源代碼分析,用BeautifulSoup對數據進行清洗,最后通過進行數據可視化。技術難點主要包括對數據的清洗以及可視化。
二、主題頁面的結構特征分析
1.主題頁面的結構與特征分析
1.主題頁面的結構與特征分析
我們需要找到作品的名稱,評分,評價,通過瀏覽頁面元素,定位並爬取所需內容

三、網絡爬蟲程序設計
1.數據爬取與采集
import json import requests from requests.exceptions import RequestException import re import time #判斷爬取是否錯誤 def get_one_page(url): try: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36' } response = requests.get(url, headers=headers) if response.status_code == 200: return response.text return None except RequestException: return None def parse_one_page(html): pattern = re.compile('<li>.*?<em class="">(.*?)</em>.*?title.*?>(.*?)</span>.*? <span class="rating_num" property="v:average">(.*?)</span>.*?<span class="inq">(.*?)</span>',re.S) items = re.findall(pattern, html) for item in items: yield {'排名': item[0], '名字': item[1], '評分': item[2], '簡介':item[3] } def write_to_file(content): with open('douban250.txt', 'a', encoding='utf-8') as f: f.write(json.dumps(content, ensure_ascii=False) + '\n') def main(offset): url = 'https://movie.douban.com/top250?start='+str(offset)+'&filter=' html = get_one_page(url) for item in parse_one_page(html): print(item) write_to_file(item) if __name__ == '__main__': for i in range(10): main(offset=i * 25) time.sleep(1)
截圖顯示結果
數據的采集並生成文件
import requests from bs4 import BeautifulSoup import pandas as pd page_indexs = range(0, 100, 25) # 構造分頁列表 list(page_indexs) def download_all_htmls(): # 爬取4個頁面的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)"}) # r返回一個包含服務器資源的Response對象 if r.status_code != 200: raise Exception("error") # 當程序出錯時通過raise語句顯示引發異常 htmls.append(r.text) return htmls # 執行爬取 htmls = download_all_htmls() # 爬取4個頁面的HTML def parse_single_html(html): # 解析單個HTML,得到數據 soup = BeautifulSoup(html, 'html.parser') # 解析HTML數據 article_items = ( # 對照HTML結構寫 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") # 有4個span,所以用find_all ) rating_star = stars[0]["class"][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 # 執行所有的HTML頁面的解析 all_datas = [] for html in htmls: all_datas.extend(parse_single_html(html)) df = pd.DataFrame(all_datas) df.to_csv("豆瓣電影Top100.csv") df = pd.DataFrame(pd.read_csv('douban.csv')) print(df)
對數據進行處理
#輸出信息檢驗文件是否成功 df = pd.DataFrame(pd.read_csv('douban.csv')) print(df)
截圖
# 刪除無效列 df.drop('title', axis = 1, inplace=True) df.head()
# 查找重復值 df.duplicated()
# 刪除重復值 df = df.drop_duplicates() df.head()
扇形圖 條形圖
import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']=['SimHei'] #顯示中文 plt.rcParams['axes.unicode_minus']=False Type = ['9分以上', '8分~9分', '7分~8分', '6分~7分'] Data = [1, 8, 8, 1] plt.pie(Data ,labels=Type, autopct='%1.1f%%') plt.axis('equal') plt.title('電影所占評分的比例') plt.show() plt.bar(['6分~7分','7分~8分','8分~9分','9分以上'], [1, 8, 8, 1], label="電影評分所占比例") plt.legend() plt.show()
代碼匯總
import json import requests from requests.exceptions import RequestException import re import time from bs4 import BeautifulSoup import pandas as pd #判斷爬取是否錯誤 def get_one_page(url): try: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36' } response = requests.get(url, headers=headers) if response.status_code == 200: return response.text return None except RequestException: return None def parse_one_page(html): pattern = re.compile('<li>.*?<em class="">(.*?)</em>.*?title.*?>(.*?)</span>.*? <span class="rating_num" property="v:average">(.*?)</span>.*?<span class="inq">(.*?)</span>',re.S) items = re.findall(pattern, html) for item in items: yield {'排名': item[0], '名字': item[1], '評分': item[2], '簡介':item[3] } def write_to_file(content): with open('douban250.txt', 'a', encoding='utf-8') as f: f.write(json.dumps(content, ensure_ascii=False) + '\n') def main(offset): url = 'https://movie.douban.com/top250?start='+str(offset)+'&filter=' html = get_one_page(url) for item in parse_one_page(html): print(item) write_to_file(item) if __name__ == '__main__': for i in range(10): main(offset=i * 25) time.sleep(1) page_indexs = range(0, 100, 25) # 構造分頁列表 list(page_indexs) def download_all_htmls(): # 爬取4個頁面的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)"}) # r返回一個包含服務器資源的Response對象 if r.status_code != 200: raise Exception("error") # 當程序出錯時通過raise語句顯示引發異常 htmls.append(r.text) return htmls # 執行爬取 htmls = download_all_htmls() # 爬取4個頁面的HTML def parse_single_html(html): # 解析單個HTML,得到數據 soup = BeautifulSoup(html, 'html.parser') # 解析HTML數據 article_items = ( # 對照HTML結構寫 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") # 有4個span,所以用find_all ) rating_star = stars[0]["class"][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 # 執行所有的HTML頁面的解析 all_datas = [] for html in htmls: all_datas.extend(parse_single_html(html)) df = pd.DataFrame(all_datas) df.to_csv("豆瓣電影Top100.csv") df = pd.DataFrame(pd.read_csv('douban.csv')) print(df) #輸出信息檢驗文件是否成功 df = pd.DataFrame(pd.read_csv('douban.csv')) print(df) df.drop('title', axis = 1, inplace=True) df.head() df.duplicated() df = df.drop_duplicates() df.head() import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']=['SimHei'] #顯示中文 plt.rcParams['axes.unicode_minus']=False Type = ['9分以上', '8分~9分', '7分~8分', '6分~7分'] Data = [1, 8, 8, 1] plt.pie(Data ,labels=Type, autopct='%1.1f%%') plt.axis('equal') plt.title('電影所占評分的比例') plt.show() plt.bar(['6分~7分','7分~8分','8分~9分','9分以上'], [1, 8, 8, 1], label="電影評分所占比例") plt.legend() plt.show()
總結
1.經過對主題數據的分析與可視化,可以得到哪些結論?
可以直觀的看到熱播電影的評分情況
2.對本次程序設計任務完成的情況做一個簡單的小結
在完成本次程序設計任務的過程中,鞏固了以前學習的知識,學會了以前沒有掌握的,既是對之前課程的復習與運用,也是對我們掌握的實質的考察與補充。我也對之前的課程進行了一個復習,也找到了很多自我的短板和遺漏的知識點,也在不斷的探索中學習到更多新東西,了解到其實還有很多值得我們去學習,也提高了我對Python的興趣。