豆瓣电影TOP250数据分析

本文使用的语言为Python, 用到的几个模块有:BeautifulSoup(爬数据),pandas(数据处理),seaborn(可视化),部分图表由Tableau生成。


1. 数据获取

计划要抓取的字段包括:片名,导演,年份,国别,评分,评价数量,看过数量,想看数量,短评数量,长评数量。

需要抓取的影片信息有250条,每页25部影片,一共有10页。简单浏览网页不难发现,翻页的链接不需要从页面底端抓取,直接修改url参数即可。
在这里插入图片描述
例如,第二页的url只需要在base url后面加上?start={start}&filter=即可。因此,第一步的任务就是抓取榜单上的每一部电影的详细信息链接即可。同时,影片的排名信息也可以通过简单计数得到,不需要从页面中抓取。具体代码如下。

import requests
from bs4 import BeautifulSoup
from time import sleep
from csv import DictWriter
base_url = r'https://movie.douban.com/top250'
records = []
for start in [x*25 for x in range(10)]:#Every single pageurl = base_url+f'?start={start}&filter='response = requests.get(url).textsoup = BeautifulSoup(response,'html.parser')movies = soup.find(class_='grid_view').find_all('li')rank=1+startfor movie in movies:#Every single movie on the pagemovie_link = movie.find(class_='info').find(class_='hd').find('a')['href']movie_dict = {'rank':rank, 'link':movie_link}records.append(movie_dict)rank += 1

这样我们就得到了一个list, list中有250个dictionary,每个dictionary中有影片在榜单中的排名和影片详细信息页面链接。

下一步就是进一步从已经得到的链接中抓取影片的详细信息。具体代码如下,仔细分析html标签做简单的测试即可。注意,爬取数据的过程中要加上sleep(5),礼貌爬取,防止IP被封。

#Use the scapped link to further scrape movie details
for record in records:rank = record.get('rank')print(f'Scarpping rank {rank} of 250')link = record.get('link')response = requests.get(link).textsoup = BeautifulSoup(response,'html.parser')record['title'] = soup.find('h1').find('span').get_text()record['year'] = soup.find('h1').find(class_='year').get_text()[1:5]record['director'] = soup.find(id='info').find(class_='attrs').find('a').get_text()record['length'] = soup.find(id='info').find(property='v:runtime').get_text()[:-2]attrs = soup.find(id='info').find_all(class_='pl')for attr in attrs:if attr.get_text().startswith('制片国家'):record['country_region']=attr.nextSibling.strip()elif attr.get_text().startswith('语言'):record['language']=attr.nextSibling.strip()record['avg_rating'] = soup.find(class_='ll rating_num').get_text()record['num_of_ratings'] = soup.find(class_='rating_people').find('span').get_text()interests = soup.find(class_='subject-others-interests-ft').find_all('a')record['people_watched'] = interests[0].get_text()[:-3]record['people_wants_to_watch'] = interests[1].get_text()[:-3]record['num_comment'] = soup.find(id='comments-section').find('h2').find('a').get_text().split()[1]record['num_reviews'] = soup.find(class_='reviews mod movie-content').find('h2').find('a').get_text().split()[1]#Set scrapping interval in case of ip blockingsleep(5)

下一步是将爬取的数据存入csv文件,代码如下:

注意,写入文件时中文可能会乱码,需要加上encoding=‘utf-8-sig’,加上newline=’'解决每行记录之间存在空行的问题。

#Write the 250 movies into a csv file
with open('douban_top_250.csv','w', newline='', encoding='utf-8-sig') as file:headers = [key for key in records[0].keys()]csv_writer = DictWriter(file, fieldnames=headers)csv_writer.writeheader()for record in records:csv_writer.writerow(record)

2. 数据清洗

由于抓取的数据只有250条,可以直接用excel打开,简单看一下数据有没有问题。

在这里插入图片描述
部分片名中可能有夹杂英文名称(中间有空格),部分片长末尾有多余字符,部分记录含有多个国家/地区或者多个语言(中间有空格)。

因为中间存在空格,片名、国家/地区、语言可以通过split()[0]取出第一个词。

片长多余字符的问题可以通过regular expression,用""替换非数字字符。代码如下,注意读取数据的时候需要加上encoding=‘utf-8-sig’:

