一、选题的背景
通过网络爬虫爬取爱奇艺网址上的热播电影榜,了解近几年因疫情影响,人们对于娱乐方式的喜爱变化。后疫情时代短视频平台成为了健康传播的热门途径。以短视频为主的视频平台用户迅猛增长,爱奇艺是国内用户数一数二的视频平台,通过对该平台上热播电影的爬取,可以从侧面反映出疫情时代人们对于娱乐主要方式的态度。
二、主题式网络爬虫设计方案
1.主题式网络爬虫名称:
通过网络爬虫技术爬取爱奇艺热播电影榜单
2.主题式网络爬虫爬取的内容与数据特征分析:
通过爬取该网站热播电影的电影名称,热度数据及排行,然后将三者通过绘图技术表现出来,以分析出人们对于电影的种类娱乐化的规律。
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
先确定爬取网站,用requests请求网站打印出html页面,之后用BeautifulSoup提取数据,将数据保存为csv文件中;之后进行pandas进行数据分析和数据可视化;难点在于怎么将数据进行加工保存下来,由于网站更新导致部分数据不一致
三、主题页面的结构特征分析
1.主题页面的结构与特征分析:
发现所有信息都被写在tbody标签下的tr中,每个tr表示一个电影名称,tr下的每个td表示一个具体信息。注意第一个tr中的信息表示格索引头,以此进行爬虫。
2.Htmls 页面解析

3.节点(标签)查找方法与遍历方法

