软通大学企业博客

北京软通动力教育科技有限公司

使用Python爬虫获取豆瓣影评,并用词云显示

使用Python爬虫获取豆瓣影评,并用词云显示

Python语言流行到现在,目前最受开发者喜爱的功能莫过于它的爬虫功能,以至于很多人以为Python的英语发音也是“爬虫”,其实它是读作“啪善”[‘paɪθɑn] 。而爬取网络信息,只是它的一个功能,它同时也涉及其它领域,比如说现在比较流行的人工智能、科学计算、网络开发等。而在爬取网络信息这个任务中,常用的是使用urllib库和bs4库打开网站并解析页面信息并分析,本文所要介绍的爬取豆瓣影评也是使用这两个库。另外,为了能形象的展示爬取的结果,在项目最后,使用了WordCloud词云对爬取的关键字进行了显示,在显示前,用jieba分词工具提取了影评中常用的关键字。

项目开始前,要做一些必要的准备,比如Python环境的安装,库的下载等。本项目是在Windows下运行,所以首先要在Windows下安装Python。由于这个过程比较简单,在本文中就不做介绍。Python安装完后,需要安装本项目所用的第三方库。如果python的基本环境安装完了,第三方库安装也很简单,直接使用pip工具即可下载安装(前提是机器必须能够连网):

安装第三方库

由于本机已经在写文章之前安装过库,所以系统提示已经存在;如果没有安装过,运行“pip install xxx”的命令时可以看到下载和安装的过程及进度。其它所需的第三方库都可以使用此方法下载。环境和库准备完成后,就可以进行代码的实现了。

本项目的主要实现过程分为两个阶段,第一部分先获取豆瓣上某个电影的影评信息;第二部分通过jieba分词和WordCloud把结果用词云的方式展示出来。

Step:获取豆瓣影评,放到文本文件中:

使用python爬取网络信息,最基本的概念就是用urllib等工具打开网站,获取网页信息,然后对所需的信息进行解析并提取感兴趣的内容。在这个过程中,难点在于解析网页内容并获取感兴趣的内容。由于不同的网站页面结构是不一样的,所以需要针对特定的网页结构实现特定的解析代码。在代码实现之前,需要分析网页的内容。
分析网页结构

从上面的图片可以看出,爬取之前首先要获取网页的url,通过url才能获得特定的网页内容用于解析。幸运的是,豆瓣上对于特定影片的影评的获取地址格式是固定的,比如:
https://movie.douban.com/subject/4920389/comments?start=1&limit=20&sort=new_score&status=P
这个网址中,https://movie.douban.com/subject/是固定的,后面的“26787574”是影片的ID,是豆瓣给定的编号,它对于特定的影片也是固定的,比如这个网址中的ID对应的就是最近得分比较高的《头号玩家》,我们可以通过打开特定的页面提前获得这个ID;对于网址后的start参数,很明显能分析出,它是对应的影评的编号是从第一条影评开始,limit表示一页显示的影评条数,这是默认值,不可修改;sort表示按照最新的热门评论排序;status表示显示看过这个电影的网友的评论,没有看过这个电影的网友写的评论就不显示了。

网址分析完成后,就要开始解析网页结构了,我们需要通过分析网页结构,得到页面上图片中红色方框标出的影评内容,忽略所有其它内容。这个过程需要一定的html的知识。

我们首先借助chrome浏览器的开发者工具功能分析一下这个网页的html代码,然后找到影评所对应的项:
解析网页内容
通过分析页面html代码,可以知道,评论内容在comment目录下对应的’p’字段中,所以我们后面解析的代码就要提取这部分的内容。

由于每部电影可能会有很多页的影评,我们不打算提取所有内容,只抓取最新的200条就可以,所以在处理网址的时候可以做循环处理,一次抓取20条,抓10页就可以。

每条影评的内容得到后,我们把它放到一个特定的文本文件中,比如content.txt中,便于后面使用jieba分词并用词云显示。

