一.主題式網絡爬蟲設計方案
1.主題式網絡爬蟲名稱:愛奇藝電影網站排行榜數據分析
2.主題式網絡爬蟲爬取的內容:愛奇藝電影排行榜排名、評分等
3.設計方案概述:
實現思路:爬取網站內容,之后分析提取需要的數據,進行數據清洗,之后數據可視化,並計算評分和排名的相關系數
技術難點:網頁結構復雜,需要提取的數據特征會略有變化
二、主題頁面的結構特征分析
1.主題頁面的結構與特征分析:打開開發者工具,通過逐個查找找到需要數據的所在位置,發現所需要的數據都在<ul class="site-piclist" data-widget-videolist="videolist" >下的<li
2.
獲取url
三、網絡爬蟲程序設計
1.數據爬取與采集
import bs4 import requests import pandas as pd from bs4 import BeautifulSoup # 創建空詞典 result = {"rank": [], # 標題 "title": [], # 主題 "score": [], # 價格 "url": [] # 地址 } def datas() :#封裝爬取數據函數,以便后續使用 url = 'https://www.iqiyi.com/dianying_new/i_list_paihangbang.html' #按照獲取的URL進行入參 res = requests.get(url) #獲取網頁內容 # print(res.status_code) #檢查連接狀態 bs = bs4.BeautifulSoup(res.text, 'html.parser') #用BS解釋網頁 datas = bs.find('ul',class_="site-piclist").find_all('li') for data in datas : mov_name = data.find('img')['title'] # 獲取電影名字 try : mov_rank = data.find('span',class_='dypd_piclist_nub dypd_piclist_nubHot').text #獲取電影排名,由於前三特征與后面的不同,因此采用試錯歷遍相關特征 except : mov_rank = data.find('span',class_='dypd_piclist_nub').text #同上 mov_score = data.find('span',class_='score').text #獲取電影評分數據 url = data.find('a',class_='site-piclist_pic_link')['href'] result["rank"].append(mov_rank) # 排名 result["title"].append(mov_name) # 名字 result["score"].append(mov_score) # 評分 result["url"].append(url) # 評分 datas() # 將news_detail 中的每一條數據存到df中去 df = pd.DataFrame(result) # 將df的內容存到根目錄下的“news.xlsx”文件中 df.to_csv('aiqiyi.csv',encoding='utf_8_sig')
2.對數據進行清洗和處理
data_dict= datas() #提取前述數據進行處理 rate1=list(data_dict.keys()) rate2=list(data_dict.values()) d={' 排名 ':rate1, ' 評分 ':rate2} df=pd.DataFrame(d) #將評分和排名結合一起 print(df) #輸出結果
4.數據分析與可視化:
(1)折線圖
import matplotlib.pyplot as plt import pandas as pd x=rate1 #設置x軸 y=rate2 plt.figure(figsize=(200,8),dpi=80) #設置繪制的圖像和字體大小 plt.plot(x,rate2,color = 'y',label="score")#k是黃色 plt.xlabel("rank")#橫坐標名字 plt.ylabel("score")#縱坐標名字 x_major_locator=MultipleLocator(10) #把x軸的刻度間隔設置為10,並存在變量里 ax=plt.gca() #ax為兩條坐標軸的實例 ax.xaxis.set_major_locator(x_major_locator) #把x軸的主刻度設置為10的倍數 plt.xlim(1,146) #把x軸的刻度范圍設置為1到146,十倍間隔 plt.legend(loc = "best")#圖例 plt.show()
(2)條形圖
#解決中文顯示問題 plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默認字體 plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題 # 讀取excel數據 data = pd.read_csv("aiqiyi.csv",usecols = [1,3]) # 轉化列表 df_li = data.values.tolist() # 轉化列表 all_lists = [] for s_li in df_li: all_lists.append(s_li[1]) # 橫軸標簽 keys = ["5.1-6","6.1-7","7.1-8","8.1-9"] # 創建空詞典 results = {} for key in keys: results.update({key:[]}) # 將數據存儲到詞典 for i in all_lists: if int(i) >= 5.1 and int(i) <= 6: results[keys[0]].append(i) elif int(i) >= 6.1 and int(i) <= 7: results[keys[1]].append(i) elif int(i) >= 7.1 and int(i) <= 8: results[keys[2]].append(i) elif int(i) >= 8.1 and int(i) <= 9: results[keys[3]].append(i) print(results) # 統計面積的個數 for result in results: results[result] = len(results[result]) # 標題 plt.title('愛奇藝評分統計圖') #構建數據 GDP=results.values() print(GDP) #繪圖 plt.bar(range(len(GDP)),GDP, align='center',color='blue',alpha=0.8) #添加軸標簽 plt.ylabel('評論數') #添加刻度標簽 plt.xticks(range(len(GDP)),results.keys()) # 橫軸標簽旋轉90度 plt.xticks(rotation = 90) #為每一個圖形加數值標簽 for x,y in enumerate(GDP): plt.text(x,y+1,y,ha='center') # 保存圖像 plt.savefig('Bar_Graph.png') #顯示圖形 plt.show()
(3)餅狀圖
# 讀取excel數據 data = pd.read_csv("aiqiyi.csv",usecols = [1,3]) # 轉化列表 df_li = data.values.tolist() # 轉化列表 all_lists = [] for s_li in df_li: all_lists.append(s_li[1]) # 橫軸標簽 keys = ["5.1-6","6.1-7","7.1-8","8.1-9"] # 創建空詞典 results = {} for key in keys: results.update({key:[]}) a=0 b=0 c=0 d=0 # 將數據存儲到詞典 for i in all_lists: if int(i) >= 5.1 and int(i) <= 6: a = a + 1 elif int(i) >= 6.1 and int(i) <= 7: b = b + 1 elif int(i) >= 7.1 and int(i) <= 8: c = c + 1 elif int(i) >= 8.1 and int(i) <= 9: d = d + 1 results[keys[0]].append(a) results[keys[1]].append(b) results[keys[2]].append(c) results[keys[3]].append(d) # 餅狀圖標題 plt.title('愛奇藝排行榜餅狀圖') # 餅狀圖顏色 colors = ['red','yellowgreen','blue','lightskyblue','tomato','cornflowerblue'] # 餅狀圖 plt.pie(results.values(),autopct='%1.1f%%',labels=results.keys(),colors=colors) # 餅狀圖右側標簽 plt.legend(loc='upper right') # 餅狀圖 plt.axis('equal') plt.savefig("Pie_chart.png",right=0.7) plt.show()
(4)散點圖
# 讀取excel數據 data = pd.read_csv("aiqiyi.csv",usecols = [1,3]) # 轉化成列表 df_li = data.values.tolist() rate1 = [] for s_li in df_li: rate1.append(s_li[0]) rate2 = [] for s_li in df_li: rate2.append(s_li[1]) xValue = rate1 yValue = rate2 plt.title(u'愛奇藝排行榜散點圖') plt.xlabel('名次') plt.ylabel('評分') plt.legend() plt.scatter(xValue, yValue, s=20, c="#ff1212", marker='o') plt.show() plt.savefig("Scatter.png",right=0.7)
6.數據持久化
import csv if __name__ == "__main__": with open("aiqiyi.csv",'r',encoding='UTF-8') as csvFile: reader = csv.reader(csvFile) print(type(reader)) for i in reader: print(i,type(i))
7.代碼匯總
import bs4 import requests import pandas as pd from bs4 import BeautifulSoup # 創建空詞典 result = {"rank": [], # 標題 "title": [], # 主題 "score": [], # 價格 "url": [] # 地址 } def datas() :#封裝爬取數據函數,以便后續使用 url = 'https://www.iqiyi.com/dianying_new/i_list_paihangbang.html' #按照獲取的URL進行入參 res = requests.get(url) #獲取網頁內容 # print(res.status_code) #檢查連接狀態 bs = bs4.BeautifulSoup(res.text, 'html.parser') #用BS解釋網頁 datas = bs.find('ul',class_="site-piclist").find_all('li') for data in datas : mov_name = data.find('img')['title'] # 獲取電影名字 try : mov_rank = data.find('span',class_='dypd_piclist_nub dypd_piclist_nubHot').text #獲取電影排名,由於前三特征與后面的不同,因此采用試錯歷遍相關特征 except : mov_rank = data.find('span',class_='dypd_piclist_nub').text #同上 mov_score = data.find('span',class_='score').text #獲取電影評分數據 url = data.find('a',class_='site-piclist_pic_link')['href'] result["rank"].append(mov_rank) # 排名 result["title"].append(mov_name) # 名字 result["score"].append(mov_score) # 評分 result["url"].append(url) # 評分 datas() # 將news_detail 中的每一條數據存到df中去 df = pd.DataFrame(result) # 將df的內容存到根目錄下的“news.xlsx”文件中 df.to_csv('aiqiyi.csv',encoding='utf_8_sig') data_dict= datas() #提取前述數據進行處理 rate1=list(data_dict.keys()) rate2=list(data_dict.values()) d={' 排名 ':rate1, ' 評分 ':rate2} df=pd.DataFrame(d) #將評分和排名結合一起 print(df) #輸出結果 x=rate1 #設置x軸 y=rate2 plt.figure(figsize=(20,8),dpi=80) #設置繪制的圖像和字體大小 plt.plot(x,rate2,color = 'y',label="score")#k是黃色 plt.xlabel("rank")#橫坐標名字 plt.ylabel("score")#縱坐標名字 x_major_locator=MultipleLocator(10) #把x軸的刻度間隔設置為10,並存在變量里 ax=plt.gca() #ax為兩條坐標軸的實例 ax.xaxis.set_major_locator(x_major_locator) #把x軸的主刻度設置為10的倍數 plt.xlim(1,146) #把x軸的刻度范圍設置為1到146,十倍間隔 plt.legend(loc = "best")#圖例 plt.show() #解決中文顯示問題 plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默認字體 plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題 # 讀取excel數據 data = pd.read_csv("aiqiyi.csv",usecols = [1,3]) # 轉化列表 df_li = data.values.tolist() # 轉化列表 all_lists = [] for s_li in df_li: all_lists.append(s_li[1]) # 橫軸標簽 keys = ["5.1-6","6.1-7","7.1-8","8.1-9"] # 創建空詞典 results = {} for key in keys: results.update({key:[]}) # 將數據存儲到詞典 for i in all_lists: if int(i) >= 5.1 and int(i) <= 6: results[keys[0]].append(i) elif int(i) >= 6.1 and int(i) <= 7: results[keys[1]].append(i) elif int(i) >= 7.1 and int(i) <= 8: results[keys[2]].append(i) elif int(i) >= 8.1 and int(i) <= 9: results[keys[3]].append(i) print(results) # 統計面積的個數 for result in results: results[result] = len(results[result])
# 標題 plt.title('愛奇藝評分統計圖') #構建數據 GDP=results.values() print(GDP) #繪圖 plt.bar(range(len(GDP)),GDP, align='center',color='blue',alpha=0.8) #添加軸標簽 plt.ylabel('評論數') #添加刻度標簽 plt.xticks(range(len(GDP)),results.keys()) # 橫軸標簽旋轉90度 plt.xticks(rotation = 90) #為每一個圖形加數值標簽 for x,y in enumerate(GDP): plt.text(x,y+1,y,ha='center') # 保存圖像 plt.savefig('Bar_Graph.png') #顯示圖形 plt.show() # 讀取excel數據 data = pd.read_csv("aiqiyi.csv",usecols = [1,3]) # 轉化列表 df_li = data.values.tolist() # 轉化列表 all_lists = [] for s_li in df_li: all_lists.append(s_li[1]) # 橫軸標簽 keys = ["5.1-6","6.1-7","7.1-8","8.1-9"] # 創建空詞典 results = {} for key in keys: results.update({key:[]}) a=0 b=0 c=0 d=0 # 將數據存儲到詞典 for i in all_lists: if int(i) >= 5.1 and int(i) <= 6: a = a + 1 elif int(i) >= 6.1 and int(i) <= 7: b = b + 1 elif int(i) >= 7.1 and int(i) <= 8: c = c + 1 elif int(i) >= 8.1 and int(i) <= 9: d = d + 1 results[keys[0]].append(a) results[keys[1]].append(b) results[keys[2]].append(c) results[keys[3]].append(d) # 餅狀圖標題 plt.title('愛奇藝排行榜餅狀圖') # 餅狀圖顏色 colors = ['red','yellowgreen','blue','lightskyblue','tomato','cornflowerblue'] # 餅狀圖 plt.pie(results.values(),autopct='%1.1f%%',labels=results.keys(),colors=colors) # 餅狀圖右側標簽 plt.legend(loc='upper right') # 餅狀圖 plt.axis('equal') plt.savefig("Pie_chart.png",right=0.7) plt.show() import csv if __name__ == "__main__": with open("aiqiyi.csv",'r',encoding='UTF-8') as csvFile: reader = csv.reader(csvFile) print(type(reader)) for i in reader: print(i,type(i))
四、結論
1.經過對主題數據的分析與可視化,可以更明顯的觀察到排名與評分的聯系:並不是評分高排名就高,前幾並不代表就是好電影
2.小結:在發現與他人選取了類似的主題后,通過網站自學和請教有經驗的朋友采取與他人不一樣的做法完成,由於爬取影片數量過多,導致圖片輸出不太完美,編寫代碼時常出錯,只有不斷修改與實踐才能成功,雖然學習麻煩了點,不過相比收獲更多