春节时,在家闲着无聊,刷了一部电视剧。


即「大江大河」,豆瓣评分8.9分。



主要讲述了1978到1992年间改革开放的大背景下。


以宋运辉、雷东宝、杨巡为代表的先行者们在变革浪潮中不断探索和突围的浮沉故事。


总的来说是一部很不错的电视剧。


恰巧那时在B站看完了吴晓波2018年的跨年演讲。


里面提到了,如果你是一个1978年的中国青年,有可能需要按下一个血手印。


故事来源于18个安徽凤阳小岗村农民的分田计划。


我觉得「大江大河」就很好的展现出了那个时代的现状。


农村改革的先行者东宝书记,知识改变命运的宋运辉,个体经营打拼的小杨巡。


都有着自己的人生,去阐述那个时代的点滴。


这也是吸引我继续观看这部电视剧的原因。


去了解那个时代的青年,他们对体制的突破以及改变自己过去的勇气。


然后结合最近「流浪地球」豆瓣电影短评的差评的现象。


我也爬取了「大江大河」的豆瓣短评。


来看看有什么猫腻没有。


在此需要感谢一下2808PROXY提供的代理服务。


如果没有他们的支持,我是肯定获取不到用户注册信息的。


因为豆瓣的反爬实在是厉害。


即使我用了稳定的代理,豆瓣还是针对我的Cookie进行了封锁。



假想我没有用代理的话,估摸着也就只有凉凉二字。



/ 01 / 网页分析


虽然评论有两万多条,但是豆瓣在登陆的情况下,也只是放出500条数据。


本次只获取全部评论以及差评评论标签页下的数据,合计约为900多条。



然后便是获取用户的注册时间。


900多个用户,900多个请求。


我相信不用代理,绝对Game Over。




/ 02 / 数据获取


评论及用户信息获取的代码如下。


import time
import requests
import proxy2808
from bs4 import BeautifulSoup

USERNAME = '用户名'
PASSWORD = '密码'