Step:从文本文件读取内容,分词后并显示

内容抓取后,剩下的就是解析并显示了。这部分代码对任何文本文件都是适用的。比如,我们不光可以分析影评,也可以分析歌词,新闻关键字等。

Jieba分词库的功能非常强大,其中常用的就是它的cut函数,它可以把给定的文本中整句或整段的文章,按照中文常用的单词进行切分,便于后续对关键字进行分析。另外WordCloud也是一个很棒的功能,能够以好看的样式显示出词云的形状,并根据每个词出现的频率,以不同的文字大小显示。词云图轮廓有’circle’, ‘cardioid’, ‘diamond’, triangle-forward’, ‘triangle’, ‘pentagon’, ‘star’可选,分别代表‘圆形’,‘心形’,‘菱形’,‘向前三角形’,‘向上三角形’,‘五边形’,‘星形’。

在获取到每个词的词频后,显示词云之前,有一个对词频进行排序的过程。由于关键词和词频是由字典组成的,所以排序时用到了sorted函数,把关键字按照词频由大到小进行排列。具体的实现过程,请参考下面的代码:

#-----------------------------------------------------------------------------
# Name:        douban.py
# Purpose:     读取豆瓣上关于某个电影的评论,并用词云显示出来
#
# Author:      ISS-XiangjianChen
#
# Created:     16/04/2018
# Copyright:   (c) ISS 2018
#-------------------------------------------------------------------------------

import urllib.request
import jieba
from bs4 import BeautifulSoup as bs
import re
from pyecharts import WordCloud

#获取评论放一个文本文件中
#名          ID
#阿甘正传   1292720
#无问西东   6874741
#红海行动   26861685
#捉妖记2    26575103
def GetTxt(start):
    eachCommentList = []
    requrl = 'https://movie.douban.com/subject/26787574/comments?start='+ \
              str(start) + '&limit=20&sort=new_score&status=P'
    resp = urllib.request.urlopen(requrl)
    html_data = resp.read().decode('utf-8')
    soup = bs(html_data, 'html.parser')
    comment_div_lits = soup.find_all('div', class_='comment')
    for item in comment_div_lits:
        if item.find_all('p')[0].string is not None:
            eachCommentList.append(item.find_all('p')[0].string)
    #写到文本文件中
    f = open('content.txt','a',encoding='utf-8')
    for comment in eachCommentList:
        f.write(comment)
    f.close()

#从文本文件中生成词云
def Generator():
    with open('content.txt', 'r', encoding='utf-8') as f:
        text_body = f.read()
    f.close()

    #使用jieba进行分词
    words_lst = jieba.cut(text_body.replace('\n', '').replace(' ', ''))
    #统计词频
    total = {}
    for i in words_lst:
        total[i] = total.get(i, 0) + 1

    #按词频进行排序,只选取包含两个或两个以上字的词
    data = dict(sorted({k: v for k, v in total.items() if len(k) >= 2}.items(),\
                        key=lambda x: x[1], reverse=True)[:200])

    name = data.keys()
    value = [i for i in data.values()]#获取列表对象

    #构造一个词云对象,把所有的词放进去
    word_cloud = WordCloud(width=1600, height=1024)
    #pentagon表示用五角星的形状显示词云
    word_cloud.add("", name, value, word_size_range=[20, 100], shape='triangle')
    #把词云显示到一个html网页中
    word_cloud.render('content.html')


def main():
    for i in range(1,201,20):
        GetTxt(i)
    Generator()

if __name__ == '__main__':
    main()
    最终的词云显示效果如下图:

最终效果

Created by 陈祥俭
这里写图片描述

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/isscollege/article/details/79970346
文章标签: python 爬虫 豆瓣
个人分类: python-爬虫实战
上一篇springMvc配置xml使ResponseBody返回Json
下一篇Angular知识图谱系列(二) -- 命令行工具
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