python爬取近十年中国电影票房数据与分析
Python爬取近十年中国电影票房数据与分析
一、选题背景
Q:为什么选择选择此题?
随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战。
Q:达到什么预期目标?
爬取中国近10年的电影票房,并数据可视化。
Q:项目背景
“2013年受市场热捧的电影行业其实是个现金流状况很差的行业。中国每年会拍七百多部电影,只有两百多部能够上映,其中票房能够超过五亿的屈指可数。即使赚了五亿的票房“大获成功”的电影,扣除分给院线的一半,再扣除发行费,宣传费,制片方能够拿到手的大概只有2亿多一点。再扣除给编剧、导演、制片和演员的薪酬以及拍摄中的各种成本,最后剩下的净利润可能只有几千万。”
这句话让我对中国的电影市场产生了好奇,想了解一下近年来中国电影市场的发展,于是想爬取近十年的中国电影票房。
二、主题式网络爬虫设计
Q:主题是网络爬虫名称
爬取近十年中国电影票房数据
Q:主题式网络爬虫的内容
爬取中国近10年的电影票房,并实现数据可视化。
Q:设计方案描述
使用 beautifulsoup 里面的 find_all 函数来进行定位,其他 xpath 等方法,都不大行得通。爬取的票房数据要进行预处理,因为票房数据中可能含有中文。
三、主页体面的结构特征分析
这是一个中国电影票房的首页界面
结构特征
结构分析
四、网络爬虫程序分析
# 引入库
import pandas as pd
import time
import urllib.request
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36‘) #进行伪装
resp = urllib.request.urlopen(request)
html = resp.read().decode(‘utf-8‘)
return html
# 待爬取内容
name = []
year = []
Box_office = []
# 循环爬取每页内容
for k in range(10):
movie_year = 2010+k
url = download(‘http://www.boxofficecn.com/boxoffice{}‘.format(movie_year))
time.sleep(3) #间隔3s,防止被封禁
tree = fromstring(url)
soup = BeautifulSoup(url)
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=‘c:/Users/wzj/Desktop/修身/与自己/数据分析/数据分析/爬虫/中国电影票房/movie_box_office.csv‘ ## 路径需要自己改!
movie_Box_office_data.to_csv(outputpath,sep=‘,‘,index=False,header=True,encoding=‘utf_8_sig‘)
引入库,导入数据
#matplotlib inline
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(‘movie_box_office.csv‘)
data.head()
len(data)
#十年top10
data.sort_values(by=‘票房‘,ascending=False).head(10)
data.iloc[2111,2]=142241.3
data.sort_values(by=‘票房‘,ascending=False).head(10).plot.bar(x=‘电影‘,y=‘票房‘,title=‘top 10‘)
# 年度top5
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‘)
data[data[‘年份‘]==2013].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2013 top 5‘)
data[data[‘年份‘]==2014].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2014 top 5‘)
data[data[‘年份‘]==2015].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2015 top 5‘)
data[data[‘年份‘]==2016].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2016 top 5‘)
data[data[‘年份‘]==2017].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2017 top 5‘)
data[data[‘年份‘]==2018].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2018 top 5‘)
data[data[‘年份‘]==2019].sort_values(by=‘票房‘,ascending=False).head(5).plot.bar(x=‘电影‘,y=‘票房‘,title=‘2019 top 5‘)
# 每年电影数
groupby_year = data.groupby(‘年份‘).size()
groupby_year.plot.bar(title = ‘每年电影数‘)
# 每年总票房
data.groupby(‘年份‘)[‘票房‘].sum().plot.bar(title = ‘每年总票房‘)
# 电影票房中的二八原则
data[data[‘年份‘]==2019][‘票房‘].plot.hist()
data[data[‘年份‘]==2018][‘票房‘].plot.hist()
percent = []
for k in range(10):
Boxoffice= data[data[‘年份‘]==(2010+k)][‘票房‘]
q80 = np.percentile(Boxoffice ,80)
percent.append(Boxoffice[Boxoffice >= q80].sum()/ Boxoffice.sum())
percent
五、总结
在学习python爬取近十年中国电影票房数据和分析后,对爬取知识有了一个深的了解,并且实现了数据的可视化。使用BeautifulSoup更加熟练。