本文主要通过对豆瓣电影爬取的数据进行的简要分析,观察得出各部分之间对应的关系影响。
一.数据抓取
我们要想进行数据分析,首先就要通过爬虫对分析对象网页的数据爬取保存,可以保存到数据库或者文件形式到本地,这里我是保存在表格中。既然获取了数据,那肯定要分析一下,豆瓣电影的各种详细的数据,评分,影评等等在国内同类型网站中,算是高质量的,所以进行数据分析也是有价值的。下面是爬取数据的关键步骤:
1.HTML解析
解析的工具有很多。比如:正则表达式、Beautifulsoup、Xpath、css等,这里采用xpath方法。
# 构造第i页的网址
url='https://movie.douban.com/top250?start='+str(25*i)
header={'user-agent':'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0'}
# 发送请求,获得返回的html代码并保存在变量html中
html = requests.get(url,headers=header)
#将返回的字符串格式的html代码转换成xpath能处理的对象
html=etree.HTML(html.text)
headers是设置反爬虫的措施
2.逐层查询信息
首先鼠标右键检查或者F12,打开当前网页的html代码。然后先单击右上角处的箭头,把鼠标移动到你要查找的信息上,右边就会显示你点击信息在html代码中的位置。一个网页的html代码是一层一层结构化的,非常规整的。每一对尖括号包起来的是一个标签,比如…,这就是一个span标签。span叫标签名,class="title"是标签的属性,“肖申克的救赎”是标签的内容。标签span在html代码中的完整路径应该是:
用xpath查找元素就是按照路径一层层找下去,[@id=“wrapper”]表示查找的标签的属性,用标签加上属性,我们可以更方便的定位,不用从头找到尾。div[1]、span[1]表示要查找的是该标签下的第1个div标签,第1个span标签。找到span标签可以用方法span[1]/text()取出其中的内容,pan[1]/@class可以取出属性值。
datas = html.xpath('//ol[@class="grid_view"]/li')
for data in datas:
data_title=data.xpath('div/div[2]/div[@class="hd"]/a/span[1]/text()')#电影名称
data_info=data.xpath('div/div[2]/div[@class="bd"]/p[1]/text()')#电影导演、主演、上映时间
data_score=data.xpath('div/div[2]/div[@class="bd"]/div/span[@class="rating_num"]/text()')#评分
data_num=data.xpath('div/div[2]/div[@class="bd"]/div/span[4]/text()')#评论人数
3.保存到CSV文件
def write_dictionary_to_csv(self,dic,filename):
#file_name='{}.csv'.format(filename)
file_exists = os.path.isfile(filename)#判断是否为文件
with open(filename, 'a',encoding='utf-8',newline='') as f:
headers=dic.keys()#dic是字典形式最后获取的所有信息
w =csv.DictWriter(f,delimiter=',',lineterminator='\n',fieldnames=headers)
#以字典形式向w中写入
if not file_exists :
w.writeheader()#保存数据
w.writerow(dic)#单行写入
print('当前行写入csv成功!')
二.数据可视化分析
2.1中国电影分布情况
首先对电影评分进行统计分析,由于电影数据只有top50,数据较少且都是排名靠前的电影,所以进行相应能得到符合现实情况的分析。
我们先来看看其中中国的影片:
mask1=data['country'].isin(['中国大陆','中国香港'])
data.loc[mask1]#找country列中名字是'中国大陆','中国香港'的行
可以发现中国影片在前50就占了7个,14%分布,其中霸王别姬排名第二(top从0开始)
这里我们可以把中国大陆和中国香港统称为中国,毕竟咱们都是一家人嘛,可以
countrys=list(data.country.unique())
data.loc[data['country']=='中国香港','country']='中国'#把country列中名字是中国香港的国家改为中国
data.loc[data['country']=='中国大陆','country']='中国'
mask2=data['country'].isin(['中国'])
data.loc[mask2]
对比上一个图可以看到全部改为了中国
2.2评分分布情况
plt.rcParams['figure.figsize']=(8,3)#图形大小
data.groupby(['year']).sum().plot(kind='bar')#x轴
plt.xticks(rotation=60)#夹角旋转60度
plt.ylabel('score',fontsize=15)#y轴及字号
plt.xlabel('Date',fontsize=15)#x轴及字号
这里本想着借助图形表分析随着年份的推移,有没有更好的电影出现,但这里由于评论人数基数相对于评分,星级太大,所以没有显示出来,不过根据评论人数的多少也是可以看出电影的受欢迎度,因此这个影响不大
data.groupby('year').sum()['score']#每年好的评分作品有多少
plt.figure(figsize=(5,4))
data.groupby('year').sum()['score'].plot()#图形显示
电影所代表的那个年份里,对应的评分总和比较,发现在上世纪90年代好的电影层出不穷,达到顶峰
还可以对最受大众讨论热烈的电影进行划分三个等级,分析以评论人数为标准,得出热度等级
from matplotlib import pyplot as plt1
data=pd.read_csv(r'C:\Users\许元宵\Desktop\d.csv',encoding='gbk')
len1=len(data[data['commonnum'] >= 1500000])
len2=len(data[(data['commonnum'] < 1500000) & (data['commonnum'] >=1000000)])
len3=len(data[(data['commonnum'] < 1000000) & (data['commonnum'] >=100000)])
plt1.figure(figsize=(10,15)) #调节图形大小
labels = ['大于一百五十万','一百万到一百五十万','十万到一百万'] #定义标签
sizes = [len1,len2,len3]
colors = ['yellow', 'blue', 'red'] #每块颜色定义
explode = (0,0,0) #将某一块分割出来,值越大分割出的间隙越大
# 中文乱码和坐标轴负号处理
plt1.rcParams['font.sans-serif'] = ['KaiTi']
plt1.rcParams['axes.unicode_minus'] = False
patches,text1,text2 = plt.pie(sizes,
explode=explode,
labels=labels,
colors=colors,
autopct = '%3.2f%%', #数值保留固定小数位
shadow = False, #无阴影设置
startangle =90, #逆时针起始角度设置
pctdistance = 0.6) #数值距圆心半径倍数距离
#patches饼图的返回值,texts1饼图外label的文本,texts2饼图内部的文本
# x,y轴刻度设置一致,保证饼图为圆形
plt1.axis('equal')
plt1.title("豆瓣热门电影分布图")
plt1.legend()
plt1.show()
通过matplotlib可视化分析得出
热度第一的电影占16%,第二占32%,第三占52%,说明评论越多的电影数量越少。