抓取豆瓣电影,告诉你《阿丽塔:战斗天使》到底值不值得看

最近,由詹姆斯·卡梅隆执导的《阿丽塔:战斗天使》备受追捧。据说光特效动作就动用了三万台电脑,由800位特效工作人员同时动工,耗时两年完成。那这部电影到底讲的是什么,到底值不值得去电影院看呢(土豪请绕道)。当然,直接百度我们就可以知道值不值得看,但是作为python初学者,有必要拿这个来试试手。

从豆瓣上抓取影评进行分析,由于才刚上映几天,豆瓣的影评还是比较少的,这也为我们数据的抓取节省了时间(虽说要数据多,准确性才高)。

对豆瓣上关于“阿丽塔:战斗天使 短评”的url进行分析,发现第一页的url为
在这里插入图片描述
第二页
在这里插入图片描述
发现在两个url中只有start在发生变化,因此我们便可以构造所有评论页面的基本的url为

https://movie.douban.com/subject/1652592/comments?start={}&limit=20&sort=new_score&status=P

很不幸的是,豆瓣你不登陆的话只能看到前几页的评论,后面的你就看不了
在这里插入图片描述
怎么办呢?这个时候就需要我们用到session来提交登陆表单,并维持会话。通过分析发现,豆瓣登陆时请求的url和表单分别为
在这里插入图片描述在这里插入图片描述
之后我们便可以对数据进行抓取,保存。
完整代码如下:

import requests
from pyquery import PyQuery as pq
import pandas as pd
from multiprocessing.pool import Pool
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
from pyecharts import Pie, Bar
import jieba
from collections import Counter
import matplotlib.pyplot as plt
import time
import random

# jieba.add('--')   # 可添加自定义词

class DouBan():
	def __init__(self):
		self.login_url = 'https://accounts.douban.com/j/mobile/login/basic'
		self.base_url = 'https://movie.douban.com/subject/1652592/comments?start={}&limit=20&sort=new_score&status=P'
		self.headers = {
				'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
				}
		self.douban_session = requests.Session()
		self.postData = {
			'ck': None,
			'name': '*****',
			'password': '****',
			'remember': 'false',
			'ticket': None
		}
		self.douban_session.post(url = self.login_url, data = self.postData, headers = self.headers)

	def download(self, i):
		"""
		下载当前页面
		:param i: 第几页
		:return: 网页源码
		"""
		time.sleep(2 + random.randint(0, 3) / 5)
		response = self.douban_session.get(url = self.base_url.format(i * 20), headers = self.headers)
		if response.status_code == 200:
			return response.text
		else:
			self.download(i)

	def get_point(self, _class):
		"""
		将豆瓣上的星级转化为分数
		:param _class: 豆瓣上显示的星级,由于class为python关键字,不能重复,所以写为_class
		"""
		if _class == '力荐':
			return int(10)
		elif _class == '推荐':
			return int(8)
		elif _class == '还行':
			return int(6)
		elif _class == '较差':
			return int(4)
		else:
			return int(2)

	def get_data(self, html):
		"""
		提取网页上所需要的数据
		:param html: 网页源码
		:return: 评价数据
		"""
		doc = pq(html)
		items = doc('div.comment-item').items()
		for item in items:
			yield pd.DataFrame({
				'user_nick': [item('span.comment-info > a').text()],           # 昵称
				'score': [self.get_point(item('span.rating').attr('title'))],  # 评分
				'content': [item('span.short').text()],                        # 评价
				'userful_num': [item('span.votes').text()]                     # 多少人觉得有用
			})

	def write_to_csv(self, data):
		"""
		将数据保存到本地
		:param data: 数据
		"""
		data.to_csv('阿丽塔:战斗天使.csv', mode = 'a', encoding = 'utf_8_sig', index = False, header = None)  # header=None去除标题行

	def main(self, i):
		"""
		使用多线程抓取豆瓣上的所有评论
		:param i: 第几页
		"""
		html = self.download(i)
		for result in self.get_data(html):
			self.write_to_csv(result)

if __name__ == '__main__':
	douban = DouBan()
	pool = Pool()
	groups = ([i for i in range(0, 25)])
	pool.map(douban.main, groups)
	pool.close()
	pool.join()

在这里,使用了教程池来进行数据的抓取以节省时间。
本地保存的数据的如下(由于豆瓣上的评论比较少,数据都没能上k):
在这里插入图片描述

在数据抓取完成之后,就需要来进行了数据分析了,直接上代码:

