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

点击跳转到总目录

前言

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

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

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

  • 设置爬虫障碍
    查看多页数据需要用户登录
    各种奇怪的验证码
    有的数据是图片格式
    5

  • 让我这个爬虫小白望而却步,后来我找到一个网站:这是个网站
    但是这个数据是非正式的,与真实数据有出入。这里只是用来作爬取和数据分析用,不代表真实情况!
    1
    2

数据采集与存储

'''
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 html

def 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_encoding
        return r.text
    except:
        print('爬取失败')

# 待爬取内容
name = []
year = []
Box_office = []

# 循环爬取每页内容
for k in range(10):
    movie_year = 2010+k
    url = 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')

3

数据清洗和简单分析

引入库,导入数据

# 数据分析并展示
# 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年top10

年度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()

2010
2011
2012
2013
2014
2015
2016
2017
2018
2019

每年电影数

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

每年电影数

每年总票房

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

每年总票房

结论

二八原则

# 二八原则
# 二八原则大概指的是,前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%!
  • 这几个图片都差不多一样,这里只放近两年的

2019
2018

end

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

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值