目录
- 前言
- 一、抓取速7影评分析数据
- 二、抓取步骤
- 1.引入库
- 2.抓取数据
- 三、数据分析及可视化
- 词云分析
- 1.引入库
- 2.读取数据并处理
- 3.绘制词云图函数
- 4.绘制好评、差评、整体数据的词云图
- 分析评分与时间的关系
- 1.引入库
- 2.读取数据
- 3.绘制评分分数分布饼图
- 4.绘制评论随时刻的变化情况折线图
- 评分与城市的关系
- 1.引入库
- 2.读取数据
- 3.绘制评论数量最多的十个城市柱形图
- 绘制评论评分与城市关系的堆积折线图
- 总结
前言
今天又重新看了一遍速7,感触颇深啊,又是想念保罗的一天,正好最近学习了selenium,所以就心血来潮爬了一下豆瓣的影评评分做一下分析。
一、抓取速7影评分析数据
本次主要抓取发布人的用户名、所在城市、加入豆瓣的时间、已经电影的评分、发表时间、评论内容和该评论的赞同内容。注:目前豆瓣影评数据只开放600条,所以这个数据量对于真实的数据量是微不足道的,所以下面分析的结果也只是基于600条数据的分析,无准确性。
二、抓取步骤
1.引入库
代码如下(示例):
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import requests
from lxml import etree
import re
import pandas as pd
2.抓取数据
代码如下(示例):
def get_data_all(dom=None, cookies=None, headers=None):names = dom.xpath('//div[@class="comment-item "]//span[@class="comment-info"]/a/text()') # 用户名rating = dom.xpath('//div[@class="comment-item "]//span[@class="comment-info"]/span[2]/@class') # 评分times = dom.xpath('//div[@class="comment-item "]//span[@class="comment-info"]/span[@class="comment-time "]/@title') # 发表时间content = dom.xpath('//div[@class="comment-item "]//span[@class="short"]/text()') # 评论正文votes = dom.xpath('//div[@class="comment-item "]//span[@class="comment-vote"]/span/text()') # 赞同数量name_url = dom.xpath('//div[@class="comment-item "]//span[@class="comment-info"]/a/@href') # 用户超链接ratings = ['' if 'rating' not in i else int(re.findall('\d{2}', i)[0]) for i in rating] # 清洗数据,取出评分# print(votes)city = []load_times = []for url in name_url:resp = requests.get(url=url, headers=headers, cookies=cookies)cont = etree.HTML(resp.text)address = cont.xpath('//div[@id="profile"]//div[@class="user-info"]/a/text()') # 所在城市load_time = cont.xpath('//div[@id="profile"]//div[@class="user-info"]/div/text()') # 加入时间city.append(address)load_times.append(load_time)city = ['' if i == [] else i[0] for i in city] # 清洗数据,取出城市名称# print(len(city))load_times = ['' if i == [] else i[1].strip()[:-2] for i in load_times] # 清洗数据,取出加入时间# print(load_times)data = pd.DataFrame({'用户名': names,'居住城市': city,'加入时间': load_times,'评分': ratings,'发表时间': times,'短评正文': content,'赞同数量': votes})return data# print(data)driver = webdriver.Chrome() # 打开Chrmoe浏览器
driver.get('https://movie.douban.com/subject/23761370/comments?status=P') # 跳转到该网址
cookies_str = 'bid=im531sLpmVE; _pk_id.100001.4cf6=64b6690a7e485a7a.1688971997.; _pk_ses.100001.4cf6=1; ap_v=0,6.0; __utma=30149280.181421363.1688971998.1688971998.1688971998.1; __utmb=30149280.0.10.1688971998; __utmc=30149280; __utmz=30149280.1688971998.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=223695111.809893019.1688971998.1688971998.1688971998.1; __utmb=223695111.0.10.1688971998; __utmc=223695111; __utmz=223695111.1688971998.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); dbcl2="215004452:CHfoq6xKFjU"; ck=Pwq8; push_noty_num=0; push_doumail_num=0'
cookies = {}
# 对cookies处理成正确的格式
for i in cookies_str.split('; '):k, v = i.split('=', 1)cookies[k] = v
# print(cookies)
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
all_data = pd.DataFrame()
wait = WebDriverWait(driver, 5) # 设置等待加载时间
while True:# 等待页面加载可点击的对象wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#comments > div:nth-child(20) > div.comment > h3 > span.comment-info > a')))dom = etree.HTML(driver.page_source, etree.HTMLParser(encoding='utf-8'))data = get_data_all(dom=dom, cookies=cookies, headers=headers)all_data = pd.concat([all_data, data], axis=0)if driver.find_element(By.CSS_SELECTOR, '#paginator > a.next') == []: # 判定是否有后页按钮break# 等待加载后页按钮confirm_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#paginator > a.next')))confirm_btn.click() # 执行翻页工作all_data.to_csv('豆瓣影评数据.csv', index=None, encoding='utf-8-sig')
三、数据分析及可视化
词云分析
1.引入库
代码如下(示例):
import pandas as pd
import jieba
from tkinter import _flatten
import matplotlib.pyplot as plt
from wordcloud import WordCloud
2.读取数据并处理
# 读取停用词
with open('stoplist.txt', 'r', encoding='utf-8') as f:stopWords = f.read()
stopWords = ['\n', '', ' '] + stopWords.split()
data = pd.read_csv('豆瓣影评数据.csv', encoding='utf-8')
dataCut = data['短评正文'].apply(jieba.lcut) # 分词
3.绘制词云图函数
def my_word_cloud(data=None, stopWords=None, img=None):dataCut = data.apply(jieba.lcut) # 分词dataAfter = dataCut.apply(lambda x: [i for i in x if i not in stopWords]) # 去除停用词wordFre = pd.Series(_flatten(list(dataAfter))).value_counts() # 统计词频mask = plt.imread(img)wc = WordCloud(font_path='C:/Windows/Fonts/STXINGKA.TTF', mask=mask, background_color='white') # 读取字体、背景、背景颜色wc.fit_words(wordFre)plt.imshow(wc)plt.axis('off')
4.绘制好评、差评、整体数据的词云图
index_negative = data['评分'] < 30 # 差评数据的索引
index_positive = data['评分'] >= 30 # 好评数据的索引
my_word_cloud(data=data['短评正文'][index_positive], stopWords=stopWords, img='aixin.jpg') # 好评词云图
my_word_cloud(data=data['短评正文'][index_negative], stopWords=stopWords, img='aixin.jpg') # 差评词云图
my_word_cloud(data=data['短评正文'], stopWords=stopWords, img='aixin.jpg') # 整体数据词云图
分析评分与时间的关系
1.引入库
import pandas as pd
import matplotlib.pyplot as plt
2.读取数据
data = pd.read_csv('豆瓣影评数据.csv', encoding='utf-8')
3.绘制评分分数分布饼图
num = data['评分'].value_counts()
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.pie(num, autopct='%.2f %%', labels=num.index)
plt.title('《速7》豆瓣短评评分分数分布')
4.绘制评论随时刻的变化情况折线图
# data['发表时间'].apply(lambda x: x.split(' ')[1][:2])
num = pd.to_datetime(data['发表时间']).apply(lambda x: x.hour).value_counts()
num = num.sort_index()
plt.plot(range(len(num)), num)
plt.xticks(range(len(num)), num.index)
plt.title('评论随时刻的变化情况')
plt.grid()
评分与城市的关系
1.引入库
import pandas as pd
import matplotlib.pyplot as plt
2.读取数据
data = pd.read_csv('豆瓣影评数据.csv', encoding='utf-8')
3.绘制评论数量最多的十个城市柱形图
num = data['居住城市'].value_counts()[:10]
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.bar(range(10), num)
plt.xticks(range(10), num.index, rotation=45)
plt.title('评论数量最多的前十个城市')
for i, j in enumerate(num):plt.text(i, j, j, ha='center', va='bottom')
plt.show()
绘制评论评分与城市关系的堆积折线图
tmp = pd.DataFrame(0,index=data['评分'].drop_duplicates().sort_values(),columns=data['居住城市'].drop_duplicates())
for i, j in zip(data['评分'], data['居住城市']):tmp.loc[i, j] += 1
cities = num.index[:5]
tmp = tmp.loc[:, cities] # 选取评论数前五的城市数据
n, m = tmps.shape
plt.figure(figsize=(10, 5))
plt.rcParams['axes.unicode_minus'] = False
for i in range(m):plt.plot(range(n), tmps.iloc[:, i])plt.fill_between(range(n), tmps.iloc[:, i], alpha=0.5)
plt.grid()
plt.title('评论评分与城市的关系')
plt.legend(tmps.columns)
plt.xticks(range(n), tmps.index, rotation=45)
plt.show()
总结
由此次分析可知豆瓣用户发布短评的时间主要集中于晚上,20点至0点尤为突出,但随着夜深,比例也在下降,这主要与豆瓣用户的作息生活相关,同时短评一般在观看完电影后发布,所以用户可能偏向于观影结束回到家之后再进行对影片的评价行为。还可以得知北上广使用豆瓣 进行评价的记录更多一些,可能是豆瓣的人文、企业文化受众多为一线城市的民众。
本文链接:https://my.lmcjl.com/post/20483.html
展开阅读全文
4 评论