近10年来中国电影票房数据爬取分析

  • 前言
  • 数据采集与存储
  • 数据清洗和简单分析
    • 引入库,导入数据
    • 近10年top
    • 年度top5
    • 每年电影数
    • 每年总票房
  • 结论
    • 二八原则
  • end

点击跳转到总目录

前言

  • 这篇文章主要讲述的是近十年(2010-2019)中国电影票房数据的爬取与简单分析。之所以想到做这个,是因为当时正做完豆瓣电影top250数据分析,让我对中国的电影市场产生了好奇,想了解一下近年来中国电影市场的发展,于是想爬取近十年的中国电影票房。

  • 我在爬取的过程中,遇到困难主要由两个方面:

  • 数据不公开
    没有一个权威、公开、透明的电影数据网站。

  • 设置爬虫障碍
    查看多页数据需要用户登录
    各种奇怪的验证码
    有的数据是图片格式
    项目三:近10年来中国电影票房数据爬取分析-编程知识网

  • 让我这个爬虫小白望而却步,后来我找到一个网站:这是个网站
    但是这个数据是非正式的,与真实数据有出入。这里只是用来作爬取和数据分析用,不代表真实情况!
    项目三:近10年来中国电影票房数据爬取分析-编程知识网
    项目三:近10年来中国电影票房数据爬取分析-编程知识网

数据采集与存储

'''
ctrl shift i
'''
# 引入库
import re
import pandas as pd
import time
import requests
from lxml.html import fromstring
from bs4 import BeautifulSoup# 下载链接
# def download(url):
#     print('Downloading:', url)
#     request = urllib.request.Request(url)
#     request.add_header('User-agent', 'Mozilla/5.0') #进行伪装
#     resp = urllib.request.urlopen(request)
#     html = resp.read().decode('utf-8')
#     return htmldef get_html(url):print('Downloading:', url)try:kv = {'user-agent':'Mozilla/5.0'}r = requests.get(url,headers = kv,timeout=30)r.raise_for_status()r.encoding=r.apparent_encodingreturn r.textexcept:print('爬取失败')# 待爬取内容
name = []
year = []
Box_office = []# 循环爬取每页内容
for k in range(10):movie_year = 2010+kurl = get_html('http://www.boxofficecn.com/boxoffice{}'.format(movie_year))time.sleep(3)   #间隔3s,防止被封禁tree = fromstring(url)soup = BeautifulSoup(url,'lxml')length_string = soup.find('div',{'class':'entry-content'}).p.get_text()length = int(re.search('[0-9]{1,3}(?=部)',length_string).group())for k in range(length):name.append(soup.find_all('tbody')[0].find_all('td')[4*k+2].get_text())year.append(movie_year)Box_office.append(soup.find_all('tbody')[0].find_all('td')[4*k+3].get_text())# 将list转化为dataframe
name_pd = pd.DataFrame(name)
year_pd = pd.DataFrame(year)
Box_office_pd = pd.DataFrame(Box_office)# 拼接
movie_Box_office_data = pd.concat([name_pd,year_pd,Box_office_pd],axis=1)
movie_Box_office_data.columns=['电影','年份','票房']movie_Box_office_data.head()# 数据预处理
## 提取数字部分
f = lambda x: re.search('[0-9]*(\.[0-9]*)?',x).group()
movie_Box_office_data['票房'] = movie_Box_office_data['票房'].apply(f)
## 缺失值填充为0
empty = movie_Box_office_data['票房'] == ''
movie_Box_office_data.loc[empty,'票房'] = 0
## 转化成浮点数
movie_Box_office_data['票房'] = movie_Box_office_data['票房'].apply(lambda x: float(x))# 输出
outputpath='E:/编程语言-青铜/python学习/25_项目/51_电影/电影票房.csv' ## 路径需要自己改!
movie_Box_office_data.to_csv(outputpath,sep=',',index=False,header=True,encoding='utf_8_sig')

项目三:近10年来中国电影票房数据爬取分析-编程知识网

数据清洗和简单分析

引入库,导入数据

