最近《寻梦环游记》刷爆朋友圈,一心只想学习的我,并没有去看,但是还是很想知道这个电影是讲的什么。怎么办呢,所谓把大象放进冰箱分三步。要知道这个电影讲什么也可以分三步:
1.登陆豆瓣
2.抓取所有短评
3.利用词云看看大家的评论集中在哪些点,就能大概了解电影类型,主题,大致内容。
一、模拟登陆豆瓣
因为豆瓣有反爬虫机制,不登录只能爬到第10页,无法获取更多的内容(练模拟登陆的本人,被豆瓣锁了两个号),本文用的post保单的方法进行登陆。
#by:大熊(xavier9410@163.com)
import requests
from lxml import etree
from PIL import Image
from io import BytesIO
import random
import pandas as pd
import time
import sys
reload(sys)
sys.setdefaultencoding('utf8')
# 获取验证码登陆
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) '
'AppleWebKit/537.36 (KHTML, like Gecko)'
'Chrome/62.0.3202.94 Safari/537.36'}
session = requests.session()
login_request = session.get('https://www.douban.com/login', headers=headers)
selector = etree.HTML(login_request.content)
post_data = {'source': 'movie', # 填写表单
'redir': 'https://movie.douban.com/subject/20495023/',
'form_email': 'chengyx@hhu.edu.cn',
'form_password': '3594633abc',
'login': '登录'}
captcha_img_url = selector.xpath('//img[@id="captcha_image"]/@src') # 获取验证码url
print captcha_img_url
try:
if captcha_img_url != None:
pic_request = requests.get(captcha_img_url[0])
img = Image.open(BytesIO(pic_request.content)) # 打开验证码图片
print '请输入你看到的字母:'
img.show()
string = raw_input('请输入验证码:')
post_data['captcha-solution'] = string
captcha_id = selector.xpath(
'//input[@name="captcha-id"]/@value') # 获取captcha_id
post_data['captcha-id'] = captcha_id
print(post_data)
except:
pass
r = session.post('https://accounts.douban.com/login',
data=post_data) # 将表单信息post进行登陆
with open('logfile.log', 'w') as logfile:
logfile.write(r.text)
except:
pass
二、爬取短评内容
本来是抱着爬9万条评论的心做的,结果每次爬到25页就不能爬了,纠结了两天,改链接改来改去都不行,后来发现豆瓣现在短评只显示到25页,后面就没有了。豆瓣你狠!
r = session.post('https://accounts.douban.com/login',
data=post_data) # 用session保持登陆状态
with open('logfile.log', 'w') as logfile:
logfile.write(r.text)
# 获取内容
page = 0
while True:
try:
username = [] # 用户姓名
star_ratings = [] # 评级
votecount = [] # 认为评论有用的人数
comments = [] # 短评内容
seetimes = [] # 评论时间
if page==0:
url='https://movie.douban.com/subject/20495023/comments?start=p'
else:
pass
r = session.get(url)
html = r.text
# 解析具体内容
selector = etree.HTML(html) # 解析所有页面的源码
contents = selector.xpath('//div[@class="comment"]')
nextp=selector.xpath('//div[@id="paginator"]/a/@href')
if len(nextp)==1:
nextpage=nextp[0] #首页只有表示“后页”的一个href
elif len(nextp)==2:
nextpage="?default" #末页有表示“首页”和“前页”的两个href
else:
nextpage=nextp[2] #中间页有表示“首页”、“前页”、“末页”的三个href
for content in contents:
user = content.xpath('.//h3/span[2]/a/text()')[0] # 用户名
print user
words = content.xpath('.//p/text()')[0].strip()
star_rating = content.xpath('.//h3/span[2]/span[2]/@class')[0][7:8]
vote = content.xpath('.//h3/span[1]/span/text()')[0]
seetime = content.xpath('//h3/span[2]/span[3]/text()')[0]
username.append(user)
comments.append(words)
star_ratings.append(star_rating)
votecount.append(vote)
seetimes.append(seetime)
shortcom = {"username": username, "star_ratings": star_ratings,
"votecount": votecount, "comment": comments,
"seetimes": seetimes}
houses_df = pd.DataFrame(shortcom)
page += 1
if page == 1:
houses_df.to_csv('dbmvtest.csv', encoding="utf8") # 写入第一页
else:
houses_df.to_csv('dbmvtest.csv', encoding="utf8", mode='a',
header=False) # 追加下一页
print '.................正在抓取第' + '%d' % (page) + '页'
url='https://movie.douban.com/subject/20495023/comments'+nextpage
time.sleep(random.uniform(1, 3)) # 间隔1-3秒抓一
于是,抓到如下评论:
三、生成词云
本来用datafram生成一些表格看上映期间每天评论数的表格,和做情感分析,但是数据有限就只做了词云。因为豆瓣短评是以评论热度(认为此评论有用的人数)来排序显示的,前25页评论基本能反映观众对电影的解读。
#coding=utf-8
from scipy.misc import imread
from os import path
import jieba
import matplotlib.pyplot as plt
from wordcloud import WordCloud, STOPWORDS,ImageColorGenerator
import csv
#从CVS中读取短评所在列的内容
def readcontent(csv):
with open('dbmvtest.csv','rb')as csvfile:
reader=csv.DictReader(csvfile)
column=[row['comment']for row in reader] #加载表头为"comment"的列,即短评内容
content="".join(column)
return content
def creatcloud(mvcontent):
wordafterjieba=jieba.cut(mvcontent,cut_all=False) #分词
wordsplit="".join(wordafterjieba)
BGI=imread('./coco.jpg')
print "加载图片成功"
#设置词云样式
wc=WordCloud(width=1024,
height=768,
background_color="white", #设置背景颜色
mask=BGI,
font_path='SourceHanSansCN-Normal.otf', #设置字体
max_words=300
max_font_size=400, #设置字体最大值
random_state=50)
wc.generate_from_text(wordsplit)
img_colors=ImageColorGenerator(BGI)
wc.recolor(color_func=img_colors) #设置字体颜色为背景图片颜色
plt.imshow(wc)
plt.axis("off")
plt.show()
return wc
if __name__ == '__main__':
comment=readcontent(csv)
pic=creatcloud(comment)
d = path.dirname(__file__) #获取当前文件路径
pic.to_file(path.join(d,"dreamcloud.jpg"))
print "..........已生成词云.........."
最终生成了如下词云:
从词语中能看到好几部动画片的名称《头脑特工队》、《僵尸新娘》、《飞屋环游记》等等,里面我就看过僵尸新娘,哈哈,不过能和僵尸新娘相提并论,这部电影很ok。“梦想”、“家庭”、“墨西哥亡灵节”、“remember”、“死亡并不可怕”都是被提及很多的词,应该是电影的主题。