通过对网站源代码的分析,得出我们所要分析的标题的标签为class=“tittle”排名的标签为图二所示,以及得分的排名为图一蓝色矩形框所示。接下来我们用网络爬虫对所得到的数据进行分析。
四、网络爬虫程序设计(60 分)
1 import requests 2 from bs4 import BeautifulSoup 3 import bs4 4 #引入pandas用于数据可视化 5 import pandas as pd 6 from pandas import DataFrame 7 import seaborn as sns 8 import numpy as np 9 import matplotlib.pyplot as plt 10 from scipy.optimize import leastsq 11 from sklearn.linear_model import LinearRegression 12 13 url='https://www.iqiyi.com/dianying_new/i_list_paihangbang.html' 14 headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.6241 SLBChan/30'} 15 r = requests.get(url, headers=headers,timeout=10) 16 17 def getHTMLText(url,timeout = 30): 18 try: 19 #用requests抓取网页信息 20 r = requests.get(url, timeout = 30) 21 #可以让程序产生异常时停止程序 22 r.raise_for_status() 23 #设置编码标准 24 r.encoding = r.apparent_encoding 25 return r.text 26 except: 27 return '产生异常' 28 29 30 html=r.text 31 soup=BeautifulSoup(html,'html.parser') 32 print(soup.prettify())
1 import requests 2 from bs4 import BeautifulSoup 3 import bs4 4 #引入pandas用于数据可视化 5 import pandas as pd 6 from pandas import DataFrame 7 import seaborn as sns 8 import numpy as np 9 import matplotlib.pyplot as plt 10 from scipy.optimize import leastsq 11 from sklearn.linear_model import LinearRegression
1 point=[] 2 for div in soup.find_all("div","site-title_score"): 3 point.append(div.span.strong.string) 4 puint
1 ulist=[] 2 3 for p in soup.find_all("p","site-piclist_info_title"): 4 ulist.append(p.a.string) 5 ulist
1 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '标题', '热度')) 2 num = 171 3 lst = [] 4 for i in range(num): 5 print('{:^5}\t{:^40}\t{:^20}'.format(i+1, ulist[i], point[i])) 6 lst.append([i+1,ulist[i],point[i]]) 7 df = pd.DataFrame(lst,columns=['排名','标题','评分'])
1 df
1 rank = r'rank.xlsx' 2 df.to_excel(rank)
1 df=pd.DataFrame(pd.read_excel('rank.xlsx')) 2 df
1 print(rank.duplicated())
1 #检查是否有空值 2 print(rank['评分'].isnull().value_counts())
1 print(rank.describe())
1 import seaborn as sns 2 sns.regplot(df.排名,df.评分)
1 import matplotlib.pyplot as plt 2 plt.rcParams['font.sans-serif']=['SimHei'] #显示中文 3 plt.rcParams['axes.unicode_minus']=False #显示负数 4 Type = ['9分以上', '8分~9分', '7分~8分', '6分~7分'] 5 Data = [1, 8, 8, 1] 6 plt.pie(Data ,labels=Type, autopct='%1.1f%%') 7 plt.axis('equal') 8 plt.title('各评分所占的比例') 9 plt.show() 10 plt.bar(['6分~7分','7分~8分','8分~9分','9分以上'], 11 [1, 8, 8, 1], 12 label="各评分所占比例") 13 plt.legend() 14 plt.show()
1 #选择排名和热度两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线 2 3 #正常显示中文 4 plt.rcParams['font.sans-serif']=['SimHei'] 5 #显示负数 6 plt.rcParams['axes.unicode_minus']=False 7 colnames=[" ","排名","标题","评分"] 8 9 X = df.排名 10 Y = df.评分 11 Z = df.排名 12 def A(): 13 plt.scatter(X,Y,color="r",linewidth=2) 14 plt.title("link",color="blue") 15 plt.grid() 16 plt.show() 17 def B(): 18 plt.scatter(X,Y,color="b",linewidth=2) 19 plt.title("link",color="blue") 20 plt.grid() 21 plt.show() 22 def func(p,x): 23 a,b,c=p 24 return a*x*x+b*x+c 25 def error(p,x,y): 26 return func(p,x)-y 27 def main(): 28 plt.figure(figsize=(10,6)) 29 p0=[0,0,0] 30 Para = leastsq(error,p0,args=(X,Y)) 31 a,b,c=Para[0] 32 print("a=",a,"b=",b,"c=",c) 33 plt.scatter(X,Y,color="blue",linewidth=2) 34 x=np.linspace(0,20,20) 35 y=a*x*x+b*x+c 36 plt.plot(x,y,color="black",linewidth=2,) 37 plt.title("评分值分布") 38 plt.grid() 39 plt.show() 40 print(A()) 41 print(B()) 42 print(main())
完整代码如下:
1 #导入相关库 2 import requests 3 from bs4 import BeautifulSoup 4 import bs4 5 #引入pandas用于数据可视化 6 7 import pandas as pd 8 from pandas import DataFrame 9 import seaborn as sns 10 import numpy as np 11 import matplotlib.pyplot as plt 12 from scipy.optimize import leastsq 13 from sklearn.linear_model import LinearRegression 14 15 #输入网址 16 17 url='https://www.iqiyi.com/dianying_new/i_list_paihangbang.html' 18 #防伪编码 19 20 headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.6241 SLBChan/30'} 21 22 r = requests.get(url, headers=headers,timeout=10) 23 24 def getHTMLText(url,timeout = 30): 25 try: 26 27 #用requests抓取网页信息 28 29 r = requests.get(url, timeout = 30) 30 31 #可以让程序产生异常时停止程序 32 33 r.raise_for_status() 34 35 #设置编码标准 36 37 r.encoding = r.apparent_encoding 38 return r.text 39 except: 40 return '产生异常' 41 42 html=r.text 43 soup=BeautifulSoup(html,'html.parser') 44 45 #输出更加友好 46 47 print(soup.prettify()) 48 49 point=[] 50 for div in soup.find_all("div","site-title_score"): 51 point.append(div.span.strong.string) 52 puint 53 54 55 html=r.text 56 soup=BeautifulSoup(html,'html.parser') 57 print(soup.prettify()) 58 59 ulist=[] 60 61 for p in soup.find_all("p","site-piclist_info_title"): 62 ulist.append(p.a.string) 63 ulist 64 65 66 #绘制图表 67 68 print('{:^5}\t{:^40}\t{:^10}'.format('排名', '标题', '热度')) 69 num = 171 70 lst = [] 71 for i in range(num): 72 73 print('{:^5}\t{:^40}\t{:^20}'.format(i+1, ulist[i], point[i])) 74 lst.append([i+1,ulist[i],point[i]]) 75 76 df = pd.DataFrame(lst,columns=['排名','标题','评分']) 77 78 79 #保存至excel 80 81 rank = r'rank.xlsx' 82 df.to_excel(rank) 83 84 df=pd.DataFrame(pd.read_excel('rank.xlsx')) 85 df 86 87 print(rank.duplicated()) 88 89 #检查是否有空值 90 91 print(rank['评分'].isnull().value_counts()) 92 print(rank.describe()) 93 94 #绘制饼图 95 #正常显示中文 96 97 plt.rcParams['font.sans-serif']=['SimHei'] 98 #显示负数 99 plt.rcParams['axes.unicode_minus']=False 100 import seaborn as sns 101 import pandas as pd 102 from pandas import DataFrame 103 import seaborn as sns 104 sns.regplot(df.排名,df.评分) 105 106 import matplotlib.pyplot as plt 107 108 #显示中文 109 110 plt.rcParams['font.sans-serif']=['SimHei'] 111 112 #显示负数 113 114 plt.rcParams['axes.unicode_minus']=False 115 116 Type = ['9分以上', '8分~9分', '7分~8分', '6分~7分'] 117 Data = [1, 8, 8, 1] 118 plt.pie(Data ,labels=Type, autopct='%1.1f%%') 119 plt.axis('equal') 120 plt.title('各评分所占的比例') 121 plt.show() 122 plt.bar(['6分~7分','7分~8分','8分~9分','9分以上'], 123 [1, 8, 8, 1], 124 label="各评分所占比例") 125 plt.legend() 126 plt.show() 127 128 #绘制折线图 129 130 #正常显示中文 131 132 plt.rcParams['font.sans-serif']=['SimHei'] 133 134 #显示负数 135 136 plt.rcParams['axes.unicode_minus']=False 137 a = df.排名 138 b = df.评分 139 plt.plot(a,b, color='r',label='时长') 140 plt.xlabel("排名") 141 plt.ylabel("评分") 142 plt.title('排名与评分') 143 plt.legend(loc=1) 144 plt.grid() 145 plt.show() 146 147 import pandas as pd 148 import numpy as np 149 import matplotlib.pyplot as plt 150 import pandas as pd 151 plt.rcParams['font.sans-serif'] = ['SimHei'] 152 plt.rcParams['axes.unicode_minus'] = False 153 154 plt.scatter(df["排名"],df["评分"]) 155 plt.title("排名评分的关系") 156 plt.grid() 157 plt.show() 158 159 #选择排名和热度两个特征变量,绘制分布图,用最小二乘法分析两个变量间的二次拟合方程和拟合曲线 160 161 #正常显示中文 162 163 plt.rcParams['font.sans-serif']=['SimHei'] 164 165 #显示负数 166 167 plt.rcParams['axes.unicode_minus']=False 168 colnames=[" ","排名","标题","评分"] 169 170 X = df.排名 171 Y = df.评分 172 Z = df.排名 173 def A(): 174 plt.scatter(X,Y,color="r",linewidth=2) 175 plt.title("link",color="blue") 176 plt.grid() 177 plt.show() 178 179 def B(): 180 plt.scatter(X,Y,color="b",linewidth=2) 181 plt.title("link",color="blue") 182 plt.grid() 183 plt.show() 184 185 #绘制一元二次 186 187 def func(p,x): 188 a,b,c=p 189 return a*x*x+b*x+c 190 191 def error(p,x,y): 192 return func(p,x)-y 193 194 def main(): 195 plt.figure(figsize=(10,6)) 196 p0=[0,0,0] 197 Para = leastsq(error,p0,args=(X,Y)) 198 a,b,c=Para[0] 199 print("a=",a,"b=",b,"c=",c) 200 plt.scatter(X,Y,color="blue",linewidth=2) 201 x=np.linspace(0,20,20) 202 y=a*x*x+b*x+c 203 plt.plot(x,y,color="black",linewidth=2,) 204 plt.title("评分值分布") 205 206 #绘制网格 207 208 plt.grid() 209 plt.show() 210 211 print(A()) 212 print(B()) 213 print(main())
五、总结(10 分)
1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?
可以直观的看到热播电影的评分情况,人们对于好的 质量高的电影评分给出普遍客观,对于分数较低的电影,一部分原因是因为播放量不占优势,但电影所拍的剧情质量也确实差强人意,通过自己所做的工作,达到了自己的预期目标。
2.在完成此设计过程中,得到哪些收获?以及要改进的建议?
在数据爬取中不断地学习了一些函数的使用以及绘图的方法,使用图表、图形对数据的理解和分析中更加简单清晰,简单回复了以前的一些知识点,设计过程中遇到的困难通过百度和视频学习基本可解决。