1. 背景与挖掘目标
  2. 获取豆瓣评论数据
  3. 分析好评与差评的关键信息
  4. 分析评论数量及评分与时间的关系
  5. 分析评论者的城市分布情况

1. 背景与挖掘目标

豆瓣(douban)是一个社区网站。网站由杨勃(网名“阿北”) 创立于2005年3月6日。该网站以书影音起家,提供关于书籍、电影、音乐等作品的信息,无论描述还是评论都由用户提供(User-generated content,UGC),是Web 2.0网站中具有特色的一个网站。
网站还提供书影音推荐、线下同城活动、小组话题交流等多种服务功能,它更像一个集品味系统(读书、电影、音乐)、表达系统(我读、我看、我听)和交流系统(同城、小组、友邻)于一体的创新网络服务,一直致力于帮助都市人群发现生活中有用的事物。

2019年2月5日电影《流浪地球》正式在中国内地上映。根据刘慈欣同名小说改编,影片故事设定在2075年,讲述了太阳即将毁灭,已经不适合人类生存,而面对绝境,人类将开启“流浪地球”计划,试图带着地球一起逃离太阳系,寻找人类新家园的故事。
《流浪地球》举行首映的时候,口碑好得出奇,所有去看片的业界大咖都发出了同样赞叹。文化学者戴锦华说:“中国科幻电影元年开启了。”导演徐峥则说,“里程碑式的电影,绝对是世界级别的。
可是公映之后,《流浪地球》的豆瓣评分却从8.4一路跌到了7.9。影片页面排在第一位的,是一篇一星影评《流浪地球,不及格》。文末有2.8万人点了“有用”,3.6万人点了“没用”。
关于《流浪地球》的观影评价,已经变成了一场逐渐失控的舆论混战,如“枪稿”作者灰狼所说,“关于它的舆论,已经演化成‘政治正确、水军横行、自来水灭差评、道德绑架、战狼精神。’”

挖掘目标:

  1. 获取豆瓣评论数据
  2. 分析好评与差评的关键信息
  3. 分析评论数量及评分与时间的关系
  4. 分析评论者的城市分布情况

2. 获取豆瓣评论数据

目标网址:https://movie.douban.com/subject/26266893/comments?status=P

数据爬取 selenium
短评解析 XPath
数据转化 DataFrame
翻页 selenium

获取首页数据

通过selenium和chromedriver获取数据

from selenium import webdriver
driver = webdriver.Chrome()url = 'https://movie.douban.com/subject/26266893/comments?status=P'
driver.get(url)

获取用户名

通过driver.page_source获取网页源码
我们使用Xpath解析网页
通过下列代码获取names并命名

names = dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/a/text()')

获取评价打分

通过谷歌开发者工具可以看到,class的属性决定评星。allstar10是一星,allstar50是五星。所以我们想要获取评价就要获取class的属性

同理:

dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/span[2]/@class')

然而发现结果是:

显然,这其中有未打分的(comment-time),要对这种进行筛选。

获取评分时间

通过谷歌开发者工具发现,时间是在span的title属性里面

times = dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/span[3]/@title')

获取短评内容

messages = dom.xpath('//div[@class="comment-item"]//div[@class="comment"]/p/span[@class="short"]/text()')

获取赞同量

votes = dom.xpath('//div[@class="comment-item"]//div[@class="comment"]/h3/span[@class="comment-vote"]/span[@class="votes"]/text()') # 赞同量

获取用户主页网

user_url = names = dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/a/@href') # 用户主页网址

一直到上面这,都爬的好好的,然后当我想用request进入某个主页网址的时候,遇到了418反爬

这里我选择的是用cookie。 登录获取一下cookies ,然后转换成字典(因为个人隐私,我删了几个数字):

cookies_str = 'bid=qKOdCLIajIs; _pk_ses.100001.4cf6=*; ap_v=0,6.0; __utma=30149280.688453215.1585988569.1585988569.1585988569.1; __utmc=30149280; __utmz=30149280.1585988569.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=223695111.1438858643.1585988569.1585988569.1585988569.1; __utmb=223695111.0.10.185988569; __utmc=223695111; __utmz=223695111.1585988569.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=30149280.1.10.1585988569; ps=y; dbcl2="214558448:XIwFTrlzX1s"; ck=I1oq; _pk_id.100001.4cf6=279739e4a763236.1585988569.1.1585989402.1585988569.; push_noty_num=0; push_doumail_num=0'
cookies = {}
# 拆分
for i in cookies_str.split(';'):key,value = i.split('=',1)cookies[key] = valuecookies

好的,加了cookie之后发现还是418,去翻了翻博客,决定加一下头文件:

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}

然后再爬,终于成功了

获取用户居住地和入会时间信息

address = dom_url.xpath('//div[@class="user-info"]/a/text()')  # 用户居住地
load_time = dom_url.xpath('//div[@class="basic-info"]//div[@class="pl"]/text()') # 用户加入时间

因为一个页面所以的评价都有一个主页,所以用for做个遍历。
同时,导入时间库,爬一次睡两秒防止反爬,部分代码:

