概述
本期文章主要对中国票房网站(http://www.cbooo.cn)中的年度票房前25名的数据进行爬取,爬取主要内容为影片名、类型、总票房(万)、平均票价、场均人次、国家及地区和上映日期。文章结构分为2个部分:爬虫部分和数据分析部分。
爬虫部分
爬虫部分主要工作是将网站上的数据分年份爬取,并且影片名、类型、总票房(万)、平均票价、场均人次、国家及地区和上映日期,最后将所爬取到的全部内容储存在CSV文件中,方便之后的数据分析。
首先导入本次爬取需要的几个模块:
import requestsimport timeimport reimport csvfrom bs4 import BeautifulSoup
之前的爬虫推文有介绍每一个模块的具体用法,在此就不赘述,我们直接进入正题。
在进行网页爬取前,我们先设置URL固定部分和设置请求头部信息:
url='http://www.cbooo.cn/year?year='headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
接下来我们对网页列表进行循环抓取。中国票房网上最早的数据是2008年的,最新的数据是2019年的数据,所以我们将爬取的年份设为2008-2019年,并设定每次爬取时间间隔为0.5秒。
for year in range(2008,2019):if year == 2008:year=str(year)res=(url+year)r=requests.get(url=res,headers=headers)html=r.contentelse:year=str(year)res=(url+year)r=requests.get(url=res,headers=headers)html2=r.contenthtml = html + html2time.sleep(0.5)bs=BeautifulSoup(html,'html.parser')
接下来在爬取到的页面中提取影片名、类型、总票房(万)、平均票价、场均人次、国家及地区和上映日期。
result=bs.find_all('td')print(result)print(len(result))mname=[]title=""index=1year=2008for i in result:i=str(i)title=re.findall(r'</span>(.*?)</p>',i,re.I|re.M)if len(title)>0:mname.append(index)index=index+1mname.append(title[0])else:info=re.findall(r'<td>(.*?)</td>',i,re.I|re.M)mname.append(info[0])print(len(mname))print(mname)
提取数据之后,我们需要对数据进行分类,即将数据按关键词存放,我们一共提取到2400条数据,将数据分为8列存放。
k=0data=[]while k<2400:year=2008year=year+(k//200)data.append([mname[k],mname[k+1],mname[k+2],mname[k+3],mname[k+4],mname[k+5],mname[k+6],mname[k+7],year,1])k=k+8print(data)print(len(data))
由此我们可以得到300条数据,正好对应中国票房12年来的票房排名前25名电影条目数。
最后将结果储存在csv文件中。
with open('./data.csv','w') as fout:cin= csv.writer(fout,lineterminator='\n')cin.writerow(["index","name","type","zpf","mantimes","price","area","datatime","year","mark"])for item in data:cin.writerow(item)
数据分析部分
首先导入本次数据分析需要用到的模块:
import pandas as pdimport numpy as np
对我们刚刚整理好的数据进行预览:
data1 = pd.read_csv('./data.csv',encoding='gbk')
接下来我们对不同类型的电影进行平均票房统计,因为有一些缺失的数据,我们将缺失的数据补充为0。
data=data1data = data.groupby(['type','year']).zpf.mean().unstack()data.fillna(0,inplace = True)
接下来我们分析一下,不同类型的电影在不同年份的平均票房走势:
data=data1data = data.groupby(['type','year']).zpf.mean().unstack()data.fillna(0,inplace = True)#设置画布大小plt.figure(figsize=(12,6))plt.title('同一类型电影平均票房走势',fontsize=20)plt.xlabel('年份')plt.ylabel('平均票房(万)')plt.plot(data.T)
或者我们可以分析在这12年间,不同类型电影总票房的变化。
data=data1data = data.groupby(['type','year']).zpf.sum().unstack()data.fillna(0,inplace = True)#设置画布大小plt.figure(figsize=(12,6))plt.title('电影类型在十年间总票房变化',fontsize=20)plt.xlabel('年份')plt.ylabel('总票房(万)')plt.plot(data.T)data.T.plot()
分析总票房和平均票价之间的关系:
data=data1plt.figure(figsize=(12,6))plt.title('总票房和平均票价的关系',fontsize=20)plt.xlabel('平均票价')plt.ylabel('总票房(万)')plt.scatter(data.price,data.zpf,c='r')
分析总票房和场均人次之间的关系:
data=data1plt.figure(figsize=(12,6))plt.title('总票房和场均人次的关系',fontsize=20)plt.xlabel('场均人次')plt.ylabel('总票房(万)')plt.scatter(data.mantimes,data.zpf,c='b')
扫码关注数据皮皮侠
本期作者 : 卢家明
本期编辑校对:张惠宁