def data_clear():
	"""
	将有Null的数据行删掉
	:return: 处理后的数据
	"""
	data = pd.read_csv('阿丽塔:战斗天使.csv', names = ['user_nick', 'score', 'content', 'userful_num'], 
						encoding = 'utf_8_sig')
	data = data[~data['userful_num'].isin(['NaN','nan'])]  # 将有NaN的数据行给删除掉,‘~’为取反
	return data

def stopwords(text):
		"""
		设置停用词
		:param text: 未进处理的原文本
		:return: 过滤掉停用词的文本
		"""
		fliter_word_list = []
		word_list = [word for word in jieba.cut_for_search(text)]
		with open('StopWords.txt', 'r') as f_obj:
			stopwords_list = f_obj.read()
		for word in word_list:
			if word.strip() not in stopwords_list:
				fliter_word_list.append(word)
		return fliter_word_list

def wordcloud():
	"""
	绘制词云
	"""
	data = data_clear()
	comments = ''.join(data['content'])
	word_list = stopwords(comments)
	background_image = plt.imread('background.jpg')      # 导入背景图
	wc = WordCloud(background_color = 'white',           # 背景颜色
					max_words = 100,                     # 最大次数
					mask = background_image,   
					max_font_size = 500,                 # 显示字体的最大值
					font_path = 'simfang.ttf',           # 设置字体格式,如不设置显示不了中文
					random_state = 50,                   # 为每个词返回一个PIL颜色
					)
	word_fre = Counter(word_list)
	wc.generate_from_frequencies(word_fre)
	# wc.generate_from_text(str(comment_list))
	image_colors = ImageColorGenerator(background_image) # 基于彩色图像生成相应颜色
	plt.imshow(wc.recolor(color_func = image_colors))    # 绘制词云
	plt.axis('off')
	# plt.show()
	wc.to_file('wordcloud.jpg')

def pie():
	"""
	计算每个评分的人数绘制饼图
	"""
	data = data_clear()
	# total_num = data.shape[0]
	score_group = data['score'].groupby(data['score'])   # 统计每个评分的人数
	score_count = score_group.agg(['count'])
	score_count.reset_index(inplace = True)
	attr = ['力荐', '推荐', '还行', '较差', '很差']
	value = [(score_count['count'][i]) for i in range(len(score_count))]
	pie = Pie('《阿丽塔:战斗天使》评分图', title_pos = 'center')
	pie.add('人数', attr, value, center = [40, 60], is_random = True, radius = [20, 65],
			is_legend_show = True, legend_orient = 'vertical', legend_pos = 'left', is_label_show = True)
	pie.render('《阿丽塔:战斗天使》评分图.html')

def bar():
	"""
	计算每个评分的觉得有用人数百分比绘制柱状图
	该评分的觉得有用人数 / 总有用人数
	"""
	data = data_clear()
	total_userful_num = data['userful_num'].sum()
	userful_data = data['userful_num'].groupby(data['score'])
	userful_data_count = userful_data.agg(['sum'])
	userful_data_count.reset_index(inplace = True)
	# userful_data_count.sort_values(by = 'sum', axis = 0, ascending = False, inplace=True)         # 对数据进行排序
	attr = userful_data_count['score']
	value = [(round((userful_data_count['sum'][i]/ total_userful_num) * 100, 3)) for i in range(len(userful_data_count))]
	bar = Bar('评分价值数', title_pos = 'left', width = 400)
	bar.add('评分价值数', attr, value, yaxis_min = 0, xaxis_interval = 0, is_splitline_show = False)
	bar.render('评分价值数.html')

read_csv时,会报编码错误,这个因为在保存编码时不正确,我们可以将本地保存的csv文件以记事本的方式打开,并在另存为csv文件时选择编码发生UTF-8格式。由于在得到的数据中有时候会出现NaN,因此我们需要将存在NaN的数据行给删除掉。
在绘制词云时,我们需要对得到的文本进行过滤处理,将一些停用词给去掉。

最后得到的数据图:
词云:
在这里插入图片描述
出现频率较高的词有‘特效’,‘效果’,‘技术’等,果然,用三万台电脑来进行特效处理还是有所体现的,我想,应该大多数人都是冲着那个将近900万个像素的眼睛去的吧。

在这里插入图片描述
在这里插入图片描述
从饼图和柱状图的来看,五星力荐的人数只有5.5%,而觉得较差的高达35.03%,并且给五星的评价的有用性只能排到第三。可想而知,大多数影迷们对该片期望过高。

从以上分析来看,这部电影对于我们这些还在为生活忧虑的人还是省点钱吧,小资产的还是可以去看看的,但还是不要带女票去看。

以上纯属娱乐,所有观点仅个人观点。

还望大家指正错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值