import time
cities = [] #用户居住地址列表
load_times = [] # 用户加入时间列表
for i in user_url:web_data = requests.get(i,cookies=cookies,headers=headers)dom_url = etree.HTML(web_data.text,etree.HTMLParser(encoding='utf-8'))address = dom_url.xpath('//div[@class="basic-info"]//div[@class="user-info"]/a/text()')  # 用户居住地load_time = dom_url.xpath('//div[@class="basic-info"]//div[@class="pl"]/text()') # 用户加入时间cities.append(address)load_times.append(load_time)time.sleep(2)   # 2秒访问一次反爬

结果:

算是初步爬取成功

单页数据整理

获取到的数据要进行整理,去掉一些没用的数据,去掉缺失值,然后dataframe表格.

1. 评分数据ratings

如果没有评分,就保留一个空字符串;有评分打印评分。
先导入re模块。我们需要的是一个int型数据,使用==int()转换类型,加个[0]==来获取引号里面的值,,就有:

import re
["" if 'rating' not in i else int(re.findall('\d{2}', i)[0]) for i in ratings]  # 评分数据整理
2. load_times

我们需要的是后面那个元素的日期.
可以使用strip将前后的元素剔除,如果没有加入时间使用”“代替,不需要最后两个字,所以加一个==[:-2]==

load_times = ["" if i==[] else i[1].strip()[:-2] for i in load_times] # 入会时间整理
3. cities

我们需要放在一个列表中,而不是嵌套列表

cities = ["" if i==[] else i[0] for i in cities] # 居住地的数据整理

最后导入库准备建表:

import pandas as pd
data = pd.DataFrame({'用户名':names,'居住城市':cities,'加入时间':load_times,'评分':ratings,'发表时间':times,'短评正文':messages,'赞同数量':votes
})

但是报错:arrays must all be same length
查找了一番,发现times只有19个数据,其他的都20个数据.
然后改了一下times的查找方式:

times = dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/span[@class="comment-time "]/@title')# 评论发布时间

然后数据就保存好了,但是这个数据是一个页面的数据,
所以要把这个data的构建定义成一个函数:

def get_web_data(dom=None,cookies=None):names = dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/a/text()') # 用户名ratings= 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')# 评论发布时间messages = dom.xpath('//div[@class="comment-item"]//div[@class="comment"]/p/span[@class="short"]/text()') # 短评正文user_url = dom.xpath('//div[@class="comment-item"]//span[@class="comment-info"]/a/@href') # 用户主页网址votes = dom.xpath('//div[@class="comment-item"]//div[@class="comment"]/h3/span[@class="comment-vote"]/span[@class="votes"]/text()') # 赞同量cities = [] #用户居住地址列表load_times = [] # 用户加入时间列表for i in user_url:web_data = requests.get(i,cookies=cookies,headers=headers)dom_url = etree.HTML(web_data.text,etree.HTMLParser(encoding='utf-8'))address = dom_url.xpath('//div[@class="basic-info"]//div[@class="user-info"]/a/text()')  # 用户居住地load_time = dom_url.xpath('//div[@class="basic-info"]//div[@class="pl"]/text()') # 用户加入时间cities.append(address)load_times.append(load_time)time.sleep(2)   # 2秒访问一次反爬ratings = ["" if 'rating' not in i else int(re.findall('\d{2}', i)[0]) for i in ratings]  # 评分数据整理load_times = ["" if i==[] else i[1].strip()[:-2] for i in load_times] # 入会时间整理cities = ["" if i==[] else i[0] for i in cities] # 居住地的数据整理data = pd.DataFrame({'用户名':names,'居住城市':cities,'加入时间':load_times,'评分':ratings,'发表时间':times,'短评正文':messages,'赞同数量':votes})return data

接下来就是把这个函数应用于每一页,所以我们需要判断网页是否已经加载。
设置一个死循环whlie ture,除非满足到最后一页,否转一直进行单页读取,还要设置一个10秒没有加载好就报错的警示。
当当前页面最后一个评论的主页可以被点击,就默认这个页面被加载进来,否转就终止程序.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#comments > div:nth-child(20) > div.comment > h3 > span.comment-info > a')))

最后一页,可以通过selector来判断,如果没有 #paginator > a.next 则是尾页,或者有 #paginator > span 是尾页,但是首页也有,所以选择第一种。

代码:

all_data = pd.DataFrame()
wait = WebDriverWait(driver, 10)  # 10秒内能加载就操作,不能就报错
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_web_data(dom=dom,cookies=cookies)all_data = pd.concat([all_data,data],axis=0) # 按列拼接# 当后页无法点击,终止循环#paginator > span#paginator > a.nextif driver.find_element_by_css_selector('#paginator > a.next')=[]: # 判断是否还有“后页”按钮breakconfirm_bnt = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#paginator > a.next")))confirm_bnt.click() # 翻页

大概十几二十分钟,就爬取完了之后就可以保存了
all_data.to_csv('doubanliulangdiqiu.csv', index=None.encoding='GB18030')
编码方式可以自己根据需要决定。
为了爬取所有数据,还是自己登录一下比较好

