爬取豆瓣电影数据并进行分析可视化

2023-11-17

学习爬虫爬取豆瓣电影数据并进行分析,整体流程如下:

1、爬取豆瓣电影数据

2、读取豆瓣电影数据

3、统计各个电影的评论数

4、读取某个电影的全部评论内容

5、获取某个电影的关键词并生成词云图

6、对电影数据的关键词和评分进行辩证分析并生成热力图

让我们开始吧!废话不多说,直接上代码 #------#

爬取豆瓣电影数据

import requests
from bs4 import BeautifulSoup
from collections import OrderedDict
import pandas as pd
# 设定headers
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
movie_info = OrderedDict()

def detail_handle(url):
    html = requests.get(url,headers = headers)
    soup = BeautifulSoup(html.text,'lxml')
    movie_info['movie_rank'] = soup.find_all('span',class_="top250-no")[0].string
    movie_info['movie_name'] = soup.find_all('span',property="v:itemreviewed")[0].string
    soup_div = soup.find(id="info")
    movie_info['movie_director'] = handle_mul_tags(soup_div.find_all('span')[0].find_all('a'))
    movie_info['movie_writer'] = handle_mul_tags(soup_div.find_all('span')[3].find_all('a'))
    movie_info['movie_starring'] = handle_mul_tags(soup_div.find_all('span')[6].find_all('a'))
    movie_info['movie_type'] = handle_mul_tags(soup_div.find_all('span',property="v:genre"))
    movie_info['movie_country'] = soup_div.find(text = '制片国家/地区:').next_element.lstrip().rstrip()
    movie_info['movie_language'] = soup_div.find(text = '语言:').next_element.lstrip().rstrip()
    movie_info['movie_release_date'] = handle_mul_tags(soup_div.find_all('span',property="v:initialReleaseDate"))
    movie_info['movie_run_time'] = handle_mul_tags(soup_div.find_all('span',property="v:runtime"))
    movie_second_name = ''
    try:
        movie_info['movie_second_name'] = soup_div.find(text = '又名:').next_element.lstrip().rstrip()
    except AttributeError:
        print('{}没有别名'.format(movie_info['movie_name']))
        movie_info['movie_second_name'] = movie_second_name
        
    movie_info['movie_rating'] = soup.find_all('strong',property="v:average")[0].string
    movie_info['movie_comment_users'] = soup.find_all('span',property="v:votes")[0].string
    soup_div_for_ratings = soup.find('div',class_="ratings-on-weight")
    movie_info['movie_five_star_ratio'] = soup_div_for_ratings.find_all('div')[0].find(class_="rating_per").string
    movie_info['movie_four_star_ratio'] = soup_div_for_ratings.find_all('div')[2].find(class_="rating_per").string
    movie_info['movie_three_star_ratio'] = soup_div_for_ratings.find_all('div')[4].find(class_="rating_per").string
    movie_info['movie_two_star_ratio'] = soup_div_for_ratings.find_all('div')[6].find(class_="rating_per").string
    movie_info['movie_one_star_ratio'] = soup_div_for_ratings.find_all('div')[8].find(class_="rating_per").string
    return movie_info
    
def handle_mul_tags(soup_span): # 获取多个标签结果将合并在一起,以/分隔
    info = ''
    for second_span in soup_span:
        info = ('' if (info == '') else '/').join((info,second_span.string))
    return info

def crawl():
    htmls = ['https://movie.douban.com/top250?start={}&filter='.format(str(page)) for page in range(0,250,25)]
    for html in htmls:
        html_url = requests.get(html,headers = headers)
        soup = BeautifulSoup(html_url.text,'lxml')
        movie_htmls = soup.select('.pic')
        for movie_html in movie_htmls:
            url = movie_html.select('a')[0]['href']
            return detail_handle(url)

对电影数据进行分析和可视化

import sqlite3
import pandas as pd
import jieba
import math
import pyecharts.options as opts
from pyecharts.charts import WordCloud
import os
os.chdir('C:\\Users\\Theo.chen\\Desktop\\数据分析项目\\')

import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

conn = sqlite3.connect('douban_comment_data.db')
comment_data = pd.read_sql_query('select * from comment;', conn)
movie_data = pd.read_excel('douban_movie_data.xlsx')
FILTER_WORDS = ['知道','影评','影片','小编','没有','一个','\n','good','is','thing','这个','就是','什么','真的','of',
                '我们','最后','一部','the','片子','这么','那么','不是','还是','时候','觉得','电影','但是','hope','Hope','best','因为',
                '只是','故事','看过','豆瓣','maybe','这部']

def get_movie_idList(min_comment_count):
    movie_list = comment_data['MOVIEID'].value_counts()
    movie_list = movie_list[movie_list.values > min_comment_count]  
# 筛选出评论数>100的电影
    return movie_list.index

