python爬取《流浪地球》豆瓣影评与数据分析(代码片段)

Facktoo Facktoo     2022-11-30     570

关键词:

一、选题背景:

  2019年年初,《流浪地球》全国上榜。在豆瓣上,首日开分站稳8分以上,评分了之后点映的高热。微博上跟着出现吴京客串31天与6000万的热度搜。知乎上关于“评价刘慈欣如何评价刘慈欣小说改编的同名电影《流浪地球片》”的热门话题,包括导演郭帆的最高赞回答。

二、数据说明:

  本篇文章爬取了豆瓣网上《流浪地球》的部分影评,并进行数据分析和可视化处理。

三、实施过程及代码:

 1 # 爬取电影《流浪地球》的影评
 2 import requests
 3 from lxml import etree
 4 from tqdm import tqdm
 5 import time
 6 import random
 7 import pandas as pd
 8 import re
 9 
10 name_list, content_list, date_list, score_list, city_list = [], [], [], [], []
11 movie_name = ""
12 
13 def get_city(url, i):
14     time.sleep(round(random.uniform(2, 3), 2))
15     headers = 
16         \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36\'
17     cookies = \'cookie\': \'bid=Ge7txCUP3v4; ll="108303"; _vwo_uuid_v2=DB48689393ACB497681C7C540C832B546|f3d53bcb0314c9a34c861e9c724fcdec; ap_v=0,6.0; dbcl2="159607750:sijMjNWV7ek"; ck=kgmP; push_doumail_num=0; push_noty_num=0; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1549433417%2C%22https%3A%2F%2Fmovie.douban.com%2Fsubject%2F26266893%2Fcomments%3Fsort%3Dnew_score%26status%3DP%22%5D; _pk_ses.100001.8cb4=*; __lnkrntdmcvrd=-1; __yadk_uid=KqejvPo3L0HIkc2Zx7UXOJF6Vt9PpoJU; _pk_id.100001.8cb4=91514e1ada30bfa5.1549433417.1.1549433694.1549433417\'  # 2018.7.25修改,
18     res = requests.get(url, cookies=cookies, headers=headers)
19     if (res.status_code == 200):
20         print("\\n成功获取第个用户城市信息!".format(i))
21     else:
22         print("\\n第个用户城市信息获取失败".format(i))
23     pattern = re.compile(\'<div class="user-info">.*?<a href=".*?">(.*?)</a>\', re.S)
24     item = re.findall(pattern, res.text)  # list类型
25     return (item[0])  # 只有一个元素,所以直接返回

(1)网页分析

获取对象:

  • 评论用户

  • 评论内容

  • 评分

  • 评论日期

  • 用户所在城市

 

(2)数据获取与存储

1、获取饼干

本人用的是Chrome浏览器,Ctrl+F12进入开发者工具页面。F5刷新一下出现数据,找到cookies、headers。

2、加载headers、cookies,并用requests库获取信息

 1 def get_content(id, page):
 2     headers = 
 3         \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36\'
 4     cookies = \'cookie\': \'                  此处填入自己的cookies,否则不能正常爬取                  \'
 5     url = "https://movie.douban.com/subject/" + str(id) + "/comments?start=" + str(page * 10) + "&limit=20&sort=new_score&status=P"
 6     res = requests.get(url, headers=headers, cookies=cookies)
 7 
 8     pattern = re.compile(\'<div id="wrapper">.*?<div id="content">.*?<h1>(.*?) 短评</h1>\', re.S)
 9     global movie_name
10     movie_name = re.findall(pattern, res.text)[0]  # list类型
11 
12     res.encoding = "utf-8"
13     if (res.status_code == 200):
14         print("\\n第页短评爬取成功!".format(page + 1))
15         print(url)
16     else:
17         print("\\n第页爬取失败!".format(page + 1))
18 
19     with open(\'html.html\', \'w\', encoding=\'utf-8\') as f:
20         f.write(res.text)
21         f.close()
22     x = etree.HTML(res.text)

3、解析需求数据

  此处我用xpath解析。发现有的用户虽然有评论,但没有给评分,所以分数和日期这两个的xpath位置是会变动的。因此需要加判断,如果发现分数里面解析日期,证明该条评论没有给出评分。

 1     for i in range(1, 21):   # 每页20个评论用户
 2         name = x.xpath(\'//*[@id="comments"]/div[]/div[2]/h3/span[2]/a/text()\'.format(i))
 3         # 下面是个大bug,如果有的人没有评分,但是评论了,那么score解析出来是日期,而日期所在位置spen[3]为空
 4         score = x.xpath(\'//*[@id="comments"]/div[]/div[2]/h3/span[2]/span[2]/@title\'.format(i))
 5         date = x.xpath(\'//*[@id="comments"]/div[]/div[2]/h3/span[2]/span[3]/@title\'.format(i))
 6         m = \'\\d4-\\d2-\\d2\'
 7         try:
 8             match = re.compile(m).match(score[0])
 9         except IndexError:
10             break
11         if match is not None:
12             date = score
13             score = ["null"]
14         else:
15             pass
16         content = x.xpath(\'//*[@id="comments"]/div[]/div[2]/p/span/text()\'.format(i))
17         id = x.xpath(\'//*[@id="comments"]/div[]/div[2]/h3/span[2]/a/@href\'.format(i))
18         try:
19             city = get_city(id[0], i)  # 调用评论用户的ID城市信息获取
20         except IndexError:
21             city = " "
22         name_list.append(str(name[0]))
23         score_list.append(str(score[0]).strip(\'[]\\\'\'))  # bug 有些人评论了文字,但是没有给出评分
24         date_list.append(str(date[0]).strip(\'[\\\'\').split(\' \')[0])
25         content_list.append(str(content[0]).strip())
26         city_list.append(city)

4、获取电影名称

1 pattern = re.compile(\'<div id="wrapper">.*?<div id="content">.*?<h1>(.*?) 短评</h1>\', re.S)
2 global movie_name
3 movie_name = re.findall(pattern, res.text)[0]  # list类型

5、数据存储

1 def main(ID, pages):
2     global movie_name
3     for i in tqdm(range(0, pages)):  # 豆瓣只开放500条评论
4         get_content(ID, i)  # 第一个参数是豆瓣电影对应的id序号,第二个参数是想爬取的评论页数
5         time.sleep(round(random.uniform(3, 5), 2))
6     infos = \'name\': name_list, \'city\': city_list, \'content\': content_list, \'score\': score_list, \'date\': date_list
7     data = pd.DataFrame(infos, columns=[\'name\', \'city\', \'content\', \'score\', \'date\'])
8     data.to_csv(movie_name + ".csv")  # 存储名为  电影名.csv

(3)、数据分析与可视化

1、获取饼干

 1 # 数据分析可视化
 2 import os
 3 import pandas as pd
 4 from pandas import DataFrame
 5 import re
 6 from pyecharts import Line, Geo, Bar, Pie, Page, ThemeRiver
 7 from snownlp import SnowNLP
 8 import jieba
 9 import matplotlib.pyplot as plt
10 from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
11 
12 fth = open(\'pyecharts_citys_supported.txt\', \'r\', encoding=\'utf-8\').read() # pyecharts支持城市列表

  城市信息过滤器中文字

1 # 过滤字符串只保留中文
2 def translate(str):
3     line = str.strip()
4     p2 = re.compile(\'[^\\u4e00-\\u9fa5]\')   # 中文的编码范围是:\\u4e00到\\u9fa5
5     zh = " ".join(p2.split(line)).strip()
6     zh = ",".join(zh.split())
7     str = re.sub("[A-Za-z0-9!!,%\\[\\],。]", "", zh)
8     return str

  匹配pyecharts支持的城市列表

 1 # 下面是按照列属性读取的
 2 def count_sentiment(csv_file):
 3     path = os.path.abspath(os.curdir)
 4     csv_file = path+ "\\\\" + csv_file + ".csv"
 5     csv_file = csv_file.replace(\'\\\\\', \'\\\\\\\\\')
 6     d = pd.read_csv(csv_file, engine=\'python\', encoding=\'utf-8\')
 7     motion_list = []
 8     for i in d[\'content\']:
 9         try:
10             s = round(SnowNLP(i).sentiments, 2)
11             motion_list.append(s)
12         except TypeError:
13             continue
14     result = 
15     for i in set(motion_list):
16         result[i] = motion_list.count(i)
17     return result

2、基于nownlp的情感分析

  snownlp主要进行中文分词(算法是Character-Base Generative Model)、词性可以官网的原理是TnT、3-gram 隐马)、情感分析(有介绍原理,但指定购物类的评论的准确率,其实是因为它的语料库主要是再生方面的,可以自己构建相关领域语料库,替换原来的,准确率也相当不错的)、文本分类(原理是朴素贝叶斯)、转换拼音、繁体转简体、提取文本关键词(原理是TextRank)、提取摘要(原理是TextRank)、分割句子、相似文本(原理是BM25)【摘自CSDN】。在此之前,可以先看一下官网,里面有最基础的一些命令的介绍。官网链接:https://pypi.org/project/snownlp/

  因为已知p全部是unicode编码,所以要注意数据是否为unicode编码。是unicode编码,所以不要为了去除中文文本里面含有的英文,所以不要把中文文本里面含有的英文,都转码成统一的编码格式只是调用snownlp原生语料对文本进行分析,snlp重点针对购物领域,所以是为了提高情绪分析评价的适当程度,可以采取训练语料库的方法。

 1 def draw_sentiment_pic(csv_file):
 2     attr, val = [], []
 3     info = count_sentiment(csv_file)
 4     info = sorted(info.items(), key=lambda x: x[0], reverse=False)  # dict的排序方法
 5     for each in info[:-1]:
 6         attr.append(each[0])
 7         val.append(each[1])
 8     line = Line(csv_file+":影评情感分析")
 9     line.add("", attr, val, is_smooth=True, is_more_utils=True)
10     line.render(csv_file+"_情感分析曲线图.html")

3、评论来源城市分析

  调用pyecharts的页面函数,可以在一个图像对象中创建chart,只需要对应的添加组件。

 1 def draw_citys_pic(csv_file):
 2     page = Page(csv_file+":评论城市分析")
 3     info = count_city(csv_file)
 4     geo = Geo("","小本聪原创",title_pos="center", width=1200,height=600, background_color=\'#404a59\', title_color="#fff")
 5     while True:   # 二次筛选,和pyecharts支持的城市库进行匹配,如果报错则删除该城市对应的统计
 6         try:
 7             attr, val = geo.cast(info)
 8             geo.add("", attr, val, visual_range=[0, 300], visual_text_color="#fff", is_geo_effect_show=False,
 9                     is_piecewise=True, visual_split_number=6, symbol_size=15, is_visualmap=True)
10         except ValueError as e:
11             e = str(e)
12             e = e.split("No coordinate is specified for ")[1]  # 获取不支持的城市名称
13             info.pop(e)
14         else:
15             break
16     info = sorted(info.items(), key=lambda x: x[1], reverse=False)  # list排序
17     print(info)
18     info = dict(info)   # list转dict
19     print(info)
20     attr, val = [], []
21     for key in info:
22         attr.append(key)
23         val.append(info[key])
24 
25 
26     geo1 = Geo("", "评论城市分布", title_pos="center", width=1200, height=600,
27               background_color=\'#404a59\', title_color="#fff")
28     geo1.add("", attr, val, visual_range=[0, 300], visual_text_color="#fff", is_geo_effect_show=False,
29             is_piecewise=True, visual_split_number=10, symbol_size=15, is_visualmap=True, is_more_utils=True)
30     # geo1.render(csv_file + "_城市dotmap.html")
31     page.add_chart(geo1)
32     geo2 = Geo("", "评论来源热力图",title_pos="center", width=1200,height=600, background_color=\'#404a59\', title_color="#fff",)
33     geo2.add("", attr, val, type="heatmap", is_visualmap=True, visual_range=[0, 50],visual_text_color=\'#fff\', is_more_utils=True)
34     # geo2.render(csv_file+"_城市heatmap.html")  # 取CSV文件名的前8位数
35     page.add_chart(geo2)
36     bar = Bar("", "评论来源排行", title_pos="center", width=1200, height=600 )
37     bar.add("", attr, val, is_visualmap=True, visual_range=[0, 100], visual_text_color=\'#fff\',mark_point=["average"],mark_line=["average"],
38             is_more_utils=True, is_label_show=True, is_datazoom_show=True, xaxis_rotate=45)
39     bar.render(csv_file+"_城市评论bar.html")  # 取CSV文件名的前8位数
40     page.add_chart(bar)
41     pie = Pie("", "评论来源饼图", title_pos="right", width=1200, height=600)
42     pie.add("", attr, val, radius=[20, 50], label_text_color=None, is_label_show=True, legend_orient=\'vertical\', is_more_utils=True, legend_pos=\'left\')
43     pie.render(csv_file + "_城市评论Pie.html")  # 取CSV文件名的前8位数
44     page.add_chart(pie)
45     page.render(csv_file + "_城市评论分析汇总.html")

4、电影推荐走势分析

  • 读取csv文件,以dataframe(df)形式保存

  • 遍历df行,保存到list

  • 统计相同 日期相同 评分的个数

  • 转换为df格式,设置列名

  • 按日期排序

  • 去新的每一个日期的推荐种,因此需要增加到最少的5种。

 1 def score_draw(csv_file):
 2     page = Page(csv_file+":评论等级分析")
 3     score, date, val, score_list = [], [], [], []
 4     result = 
 5     path = os.path.abspath(os.curdir)
 6     csv_file = path + "\\\\" + csv_file + ".csv"
 7     csv_file = csv_file.replace(\'\\\\\', \'\\\\\\\\\')
 8     d = pd.read_csv(csv_file, engine=\'python\', encoding=\'utf-8\')[[\'score\', \'date\']].dropna()  # 读取CSV转为dataframe格式,并丢弃评论为空的记录
 9     for indexs in d.index:  # 一种遍历df行的方法(下面还有第二种,iterrows)
10         score_list.append(tuple(d.loc[indexs].values[:])) # 目前只找到转换为tuple然后统计相同元素个数的方法
11     print("有效评分总数量为:",len(score_list), "")
12     for i in set(list(score_list)):
13         result[i] = score_list.count(i)  # dict类型
14     info = []
15     for key in result:
16         score= key[0]
17         date = key[1]
18         val = result[key]
19         info.append([score, date, val])
20     info_new = DataFrame(info)  # 将字典转换成为数据框
21     info_new.columns = [\'score\', \'date\', \'votes\']
22     info_new.sort_values(\'date\', inplace=True)    # 按日期升序排列df,便于找最早date和最晚data,方便后面插值
23     print("first df", info_new)
24     # 以下代码用于插入空缺的数据,每个日期的评分类型应该有5中,依次遍历判断是否存在,若不存在则往新的df中插入新数值
25     mark = 0
26     creat_df = pd.DataFrame(columns = [\'score\', \'date\', \'votes\']) # 创建空的dataframe
27     for i in list(info_new[\'date\']):
28         location = info_new[(info_new.date==i)&(info_new.score=="力荐")].index.tolist()
29         if location == []:
30             creat_df.loc[mark] = ["力荐", i, 0]
31             mark += 1
32         location = info_new[(info_new.date==i)&(info_new.score=="推荐")].index.tolist()
33         if location == []:
34             creat_df.loc[mark] = ["推荐", i, 0]
35             mark += 1
36         location = info_new[(info_new.date==i)&(info_new.score=="还行")].index.tolist()
37         if location == []:
38             creat_df.loc[mark] = ["还行", i, 0]
39             mark += 1
40         location = info_new[(info_new.date==i)&(info_new.score=="较差")].index.tolist()
41         if location == []:
42             creat_df.loc[mark] = ["较差", i, 0]
43             mark += 1
44         location = info_new[(info_new.date==i)&(info_new.score=="很差")].index.tolist()
45         if location == []:
46             creat_df.loc[mark] = ["很差", i, 0]
47             mark += 1
48     info_new = info_new.append(creat_df.drop_duplicates(), ignore_index=True)
49     score_list = []
50     info_new.sort_values(\'date\', inplace=True)    # 按日期升序排列df,便于找最早date和最晚data,方便后面插值
51     print(info_new)
52     for index, row in info_new.iterrows():   # 第二种遍历df的方法
53         score_list.append([row[\'date\'], row[\'votes\'], row[\'score\']])
54     tr = ThemeRiver()
55     tr.add([\'力荐\', \'推荐\', \'还行\', \'较差\', \'很差\'], score_list, is_label_show=True, is_more_utils=True)
56     page.add_chart(tr)
57 
58     attr, v1, v2, v3, v4, v5 = [], [], [], [], [], []
59     attr = list(sorted(set(info_new[\'date\'])))
60     bar = Bar()
61     for i in attr:
62         v1.append(int(info_new[(info_new[\'date\']==i)&(info_new[\'score\']=="力荐查看详情  

爬取豆瓣网影评数据并进行简单分析与展示(代码片段)

编译在线环境:https://www.kesci.com一. 内容1、使用Python爬虫爬取豆瓣网某一部电影的评论信息;2、从评论信息中统计各级星评的数量占比1fromurllibimportrequest2frombs4importBeautifulSoup3importmatplotlibasmpl4importmatplotlib.pyplotasplt5importpandasas... 查看详情

利用python带领你爬取流浪地球评论,并写入数据库

...的事情,要有个相互监督的伙伴,工作需要学习python或者有兴趣学习python的伙伴可以私信回复小编“学习”获取资料,一起学习创建数据库开始抓取网页分析文档具体内容写入数据释放流运行结果 查看详情

r从网页抓取到文本分析全教程:影评的获取与分析(代码片段)

...的网页文本数据做后续分析的实战案例。我将以网友对《流浪地球》豆瓣影评文本的获取与分析全过程,作为演示案例。文本挖掘的本质是,通过自然语言处理(NaturalLanguageProcessing,NLP)和分析方法,将文本转化为数据进行分... 查看详情

python爬虫爬取豆瓣影评返回403怎么办,代理ip和cookie都设置了

如果只是爬取影评的话,没必要登录。返回的304是你的cookie用的是旧的。去掉cookie,正常抓取就可以了。参考技术A使用618动态爬虫就可以,电信ADSL每次拨号就会更换一个IP,可以按这个思路去做。可以根据爬虫对象的限制策略... 查看详情

爬取豆瓣中的战狼影评,保存在csv

下面是源代码,第一把爬取的数据保存在CSV,保存的过程中遇到钟种坑,不过还好弄好了,写入csv是要特别注意数据流写入的编码格式,window下所有文件默认都是gbk编码的,所以如果你的网页数据编码格式是utf-8的,那你就要注... 查看详情

python分析44130条用户观影数据,挖掘用户与电影之间的隐藏信息!

参考技术A很多电影也上映,看电影前很多人都喜欢去『豆瓣』看影评,所以我爬取44130条『豆瓣』的用户观影数据,分析用户之间的关系,电影之间的联系,以及用户和电影之间的隐藏关系。在****『豆瓣』****平台爬取用户观影... 查看详情

10分钟用python爬取最近很火的复联4影评(代码片段)

欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可!《复仇者联盟4:终局之战》已经上映快三个星期了,全球票房破24亿美元,国内票房破40亿人民币。虽然现在热度逐渐下降,但是我们还是恬不知耻地来蹭一蹭热... 查看详情

团队-爬取豆瓣电影top250-需求分析

团队-爬取豆瓣电影TOP250-需求分析需求:爬取豆瓣电影TOP250*向用户展示电影的排名,分数,名字,简介,导演,演员,前10条影评信息,链接信息实现思路:分析豆瓣电影TOP250的url规则,编写模块获取相关url获取全部相关页面的html代码分析html... 查看详情

团队-爬取豆瓣电影top250-需求分析

需求:爬取豆瓣电影TOP250*向用户展示电影的排名,分数,名字,简介,导演,演员,前10条影评信息,链接信息 实现思路:分析豆瓣电影TOP250的url规则,编写模块获取相关url获取全部相关页面的html代码分析html中有关"排名,分数,名字,简介,... 查看详情

r从网页抓取到文本分析全教程:影评的获取与分析(代码片段)

...的网页文本数据做后续分析的实战案例。我将以网友对《流浪地球》豆瓣影评文本的获取与分析全过程,作为演示案例。文本挖掘的本质是,通过自然语言处理(NaturalLanguageProcessing,NLP)和分析方法,将文本转化为数据进行分... 查看详情

.利用python获得豆瓣电影前30部电影的中文片名,排名,导演,主演,上映时间

...打开CSDNAPPCopyright©1999-2020,CSDN.NET,AllRightsReserved打开APPpython网络爬虫1.2获取豆瓣TOP250电影的中英文名、港台名、导演、上映年份、电影分类以及评分,将数据存入文档。原创2021-07-1901:03:152点赞zynaln码龄8年关注题目:获取豆瓣TOP... 查看详情

豆瓣书籍数据爬取与分析(代码片段)

...从那个时候其就对出版社综合实力很感兴趣,想通过具体数据分析各个出版社的出版质量,另外借此也可以熟悉大数据生态和相关操作。豆瓣上的书籍数据刚好可以满足需求,所以有了思路:1.用python编写爬虫,爬取豆瓣上的书... 查看详情

「长津湖」为什么这么火爆?用python分析了5w+影评(代码片段)

要说十一档最热门的电影,那肯定是长津湖了,在十一档电影中评分排名第一。并且刚刚上映两天,票房就已经突破了六亿,破了十一项记录!本文通过爬取《长津湖》豆瓣短评,进行数据可视化分析后&#x... 查看详情

影评推荐系统

...采用爬虫知识,使用scrapy库从bing搜索引擎采取和抽取1、爬取数据必应(英语:Bing,台港称Bing)是一款由微软公司推出的网络搜索引擎。  简短几十行代码之后你已经能够开始抓取一部电影的全部短评和评分了。在这之... 查看详情

python爬虫——刚学会爬虫,第一次实践就爬取了《长津湖》影评数据(代码片段)

思路:数据采集清洗入库分析处理1.数据采集接口地址https://m.maoyan.com/mmdb/comments/movie/257706.json?_v_=yes&offset=15&startTime=解析地址:257706代表电影ID长津湖offset=15代表:每次加载多少条数据15条start 查看详情

python爬虫——刚学会爬虫,第一次实践就爬取了《长津湖》影评数据(代码片段)

思路:数据采集清洗入库分析处理1.数据采集接口地址https://m.maoyan.com/mmdb/comments/movie/257706.json?_v_=yes&offset=15&startTime=解析地址:257706代表电影ID长津湖offset=15代表:每次加载多少条数据15条start 查看详情

python爬虫简单实例——豆瓣电影评论数据的爬取(代码片段)

 一、前言豆瓣网是一家基于用户对于图书、电影和音乐兴趣而搭建的社交网站,由杨勃创立于2005年。豆瓣网推崇算法,根据用户对音乐、书、电影等进行的操作,自动给出同类趣味和友邻推荐。基于记录和分享而生... 查看详情