爬虫实战之《流浪地球》豆瓣影评分析(一)相关推荐

  1. python 豆瓣评论数据分析_Python爬虫实战案例:豆瓣影评大数据分析报告之网页分析...

    个人希望,通过这个完整的爬虫案例(预计总共4篇短文),能够让爬虫小白学会怎么做爬虫的开发,所以在高手们看来,会有很多浅显的废话,如果觉得啰嗦,可以跳过一些内容~ 上一篇文章给大家简单介绍了Python ...

  2. python电影评论的情感分析流浪地球_《流浪地球》影评分析(一):使用Python爬取豆瓣影评...

    本文爬虫的步骤: 使用Selenium库的webdriver进行网页元素定位和信息获取: 使用BeautifulSoup库进行数据的提取: 使用Pandas库进行数据的存储. 后台回复python爬虫 ...

  3. Python 爬虫实战(1):分析豆瓣中最新电影的影评

    目标总览 主要做了三件事: 抓取网页数据 清理数据 用词云进行展示 使用的python版本是3.6 一.抓取网页数据 第一步要对网页进行访问,python中使用的是urllib库.代码如下: from ...

  4. python爬虫豆瓣电影评价_Python 爬虫实战(1):分析豆瓣中最新电影的影评

    目标总览 主要做了三件事: 抓取网页数据 清理数据 用词云进行展示 使用的python版本是3.6 一.抓取网页数据 第一步要对网页进行访问,python中使用的是urllib库.代码如下: from ...

  5. Python 爬虫实战(1):分析豆瓣中最新电影的影评并制作词云

    入门Python不久,想做个小项目练练手,碰巧最近一部国产电影<红海行动>反响不错,便萌生想法去抓取一下它最新的评论,并制作词云,来看看网页对这部电影的一些评价,接下来就是开始分析啦(分析 ...

  6. Python爬虫实践《流浪地球》豆瓣影评分析及实践心得

    一段多余的话 多余的话不多说,我想聊聊在进行实践分析中遇到的困难与心得. 下载jupyter进行分析的一些建议 我们安装juputer前,首先需要安装python,因为本人曾经上过自然语言处理课,所以 ...

  7. python爬虫实战:《星球大战》豆瓣影评分析

    #################更新于2018.2.2.彻底搞定小问题.开心############################ ''' Windows 7 系统 Sublime text 编辑 ...

  8. python爬虫影评_Python爬虫-爬取杀破狼豆瓣影评并小作分析~

    也是前几天看到一个公众号推了一篇文章,是爬取战狼的影评.今天自己也来试一下 我选择爬的是<杀破狼> image.png 然后就是打开短评页面,可以看到comment-item,这就是影评了 ...

  9. 爬虫实战2:豆瓣电影TOP250

    1.豆瓣简介 豆瓣是一个社交网站,起源于2005年,该网站以书影音起家,提供关于图书.电影.音乐唱片的推荐.评价和价格比较,以及城市独特的文化生活.本篇文章将从数据分析的角度来分析豆瓣网站.分析的维度 ...

最新文章

  1. Js 校验时间、比较时间 和转换时间格式
  2. **Git分支管理策略
  3. linux kill进程
  4. VAE【keras实现】
  5. C#基础5:字符串操作
  6. Ubuntu18.04报错:make[1]: *** No rule to make target armv4-mont.o, needed by build-msm8916/lk. Stop.
  7. InnoDB存储引擎
  8. 【电赛最全备赛资源】电赛历年赛题源码+老学长挥泪经验之谈(文章较长全网最全)+电赛论文写作模板及评分标准【19电磁炮、17板球、15风力摆、13倒立摆、94-21全国大学生电子设计竞赛历年真题】
  9. python 管理windows客户端_Python管理Windows进程
  10. maven的生命周期,插件介绍(二)
  11. MTK OTA更新方法
  12. 大数据分析实战之异构数据源联合分析业务创新实践
  13. 一种改进的天鹰优化算法和非洲秃鹫混合优化算法(Matlab代码实现)
  14. ArrayList 集合底层实现原理解析
  15. 操作系统学习——分时操作系统
  16. 玫瑰花的python程序代码_python玫瑰花代码讲解,怎样用程序编写编写玫瑰花的代码,c程序或gava或者python...
  17. [PTA]习题11-1 输出月份英文名
  18. 硬盘IDE和SATA接口
  19. C# XML 与 String 互转
  20. 操作系统作业 -期末考试选择题

热门文章

  1. tp5 童攀_ThinkPHP5第三季开发大型CMS下载|童攀ThinkPHP5第三季开发大型CMS完整版_ - 极光下载站...
  2. 金融科技大数据产品推荐:蜜蜂+蜜罐报告——基于互联网大数据的风控技术服务平台
  3. 呼叫中心系统适合哪些部门使用
  4. 用python利用正则表达式学习下载图片
  5. 百度优化指南解读-姜成
  6. igxe查询交易机器人_igxe卖家助手
  7. Revit二次开发——剪切
  8. android 部分韩国手机采用KSC5601编码保存联系人,MTK平台手机无法显示联系人姓名
  9. Python之tqdm
  10. python玩腻了?要不玩一下汉字转拼音!