python:从影评中看妙先生讲了啥?

最近,在工作之余自学python,越发膨胀,觉得自己厉害了一丢丢,前段时间看过秒先生,画面还挺好,立意嘛就图一乐呵,于是想用影评分析一下,看看大家都怎么看待妙先生这部电影。

分析网站

alt3
如图所示,我们要读取的是该页面的短评部分,文章是有分页,从浏览器地址栏我们看到有start参数,在第二页时参数值为20,因此我们可以知道,豆瓣影评的分页大小为20 初始值为0,可以看每段短评都有展开字样,这里我们就不再展开,只分析短评部分(省事)。

开始编码

1.进入主页面,使用beautifulsoap 解析获取到的html标签以及数据

 url = "https://movie.douban.com/subject/34888476/reviews"
 headers = getHeader()
 request = urllib3.PoolManager()
 response = request.request("GET", url, headers=headers)
 htmlText = response.data

2.获取评论总数,然后根据评论总数和分页参数构建请求

# 获取每页具体影评
def getRemarks(url):
    headers=getHeader()
    global all_remark
    html = getXHRHtml(url)
    bs = BeautifulSoup(html, "html.parser")
    remarks = bs.find(attrs={'class': 'review-list'}).find_all(attrs={'class':'short-content'})
    for item in remarks:
        text= item.text
        text='|'.join(text.split())
        strArr= text.split(sep="|")
        all_remark=all_remark+strArr[1]
    # 获取评论总条数
    remarks_title = bs.find(attrs={'id':'content'}).find('h1').text
    remarks_count = remarks_title[remarks_title.index('(')+1:remarks_title.index(')')]
    remarks_count = int(remarks_count,base=10)
    # 已知每页显示20条 ,翻页
    for start in range(0,remarks_count,20):
        url_temp=f"https://movie.douban.com/subject/34888476/reviews?start={start}"
        # 使用多线程加载分页的异步数据,挨个加载效率太低
        t = Thread(target=getRemarks, args=[url_temp])
        t.start()
        threads.append(t)
    # 等待所有线程结束
    for thread in threads:
        thread.join()
    print(all_remark)

这里我们通过多线程请求,避免在网页响应的处理等待。在具体获取分页的影评时我们要通过selenium.webdriver库通过浏览器去获取异步加载的数据。
最后通过解析过来的数据,我们将其生成一个词云图,分析一下大家都在讨论什么。
词云我是借鉴的这位大佬的 文章

最终结果,如图
alt5
最后得出结论我太菜了,只知道大家一致认为 妙先生里没有好人。

全部代码

import urllib3
from bs4 import BeautifulSoup
import numpy as np
from selenium import  webdriver
from selenium.webdriver.chrome.options import Options
import time
from threading import Thread
import re
import jieba
import collections
from PIL import Image
import wordcloud
import matplotlib.pyplot as plt


# 全局变量
# 创建进程列表
threads = []
all_remark=""


#  获取模拟头
def getHeader():
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
    return headers


# 异步获取页面数据
def getXHRHtml(url):
    # 使用Google浏览器
    googledriver=r"C:\Users\weiyongjian\AppData\Local\Google\Chrome\Application\chromedriver.exe"
    # 不弹窗口
    options = Options()
    options.headless = True
    google=webdriver.Chrome(options=options,executable_path=googledriver)
    try:
        google.get(url)
        google.refresh()
        time.sleep(4)
    except Exception as e:
        pass
    html=google.page_source
    google.close()
    return html


# 获取具体影评
def getRemarks(url):
    headers=getHeader()
    global all_remark
    html = getXHRHtml(url)
    bs = BeautifulSoup(html, "html.parser")
    remarks = bs.find(attrs={'class': 'review-list'}).find_all(attrs={'class':'short-content'})
    for item in remarks:
        text= item.text
        text='|'.join(text.split())
        strArr= text.split(sep="|")
        all_remark=all_remark+strArr[1]


# 进入影评页拿取影评信息
def getRemark(url):
    headers = getHeader()
    request = urllib3.PoolManager()
    response = request.request("GET", url, headers=headers)
    htmlText = response.data
    bs = BeautifulSoup(htmlText, "html.parser")
    # 获取评论总条数
    remarks_title = bs.find(attrs={'id':'content'}).find('h1').text
    remarks_count = remarks_title[remarks_title.index('(')+1:remarks_title.index(')')]
    remarks_count = int(remarks_count,base=10)
    # 已知每页显示20条 ,翻页
    for start in range(0,remarks_count,20):
        url_temp=f"https://movie.douban.com/subject/34888476/reviews?start={start}"
        # 使用多线程加载分页的异步数据,挨个加载效率太低
        t = Thread(target=getRemarks, args=[url_temp])
        t.start()
        threads.append(t)
    # 等待所有线程结束
    for thread in threads:
        thread.join()
    print(all_remark)
    # 处理结果生成词云
    # 文本预处理
    pattern = re.compile(u'\t|\n|\.|-|:|;|\)|\(|\?|"|》|《|”')  # 定义正则表达式匹配模式
    string_data = re.sub(pattern, '', all_remark)  # 将符合模式的字符去除
    # 文本分词
    seg_list_exact = jieba.cut(string_data, cut_all=False)  # 精确模式分词
    object_list = []
    remove_words = [u'的', u',', u'和', u'是', u'随着', u'对于', u'对', u'等', u'能', u'都', u'。', u' ', u'、', u'中', u'在', u'了',
                    u'通常', u'如果', u'我们', u'需要', u'我', u'有', u'展开']  # 自定义去除词库
    for word in seg_list_exact:  # 循环读出每个分词
        if word not in remove_words:  # 如果不在去除词库中
            object_list.append(word)  # 分词追加到列表
    # 词频统计
    word_counts = collections.Counter(object_list)  # 对分词做词频统计
    word_counts_top10 = word_counts.most_common(10)  # 获取前10最高频的词
    print(word_counts_top10)  # 输出检查

    # 词频展示
    mask = np.array(Image.open('wordcloud.png'))  # 定义词频背景
    wc = wordcloud.WordCloud(
        font_path='C:/Windows/Fonts/simhei.ttf',  # 设置字体格式
        mask=mask,  # 设置背景图
        max_words=200,  # 最多显示词数
        max_font_size=100  # 字体最大值
    )
    wc.generate_from_frequencies(word_counts)  # 从字典生成词云
    image_colors = wordcloud.ImageColorGenerator(mask)  # 从背景图建立颜色方案
    wc.recolor(color_func=image_colors)  # 将词云颜色设置为背景图方案
    plt.imshow(wc)  # 显示词云
    plt.axis('off')  # 关闭坐标轴
    plt.show()  # 显示图像

if __name__ == '__main__':
    url = "https://movie.douban.com/subject/34888476/reviews"
    getRemark(url)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值