import numpy as np
import pandas as pd
import re
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as statspath = r'C:\Users\yingk\Desktop\Douban_Top250\douban_top_250.csv'
data = pd.read_csv(path,encoding='utf-8-sig')#Preprocessing
#extract Chinese title
data['Chinese_title'] = data['title'].apply(lambda title:title.split()[0])
data.drop(['title'],axis=1,inplace=True)#re.sub() - Use "" to repleace characters which are not digit
data['movie_length'] = data['length'].apply(lambda length:re.sub("\D","",length))
data.drop(['length'], axis=1, inplace=True)#extract main country_region when there are multiple
data['main_country_region'] = data['country_region'].apply(lambda cr:cr.split()[0])
data.drop(['country_region'],axis=1,inplace=True)#extract main language
data['main_language'] = data['language'].apply(lambda lan:lan.split()[0])
data.drop(['language'],axis=1,inplace=True)data.to_csv(r'C:\Users\yingk\Desktop\Douban_Top250\cleaned_data.csv',encoding='utf-8-sig')

3. 探索分析

将清洗好的csv文件导入Tableau,下面是豆瓣电影TOP250上的制片国家/地区分布和各个语言所占的比重。比重越大,字体越大。类似的图表也可以用Python wordcloud来做。

在这里插入图片描述
榜单上的美国影片占了相当大的比重,其次是日本,然后才是中国大陆、中国香港和英国。
在这里插入图片描述
从制片国家/地区上不难推断,榜单上英语将会占很大的比重,其次是日语,然后是普通话和粤语。

下面是榜单上影片的年代分布,在Tableau中可以创建组来实现对上映时间的划分。

在这里插入图片描述
1990年之后上映的电影几乎占据了整个榜单的85%,这应该和电影技术的发展有关系。更早期的电影在数量、画面、主题、拍摄手法等方面上可能比较难征服现在的观众。



“豆瓣用户每天都在对“看过”的电影进行“很差”到“力荐”的评价,豆瓣根据每部影片看过的人数以及该影片所得的评价等综合数据,通过算法分析产生豆瓣电影 Top 250。”

以上摘自豆瓣。

下面简单分析一下哪些特征会榜单排名产生比较大的影响。

首先需要拿掉诸如链接,片名,导演等非量化字段。

metrics = data.drop(['link','director','Chinese_title','main_country_region','main_language'],axis=1)

增加/转化一些字段:

相较于平均评分,评价人数,可能增加一个总评分=avg_rating*num_of_ratings会更直接体现影片的质量。

上映年份可以转换成已经上映了多少年,即2019-year,在时间显得更直观。

metrics.eval('total_rating_scores = avg_rating*num_of_ratings', inplace=True)
metrics['years to 2019'] = metrics['year'].apply(lambda y:2019-y)
metrics.drop(['year'],axis=1,inplace=True)

生成相关系数和heatmap。

corr = metrics.corr()
plt.figure(figsize=(6,5), dpi=100)
sns.heatmap(corr,cmap='coolwarm',linewidths=0.5)

在这里插入图片描述
观察heatmap的第一行不难发现,rank和多个字段存在较高的相关性。下面看一下具体的相关系数:

corr.head(1)

在这里插入图片描述
新建的字段total_rating_scores相关系数最高,进一步做显著性检验:

#total_rating_scores t-test
x = list(metrics['rank'])
y = list(metrics['total_rating_scores'])
r,p = stats.pearsonr(x,y)
print(r)
print(p)

在这里插入图片描述
相关系数为-0.7,显著性水平小于0.001,说明豆瓣电影TOP250榜单的排名与影片得到总评分存在较强的相关性。总评分越高,排名越靠前。

类似的字段还有平均评分、评分人数、观看人数,而想看人数、短评数、长评数相关性相对较弱,与上映时间几乎没有相关性。

因此,想要影片挤进这份榜单,需要影片能够得到足够多的评分和较好的评价。

由于样本数量只有250个,加上豆瓣内部可能还有其他隐藏的特征,现有的数据可能很难构建出比较满意的模型。可以尝试爬取更多的数据并增加其他特征然后再来构建榜单排名的预测模型。

豆瓣上每部影片都有很多短评/长评,观察heatmap的第6、7行可以发现,平均评分与影片短评/长评的相关性较弱。这与我们平常看到的烂片常常反而能够引来热烈讨论的现象相一致。同样与影评数量相关性较弱的还有标记为想看的数量和影片上映的时间。

可以通过boxplot来进一步了解。代码如下:

