前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python小练:爬取豆瓣影评,看一部电影到底在讲什么?

Python小练:爬取豆瓣影评,看一部电影到底在讲什么?

作者头像
养码场
发布2018-08-10 15:00:39
4970
发布2018-08-10 15:00:39
举报
文章被收录于专栏:养码场养码场

每周养码场干货放送日

第 18 期

晚 20:00

?温馨提示:看到文末有彩蛋?

Python的强大,可能在于能做好玩的事情,比如知乎上有关python最火的回答,就是分享怎么用python画出世界名画的赶脚。

而今天,场主和大家分享的就是如何用 Python 制作网络爬虫,爬取豆瓣电影评论,并分析,最后制作豆瓣影评的云图。

就拿《复仇者联盟3:无限战争》这部电影为例吧。前段时间刷爆了场主的朋友圈,很多朋友不惜熬夜看首场,然后带着黑眼圈去上班。

那大家看复联3的时候,到底在看什么?什么是关键词?

根据下面分享的代码操作走,你会得到这样子一张图:

"灭霸"这个词,出现频率最高,可见反派灭霸不但得到了大家的喜欢,而且还是整部剧的焦点。

那如何用Python作出这张云图?且看下文猴哥的分享。

1、分析

先通过影评网页确定爬取的内容。我要爬取的是用户名,是否看过,五星评论值,评论时间,有用数以及评论内容。

然后确定每页评论的 url 结构。

第二页 url 地址:

第三页 url 地址:

点击查看大图

最后发现其中的规律:除了首页,后面的每页 url 地址中只有 start= 的值逐页递增,其他都是不变的。

2、数据爬取

本文爬取数据,采用的主要是 requests 库和 lxml 库中 Xpath。豆瓣网站虽然对网络爬虫算是很友好,但是还是有反爬虫机制。如果你没有设置延迟,一下子发起大量请求,会被封 IP 的。另外,如果没有登录豆瓣,只能访问前 10 页的影片。因此,发起爬取数据的 HTTP 请求要带上自己账号的 cookie。搞到 cookie 也不是难事,可以通过浏览器登录豆瓣,然后在开发者模式中获取。

我想从影评首页开始爬取,爬取入口是:https://movie.douban.com/subject/24773958/comments?status=P,然后依次获取页面中下一页的 url 地址以及需要爬取的内容,接着继续访问下一个页面的地址。

代码语言:javascript
复制
import jieba
import requests
import pandas as pd
import time
import random
from lxml import etree

def start_spider():
    base_url = 'https://movie.douban.com/subject/24773958/comments'
    start_url = base_url + '?start=0' 

    number = 1
    html = request_get(start_url) 

    while html.status_code == 200:
        # 获取下一页的 url
        selector = etree.HTML(html.text)
        nextpage = selector.xpath("//div[@id='paginator']/a[@class='next']/@href")
        nextpage = nextpage[0]
        next_url = base_url + nextpage
        # 获取评论
        comments = selector.xpath("//div[@class='comment']")
        marvelthree = []
        for each in comments:
            marvelthree.append(get_comments(each))

        data = pd.DataFrame(marvelthree)
        # 写入csv文件,'a+'是追加模式
        try:
            if number == 1:
                csv_headers = ['用户', '是否看过', '五星评分', '评论时间', '有用数', '评论内容']
                data.to_csv('./Marvel3_yingpping.csv', header=csv_headers, index=False, mode='a+', encoding='utf-8')
            else:
                data.to_csv('./Marvel3_yingpping.csv', header=False, index=False, mode='a+', encoding='utf-8')
        except UnicodeEncodeError:
            print("编码错误, 该数据无法写到文件中, 直接忽略该数据")

        data = []

        html = request_get(next_url)

我在请求头中增加随机变化的 User-agent, 增加 cookie。最后增加请求的随机等待时间,防止请求过猛被封 IP。

代码语言:javascript
复制
def request_get(url):
    '''
    使用 Session 能够跨请求保持某些参数。
    它也会在同一个 Session 实例发出的所有请求之间保持 cookie
    '''
    timeout = 3

    UserAgent_List = [
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2226.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 4.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2309.372 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2117.157 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1866.237 Safari/537.36",
    ]

    header = {
        'User-agent': random.choice(UserAgent_List),
        'Host': 'movie.douban.com',
        'Referer': 'https://movie.douban.com/subject/24773958/?from=showing',
    }

    session = requests.Session()

    cookie = {
        'cookie': "你的 cookie 值",
    }

    time.sleep(random.randint(5, 15))  
    response = requests.get(url, headers=header, cookies=cookie_nologin, timeout = 3)
    if response.status_code != 200:
        print(response.status_code)
    return response

最后一步就是数据获取:

代码语言:javascript
复制
def get_comments(eachComment):
    commentlist = []
    user = eachComment.xpath("./h3/span[@class='comment-info']/a/text()")[0]  # 用户
    watched = eachComment.xpath("./h3/span[@class='comment-info']/span[1]/text()")[0]  # 是否看过
    rating = eachComment.xpath("./h3/span[@class='comment-info']/span[2]/@title")  # 五星评分
    if len(rating) > 0:
        rating = rating[0]

    comment_time = eachComment.xpath("./h3/span[@class='comment-info']/span[3]/@title")  # 评论时间
    if len(comment_time) > 0:
        comment_time = comment_time[0]
    else:
        # 有些评论是没有五星评分, 需赋空值
        comment_time = rating
        rating = ''

    votes = eachComment.xpath("./h3/span[@class='comment-vote']/span/text()")[0]  # "有用"数
    content = eachComment.xpath("./p/text()")[0]  # 评论内容

    commentlist.append(user)
    commentlist.append(watched)
    commentlist.append(rating)
    commentlist.append(comment_time)
    commentlist.append(votes)
    commentlist.append(content.strip())
    # print(list)
    return commentlist

3、制作云图

因为爬取出来评论数据都是一大串字符串,所以需要对每个句子进行分词,然后统计每个词语出现的评论。我采用 jieba 库来进行分词,制作云图,我则是将分词后的数据丢给网站 worditout 处理。

代码语言:javascript
复制
def split_word():
    with codecs.open('Marvel3_yingpping.csv', 'r', 'utf-8') as csvfile:
        reader = csv.reader(csvfile)
        content_list = []
        for row in reader:
            try:
                content_list.append(row[5])
            except IndexError:
                pass

        content = ''.join(content_list)

        seg_list = jieba.cut(content, cut_all=False)
        result = '\n'.join(seg_list)
        print(result)

最后制作出来的云图效果是:

赶紧实战吧!

爬一爬你喜欢的电影,大家的评论是怎样的,或者在制作过程中,你也会有新的创新和发现哦~

-END-

转载声明:本文转载自「极客猴」,若喜欢,可关注~

Bonus Time

最后送上一个彩蛋?!

近半年,场主邀请了360、有赞、环球黑卡等公司的技术大咖来社群进行直播分享,接下来场主还会邀请腾讯技术工程事业群(TEG)的技术大牛来给大家分享,至于分享哪方面的内容,场主把主动权交给你们~

大家可以投票选下自己感兴趣的方向哦,人数最多的方向先分享(确定方向后会进行细化)。有其他希望了解和学习交流的方向也欢迎留言告诉我们!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 养码场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、分析
  • 2、数据爬取
  • 3、制作云图
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档