def get_comment_keywords(movie_id,count):
    comment_list = comment_data[comment_data['MOVIEID'] == movie_id]['CONTENT']
    comment_str_all = ''
    for comment in comment_list:
        comment_str_all += comment + '\n'
    seg_list = list(jieba.cut(comment_str_all))
    keywords_counts = pd.Series(seg_list)
    keywords_counts = keywords_counts[keywords_counts.str.len() > 1]
    keywords_counts = keywords_counts[~keywords_counts.str.contains('|'.join(FILTER_WORDS))]
    keywords_counts = keywords_counts.value_counts()[:count]
    return keywords_counts

def get_movie_name_and_score(movie_id):
    movie_link = 'https://movie.douban.com/subject/{}/'.format(movie_id)
    search_result = movie_data[movie_data['链接'] == movie_link].iloc[0]
    movie_name = search_result['电影名']
    movie_score = search_result['评分']
    return (movie_name,movie_score)

def generate_wordcloud(word_list,path_name):
    wordcloud = WordCloud()
    wordcloud.add(
        "",
        tuple(zip(keywords_counts.index,keywords_counts)),word_size_range = [20,100])
    wordcloud.render(path_name)
    print(f"Generate word cloud file done: {path_name}")

# 创建列表, 每个列表都含有10个列表
kw_list_by_score=[[] for i in range(10)]
kw_counts_by_score = [[] for i in range(10)]

movie_id_list = get_movie_idList(300)
for movie_id in movie_id_list:
    word_list = get_comment_keywords(movie_id,30)
    movie_name, movie_score = get_movie_name_and_score(movie_id)
    try:
        kw_list_by_score[math.floor(movie_score)].extend(word_list.index)
        kw_counts_by_score[math.floor(movie_score)].extend(word_list.values)
    except:
        print('Something Error!!!')

for i in range(10):
    if kw_list_by_score[i]:
        kw30_with_counts = pd.DataFrame({
            'kw':kw_list_by_score[i],
            'count':kw_counts_by_score[i]
            })
        kw30_with_counts = kw30_with_counts.groupby('kw').sum()
        kw30_with_counts = kw30_with_counts.sort_values(by = 'count', ascending = False)[:30]
        counts_sum = kw30_with_counts['count'].sum()
        kw30_with_counts['percentage'] = kw30_with_counts['count'] / counts_sum
        kw30_with_counts.to_csv('{}_movie_keywords.csv'.format(i))


from pyecharts.charts import HeatMap

kw_counts_by_score=[[] for _ in range(10)]
for i in range(4,10):
	kw_counts_by_score[i] = pd.read_csv('{}_movie_keywords.csv'.format(i))
	kw_percentage_df = pd.DataFrame([],
		columns = list(range(4,10)),
		index=kw_counts_by_score[9]['kw'][:10])

for i in range(4,10):
	kw=kw_counts_by_score[i]
	kw=kw[kw['kw'].isin(kw_percentage_df.index)]
	kw_percentage_df[i] = pd.Series(list(kw['percentage']),index=kw['kw'])

kw_percentage_df.fillna(0,inplace=True)

data=[]
i = 0
for index in kw_percentage_df.index:
	j=0
	for column in kw_percentage_df.columns:
		data.append([j,i,kw_percentage_df[column][index]*100])
		j+=1
	i+=i

heatmap = HeatMap()
heatmap.add_xaxis(list(kw_percentage_df.columns))
heatmap.add_yaxis("电影评论关键词热力图",list(kw_percentage_df.index),data)
heatmap.set_global_opts(
	visualmap_opts=opts.VisualMapOpts(
		min_= 0,
		max_=10,
		orient='horizontal'
		),
	)
heatmap.render(path="heatmap.html")

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

爬取豆瓣电影数据并进行分析可视化 的相关文章