headers = {
    'Cookie''你的Cookie值',
    'User-Agent''Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}


def get_comments(page, proxy_url_secured):
    """
    评论获取
    """

    # 热门评论获取
    url = 'https://movie.douban.com/subject/26797690/comments?start=' + str(page) + '&limit=20&sort=new_score&status=P'
    # 好评获取
    # url = 'https://movie.douban.com/subject/26797690/comments?start=' + str(page) + '&limit=20&sort=new_score&status=P&percent_type=h'
    # 一般评论获取
    # url = 'https://movie.douban.com/subject/26797690/comments?start=' + str(page) + '&limit=20&sort=new_score&status=P&percent_type=m'
    # 差评获取
    # url = 'https://movie.douban.com/subject/26797690/comments?start=' + str(page) + '&limit=20&sort=new_score&status=P&percent_type=l'
    # 使用2808proxy代理
    response = requests.get(url=url, headers=headers, proxies={'http': proxy_url_secured, 'https': proxy_url_secured})
    soup = BeautifulSoup(response.text, 'html.parser')
    for div in soup.find_all(class_='comment-item'):
        time.sleep(3)
        # 评论信息
        comment_info = div.find(class_='comment-info')
        # 用户名
        user_name = comment_info.find('a').get_text()
        print(user_name)
        # 用户主页地址
        user_url = comment_info.find('a').attrs['href']
        print(user_url)
        # 获取用户注册时间,看水军必备
        registered_time = get_user(user_url, proxy_url_secured)
        print(registered_time)
        # 用户评分
        score = comment_info.find_all('span')[1].attrs['class'][0][-2:-1]
        print(score)
        # 用户评价
        eva = comment_info.find_all('span')[1].attrs['title']
        print(eva)
        # 有用数
        useful_num = div.find(class_='votes').get_text()
        print(useful_num)
        # 评价日期
        date = comment_info.find(class_='comment-time ').attrs['title'].split(' ')[0]
        print(date)
        # 评价时间
        comment_time = comment_info.find(class_='comment-time ').attrs['title'].split(' ')[1]
        print(comment_time)
        # 用户评论
        comment = div.find(class_='short').get_text().replace('\n''').strip().replace(','',').replace(' ''')
        print(comment)
        # 写入csv文件
        with open('comments_douban_l.csv''a', encoding='utf-8-sig'as f:
            f.write(user_name + ',' + user_url + ',' + registered_time + ',' + score + ',' + date + ',' + comment_time + ',' + useful_num + ',' + comment + '\n')
        f.close()


def get_user(user_url, proxy_url_secured):
    """
    获取用户注册时间
    """

    # 使用2808proxy代理
    response = requests.get(url=user_url, headers=headers, proxies={'http': proxy_url_secured, 'https': proxy_url_secured})
    soup = BeautifulSoup(response.text, 'html.parser')
    user_message = soup.find(class_='basic-info')
    # 获取用户注册时间
    try:
        user_registered = user_message.find(class_='pl')
        registered_time = user_registered.get_text().split('  ')[1].replace('加入''')
    except:
        registered_time = 'unknow'
    return registered_time


def main():
    num = 0
    for i in range(050020):
        cli = proxy2808.Client(username=USERNAME, password=PASSWORD)
        cli.release_all()
        p = cli.get_proxies(amount=1, expire_seconds=300)[0]
        proxy_url_secured = "%s://%s:%s@%s:%d" % ('http', USERNAME, PASSWORD, p['ip'], p['http_port_secured'])
        print(proxy_url_secured)
        get_comments(i, proxy_url_secured)
        num += 1


if __name__ == '__main__':
    main()


获取全部评论标签页下的数据(500条)。



红框部分为用户的注册时间。


假设我能爬取所有评论,那么水军估计要被我逮到了。


个人理解,水军就是过多的新注册用户...


然而豆瓣并没有给我们这个机会。


获取差评标签页的数据(482条)。



看看给差评的用户注册时间。


相较好评的用户注册时间,有那么点意思了。


注册时间相对都比较晚。


难不成豆瓣真有水军...


差评水军,我劝你善良。



/ 03 / 情感分析


评论的情感分析使用百度的自然语言处理。



下面利用网站做个示例。



具体的可以去官网看文档,这里只是简述一番。


通过你的百度账号登陆百度的AI开发平台,新建自然语言处理项目。


获取「API Key」及Secret Key」后。


调用情感倾向分析接口,得到情感结果。


import urllib.request
import pandas
import json
import time


def get_access_token():
    """
    获取百度AI平台的Access Token
    """

    # 使用你的API Key及Secret Key
    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=[API Key]&client_secret=[Secret Key]'
    request = urllib.request.Request(host)
    request.add_header('Content-Type''application/json; charset=UTF-8')
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    rdata = json.loads(content)
    return rdata['access_token']


def sentiment_classify(text, acc):
    """
    获取文本的感情偏向(消极 or 积极 or 中立)
    参数:
    text:str 本文
    """

    raw = {"text":"内容"}
    raw['text'] = text
    data = json.dumps(raw).encode('utf-8')
    # 情感倾向分析接口
    host = "https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify?charset=UTF-8&access_token=" + acc
    request = urllib.request.Request(url=host, data=data)
    request.add_header('Content-Type''application/json')
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    rdata = json.loads(content)
    return rdata


# 获取access_token
access_token = get_access_token()
# 差评标签
df = pandas.read_csv('comments_douban_l.csv', header=None, names=['user_name''user_url''registered_time''score''date''comment_time''useful_num''comment'])
# 好评标签
# df = pandas.read_csv('comments_douban_a.csv', header=None, names=['user_name', 'user_url', 'registered_time', 'score', 'date', 'comment_time', 'useful_num', 'comment'])

# 输出情感极性分类结果,0:负向,1:中性,2:正向
sentiments = []
for text in df['comment']:
    time.sleep(1)
    result = sentiment_classify(str(text), access_token)
    value = result['items'][0]['sentiment']
    sentiments.append(value)
    # print(result)
    print(result['items'][0]['sentiment'], text)

# 添加评分列及情感列
df['score1'] = df['score']
df['emotional'] = sentiments
# 差评标签
df.to_csv('comments_douban_ll.csv', header=0, index=False, encoding='utf-8-sig')
# 好评标签
# df.to_csv('comments_douban_al.csv', header=0, index=False, encoding='utf-8-sig')


情感分析结果如下。



总的来说5星评分的结果多为正向(2)的。


当然也出现了一些负向(0)的结果。


不过还是在可接受范围内。


没什么大影响。



1星评分的评论情感倾向多为负向。


这里把正向的用红框圈出来了,大家可以自行体会。


毕竟机器的识别水平有限,想达到100%识别,可能性几乎为0。


这就好比语文试卷拿满分,闻所未闻。


总而言之,百度这个情感倾向分析,很不错。



/ 04 / 数据可视化


01 评论日期分布情况



热评随着电视剧的开播,便慢慢没有什么变化。


而差评却在后头有一些波动。


假设我们能够获取到差评有异常时所有的用户注册时间。


那么便能看是否真的有水军存在。


当然此处仅仅是一个假想而已,豆瓣早已把你我拒之门外。


02 评论时间分布情况



大部分评论都是在晚上评论的,符合常态。


估摸着晚上都是大家的娱乐时间,便有了闲情逸致去写评论。


03 评论评分情况



全部短评的5星评分占大头。


全部差评的1星和2星占大头。


这对得起豆瓣的8.9分了。


04 评论情感分析情况



其中「2」代表积极的,「1」代表中性的,「-2」代表消极的。


全部短评的正向结果占大头。


全部短评的排序是基于点赞数而来的。


所以对于整部剧,大家还是比较认可的。


全部差评的负向结果占大头。


给了差评,情感倾向果断差了。


05 评论用户注册时间



由于数据比较少,所以大家看着乐呵就好。


要想判断出有水军还是有难度的。


06 评论词云


好评词云。


充满了满满的正能量。



差评词云。


「看不下去」「失望」「恶心」「难看」,体现了大家对于这部剧的负面评价。




/ 05 / 总结


文章源码及相关文件已上传「GitHub」。


点击左下角阅读原文,即可获取。


万水千山总是情,点个「好看」行不行。





···  END  ···



©著作权归作者所有:来自51CTO博客作者mb5fe18ec4a4df8的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Python数据可视化:豆瓣电影TOP250
  2. 豆瓣开源的那些神库
  3. 豆瓣的账号登录及api操作
  4. 豆瓣Javascript代码风格规范
  5. 记一次python爬虫实战,豆瓣电影Top250爬虫
  6. python3爬虫爬取豆瓣电影并保存到sql serve数据库

随机推荐

  1. MyEclipse10.1正式版官网下载(附Win+Llinu
  2. Linux 删除除了某个文件之外的所有文件
  3. 嵌入式linux系统如何微秒级采样以及while
  4. 开发板挂载vmware虚拟机linux下nfs服务器
  5. Linux下符号版本原理及实现
  6. 工作中常用的Linux命令
  7. linux从0开始----01
  8. Linux2.6内核下键盘输入设备驱动的实现
  9. 一键安装linux (附带各种命令,登录欢迎界
  10. Linux之I2C设备总结