comment_reviews = metrics.loc[:,['num_comment','num_reviews']]
def bin_years(value):for i in range(10,91,10):if value<i:return f'{i-9}-{i}'
comment_reviews['years_bin'] = metrics['years to 2019'].apply(bin_years)
bins = [f'{i-9}-{i}' for i in range(10,91,10)]
plt.figure(figsize=(12,5), dpi=100)
sns.boxplot(x='years_bin', y='num_comment', data=comment_reviews, order=bins)
plt.figure(figsize=(12,5), dpi=100)
sns.boxplot(x='years_bin', y='num_reviews', data=comment_reviews, order=bins)

在这里插入图片描述
在这里插入图片描述
豆瓣电影TOP250榜单上,除了最近10年的影片获得的影评相比较高以外,其他上映时间的电影得到的影评数量大体保持在同一水平。这也与这两组特征之间较低的相关系数相吻合。



数据来源: 豆瓣Top250榜单:https://movie.douban.com/top250

完整代码: https://github.com/Yinstinctive/douban_top_250

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/63546.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

豆瓣高分电影信息分析(数据分析)

豆瓣高分电影信息分析&#xff08;数据分析&#xff09; 1、数据抓取 数据集的获取是我们进行数据分析的第一步。现在获取数据的主要途径一般为&#xff1a;现成数据&#xff1b;自己写爬虫去爬取数据&#xff1b;使用现有的爬虫工具爬取所需内容&#xff0c;保存到数据库&am…

豆瓣电影评分分析(数据分析)

本文主要通过对豆瓣电影爬取的数据进行的简要分析&#xff0c;观察得出各部分之间对应的关系影响。 一.数据抓取 我们要想进行数据分析&#xff0c;首先就要通过爬虫对分析对象网页的数据爬取保存&#xff0c;可以保存到数据库或者文件形式到本地&#xff0c;这里我是保存在表…

人类禁止进入的“微博”,我的AI机器人在那里吹牛,“勾搭”AI小姑娘

最近球友推荐了一个非常有趣的网站&#xff0c;叫“奇鸟”&#xff08;https://chirper.ai/zh&#xff09;。 简单来说&#xff0c;这是一个AI专属的微博&#xff0c;人类禁止发言&#xff0c;但是你可以创建一个叫“奇鸟”的机器人代理&#xff0c;让它在里边发帖&#xff0c;…

OpenAI 的嵌入 API太慢了吗?探索其他嵌入模型和服务的优势

这篇文章讨论了机器学习模型的延迟对聊天应用和代理的用户体验的影响&#xff0c;重点关注了生成语言模型&#xff08;LLM&#xff09;的提示生成过程中的语义搜索任务。文章比较了两种嵌入API 服务&#xff08;OpenAI 和 Google&#xff09;和几种开源嵌入模型&#xff08;sen…

chatgpt赋能python:Python怎么Import自己写的SEO文章

Python怎么Import自己写的SEO文章 如果你是一位Python开发人员&#xff0c;并且正在为SEO优化而努力编写文章&#xff0c;那么你可能会想知道如何将自己编写的SEO文章导入您的程序中以便更好的利用。 在这篇文章中&#xff0c;我们将介绍如何使用Python中的import语句将自己编…

什么是全景地图?

如果问什么是全景图&#xff0c;那应该很多人都能回答上来。那么要是问什么是全景地图&#xff0c;估计很多人就不清楚了。然而我们在想要知道全景地图是怎么做的时候&#xff0c;就必须要知道什么是全景地图&#xff0c;那么这篇文章就告诉大家什么是全景地图。 全景地图也经…

全景图为何如此受欢迎/

为何全方位全景和720度全景这般受欢迎?今日我来给各位朋友科谱答疑解惑&#xff1a;说白了3d全景&#xff0c;便是运用全景和虚拟现实技术技术性&#xff0c;在互联网技术完成可720度无死角收看的呈现方式。从现阶段的实例来讲&#xff0c;3d全景除开在游戏娱乐行业得到巨大的…

教你一招,如何将vr网站中的360全景图图片和全景漫游文件下载到本地电脑

如果你打开vr全景平台&#xff0c;看到好的作品想将360全景图片下载保存到本地&#xff0c;直接右键另存是下载不下来的&#xff0c;因为上传的图片已经过服务器端碎片化处理&#xff0c;在浏览器端访问时通过js脚本动态的加载碎片组合成全景漫游的效果&#xff0c;那么将全景图…