随机推荐

  • 在事情没有变得糟糕之前_这是我们没有的问题的糟糕解决方案

    在事情没有变得糟糕之前 最糟糕的代码是什么 不要说JavaScript 它会在你身上成长 不 也不是Perl 好的 所以Perl非常令人讨厌 最糟糕的代码 这是我们不需要的代码 紧接着是几乎有效的代码 然后是无效的代码 几乎可以正常工作的代
  • sim卡安全问题

    USIM 存储支持鉴权密钥K 是整个UMTS安全体系的核心 接受参数有 随机数 RAND 鉴权标志参数 AUTN 并计算生成消息鉴权码 XMAC 响应参数 RES 完整性保护密钥 IK 鉴权密钥 CK GSM的SIM卡仅是一种单应用卡 它仅
  • ora-12542 address in used

    这主要是由于 操作系统的 临时端口 不够用而引起的 一般系统的 临时端口为 1024 5000 这在多用户的环境下 3000多个oracle链接就用光了 由于每个链接断开以后 还要有一个等待时间 例如在 windows 系统中 这个时间是
  • 比亚迪后续车都会搭在鸿蒙系统吗_华为手机也能当车钥匙,搭载鸿蒙系统,5G款比亚迪赶超特斯拉?...

    一直以来 互联网公司在造车这事儿上都被认为不太靠谱 虽然这点可以让下周回国贾跃亭和他的ff91背下锅 但依然改变不了我们造的车还不是那个 味 有时候我们自己也会疑问 为什么我们为啥没有自己的特斯拉 不过这件事情目前来看 似乎已经不是什么难题
  • windows下C盘文件夹管理员权限设置

    我们有时会将一些软件安装在C盘 却发现有时程序对C盘文件增删改操作失败 然后自己手动去执行时也经常弹出 你需要提供管理员权限才能进删除此文件 之类 这很烦 网上有些说法是开启Administrator用户 但是我这种有点洁癖的不喜欢增加一个
  • java b 类型_什么类型的Java类型是“[B”?

    我试图通过Java代码 Hibernate 从MySQL DB获取MD5加密传递 但我不能得到字符串或任何合理的Java类型 我唯一得到的是这个无益的信息 java lang ClassCastException B无法转换为com mys
  • 封装与检测技术

    环氧树脂 环氧树脂是一种高分子聚合物 分子式为 C 11 H 12 O 3
  • 复杂的密码有多重要?实操暴力破解wifi密码......

    暴力破解就是穷举法 将密码字典中每一个密码依次去与握手包中的密码进行匹配 直到匹配成功 注意 私自破解他人WiFi属于违法行为 本教程仅供学习与参考 破解工具 破解工具 kali linux系统 本教程使用的装在物理机的linux系统 虚拟
  • postgresql 中输入逃逸字符\n\r\b\t

    例如 1 建表 create table test a1 text a2 varchar 100 a3 char 200 2 插入数据 使用关键字 E insert into test a1 a2 a3 values E aaa n aaa
  • linux ssh服务是否已经启动?

    linux ssh服务是否已经启动 突然想到 ubuntu貌似默认是不会安装ssh server的 会默认安装ssh client 恍然大悟 是不是因为这个原因 于是查看发现 果然没有安装 下面进行安装openssh server sudo
  • Linux系统常用基本命令总结

    Linux基本命令 Linux的简介 Linux的厂商 Linux的目录结构 基于虚拟机的环境搭建 常用命令与示例 一 文件基本操作命令 1 ls命令 2 pwd命令 3 mkdir命令 4 cd命令 5 touch命令 6 cp命令 7
  • ubuntu13.10 64位系统下载Android源码

    参考http source android com source downloading html进行下载 下载过程中出现的问题参考http blog 163 com aravarcv 126 blog static 12384272820
  • (超级详细)如何在Mac OS上的VScode中配置OpenGL环境并编译

    文章目录 安装环境 下载GLAD与GLFW 一 下载GLAD 二 下载GLFW 项目结构配置 测试程序与项目的编译 测试可执行文件HelloGL 安装环境 机器 macbook air 芯片 M1芯片 arm64 macOS macOS V
  • SHA-256算法实现过程

    整理一下SHA 256的实现步骤 1 定义8个32位常量 h0 0x6a09e667 h1 0xbb67ae85 h2 0x3c6ef372 h3 0xa54ff53a h4 0x510e527f h5 0x9b05688c h6 0x1f
  • 通过Java理解Kruskal算法

    今天 我将解析一段Java代码 该代码实现了Kruskal算法 用于在连通的无向图中找到最小生成树 首先 我们来了解一些关键组件 1 DisjointSet 不相交集 这是Kruskal算法中的辅助数据结构 用于管理不相交集的集合 Find
  • msvcr100.dll丢失的解决方法?三招解决msvcr100.dll丢失问题

    最近我遇到了一个电脑问题 就是在运行某个软件时提示缺少msvcr100 dll文件 起初我并不知道这个文件是什么 也不知道它的作用 但通过一番搜索和了解 我对这个问题有了更深的理解 并且也得到了解决的办法 解决方法一 确保你的两台电脑都是相
  • requests_模拟搜狗翻译

    01笔记 在搜狗翻译的url中 请求的方法是Post 所以我们需要通过requests post方法来请求数据 接着url的请求参数是一个字典 所以我们需要修改该字典参数的搜索关键词 且其他参数需复制请求 否则请求不到数据 最后该url返回
  • PyTorch 2.0来了!100%向后兼容,一行代码训练提速76%

    编辑 机器之心 点击下方卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 全栈算法 技术交流群 PyTorch 官方 我们这次的新特性太好用了 所以就直接叫 2 0 了 前段时间 PyTorch 团队在官
  • Altium Designer-Net has no driving source警告消除的方法

    1 其实这个警告原因是 你图中有一个器件的管脚有属性 如I O 并且这个管脚设定了驱动源 你先从元件库中 找到这个管脚 把管脚的属性 改成下面图片 的这个样子 就好了 2 下面这种方法 只是快速 逃避警告 也是可以通过编译的 在进行原理图编
  • 爬取豆瓣电影数据并进行分析可视化

    学习爬虫爬取豆瓣电影数据并进行分析 整体流程如下 1 爬取豆瓣电影数据 2 读取豆瓣电影数据 3 统计各个电影的评论数 4 读取某个电影的全部评论内容 5 获取某个电影的关键词并生成词云图 6 对电影数据的关键词和评分进行辩证分析并生成热力