# 数据分析并展示
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple
import matplotlib.pyplot as plt
import seaborn
import pandas as pd
import numpy as np
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei'] #使得图片可以显示中文
data = pd.read_csv('电影票房.csv')

近10年top

# 先看一下这十年 top10的影片,(票房的单位是万)
# data.sort_values(by='票房',ascending=False).head(10)
# print(data.sort_values(by='票房',ascending=False).head(10))
# 有一个问题就是,电影芳华的数据明显出错了,没有加小数点。更改之后如下
# 图没有出来
# 直方图
# data.iloc[2111,2]=142241.3
# df = data.sort_values(by='票房',ascending=False).head(10)
# df.plot.bar(x='电影',y='票房',title='top 10')
# plt.show()
# data.iloc[2111,2]=142241.3
# data.sort_values(by='票房',ascending=False).head(10).plot.bar(x='电影',y='票房',title='top 10')
# plt.show()

项目三:近10年来中国电影票房数据爬取分析-编程知识网

年度top5

# 年度top5*10
# data[data['年份']==2010].sort_values(by='票房',ascending=False).head(5).plot.bar(x='电影',y='票房',title='2010 top 5')
# data[data['年份']==2011].sort_values(by='票房',ascending=False).head(5).plot.bar(x='电影',y='票房',title='2011 top 5')
# data[data['年份']==2012].sort_values(by='票房',ascending=False).head(5).plot.bar(x='电影',y='票房',title='2012 top 5')
  • 类似的可以得到其他年份的top5
# for i in range(2010,2020):
#     df = data[data['年份']==i].sort_values(by='票房',ascending=False).head(5)
#     df.plot.bar(x='电影',y='票房',title='{} top 5'.format(i))
#     plt.show()

项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网

每年电影数

# 每年电影数
# 注意到2013年上映电影数明显下降。事实上是因为这份网页在统计2013年电影数据时存在缺失。
# groupby_year = data.groupby('年份').size()
# groupby_year.plot.bar(title = '每年电影数')
# plt.show()

项目三:近10年来中国电影票房数据爬取分析-编程知识网

每年总票房

# 每年总票房
# 同样地,2013年电影票房明显下降。
# data.groupby('年份')['票房'].sum().plot.bar(title = '每年总票房')
# plt.show()

项目三:近10年来中国电影票房数据爬取分析-编程知识网

结论

二八原则

# 二八原则
# 二八原则大概指的是,前20%的人,拥有了80%的资源。
# 电影票房是不是也符合二八原则呢?是不是爆款电影占据了电影市场大部分份额,
# 而绝大多数的电影却成为了不为人知的炮灰呢?事实正是如此。# 先看一下近两年的票房情况:
# data[data['年份']==2010]['票房'].plot.hist()
# plt.show()# x,y轴没打印出来
# for i in range(2010,2020):
#     data[data['年份']==i]['票房'].plot.hist(title='{} 票房情况'.format(i))
#     plt.show()percent = []
for k in range(10):Boxoffice=  data[data['年份']==(2010+k)]['票房']q80 = np.percentile(Boxoffice ,80)percent.append(Boxoffice[Boxoffice >= q80].sum()/ Boxoffice.sum())# x = Boxoffice[Boxoffice >= q80].sum() / Boxoffice.sum()# percent.append('{:.2f}'.format(x))
print(percent,'\n',type(percent))
# for i in range(len(percent)):
#     print('{:.2f}'.format(percent[i]))
#     print(type(i))# print(type(percent[i]))# print(type('{:.2f}'.format(percent[i])))# 每年票房前20%电影所占全年票房总市场的份额大于70%的,而且是逐年增加的,近四年甚至超过了90%!
  • 这几个图片都差不多一样,这里只放近两年的

项目三:近10年来中国电影票房数据爬取分析-编程知识网
项目三:近10年来中国电影票房数据爬取分析-编程知识网

end

以上便是我对这份电影票房数据进行的一次探索分析,相信其中会有很多不足之处,欢迎有缘读到此篇文章的小朋友们批评指正,如有能启发或帮助到你的地方,我将倍感荣幸。(●’◡’●)