【案例】VR全景图:效果+源码

狠人话不多说,直接放视频效果地址 一、效果 1.视频效果 视频效果地址:点击这里 2.图片效果 二、构思 该怎么实现?页面如何布局页面是否可随意控制显示1.功能 控制页面显示数量可放大控制全景图+自动播放左右按钮控制上一页或下一页(尾页:下一页按钮隐藏,首页:上一页按…

web实现全景图的交互展示

Web实现全景图的交互展示 不需要学习其他知识&#xff0c;小白也能实现全景图AR展示一、webVR全景图多种方案实现&#xff08;aframe&#xff0c;Krpano&#xff0c;three,jquery-vrview等等&#xff09;二、用krpano之前的一些知识准备三、krpano的购买、下载、注册四、做一个…

全景图的获取以及HTML页面显示全景图

目录 前言 1. 使用全景相机拍摄 2.手机app拍摄 3.使用爬虫爬取 二、全景图显示 总结 前言 随着前端技术的不断发展&#xff0c;图像的展示越来越重要&#xff0c;本文就介绍了全景图获取与显示的基础内容。 一、全景图片获取方法 1. 使用全景相机拍摄 拍摄的图片在2维显示下…

PTGui+PS生成全景图

1.打开PTGui&#xff0c;加载影响&#xff0c;拖入需要生成的全景图文件 2.点击对齐影像 3.点击创建全景图片 4.把生成的全景图导入到PS&#xff0c; 由于生成的全景图天空是空缺的&#xff0c;需要使用PS修复 套索选中黑色区域&#xff0c;右击填充即可。如遇到内存不足&#…

百度全景图/内景图切换示例

先看效果&#xff1a; 外景图 内景图&#xff1a; 具体代码&#xff1a; <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><meta name"viewport" content&qu…

什么是全景图?如何进行vr全景图拍摄

照片可以记录生活中的精彩的片段&#xff0c;而且照片的种类也分为很多&#xff0c;比如人像图&#xff0c;美食图&#xff0c;风景图等&#xff0c;其中有一种照片称为大像素全景图&#xff0c;大像素是全景的一种比较超高清的全景图&#xff0c;他不仅可以保留vr全景技术的所…

自己制作并发布720°VR全景图

大疆内置的全景图不好用&#xff0c;导出就成了平面图了&#xff0c;只能在他的“天空之城”上看&#xff0c;很不方便&#xff0c;而且他的全景图像素降低了&#xff0c;所以我们要自己制作。 1、先用大疆或者其它设备拍一组全景照。 2、然后下载并安装“PTGui”软件&#xff…

浪潮信息Inspur KOS性能及稳定性位列前茅 与万里安全数据库GreatDB高效兼容

为满足企业在数据安全、产品可控等数字化转型中的多样化需求&#xff0c;浪潮信息正基于技术与应用的深厚积累&#xff0c;持续优化创新产品及服务能力&#xff0c;助力企业在数智化时代下构筑黑心竞争力。日前&#xff0c;浪潮信息打造的Inspur KOS V5与万里安全数据库软件Gre…

随便聊聊浪潮开务数据库

今天这个话题挺随意&#xff0c;我们来聊聊浪潮开务数据库&#xff0c;原因主要是我的微信朋友圈被这个数据库刷屏了。当然我对这款号称多模数据库的非开源数据库也很感兴趣&#xff0c;也有很多疑问&#xff0c;希望各位专家能帮忙答疑解惑&#xff0c;揭开这款即将发布的 Kai…

浪潮信息推出服务器操作系统Inspur KOS的底气与豪气

近日&#xff0c;浪潮信息正式发布了其基于Linux内核、OpenAnolis等开源成果自主研发的服务器操作系统Inspur KOS&#xff0c;这为本就热闹非凡的自主操作系统市场再次带来涟漪。 何以推出Inspur KOS&#xff1f; 浪潮信息副总裁张东表示&#xff0c;“智慧时代&#xff0c;计…

20220624使用python3通过近6期的号码生成双色球红球

20220624使用python3通过近6期的号码生成双色球红球 2022/6/24 18:33 https://zst.cjcp.com.cn/shdd/ssq-hq.html 双色球红球杀号 首先获取近100期的双色球的红球号码。 【本例子以2022-06-21号算号为例子】 获取最近的6期的号码&#xff1a; 04 06 12 13 17 31 09 14 18 23…