Python豆瓣电影评论的爬取及词云显示

课程设计论文链接

课程设计论文链接:
https://download.csdn.net/download/QQwli/14066030

前言

小白简单的课程设计,功能简单。
本文通过利用 Python 爬虫分类中的聚焦型爬虫网络系统以及python窗体的相关应用,在指定的网页下抓取相关的信息。在本文的实验中通过在电脑网页抓取豆瓣网中排名top250电影的影评信息,再通过选取要爬取的电影爬取电影评论,成功的爬取后在窗体中显示并以.csv的格式保存到本地,接着利用 jieba 分词对下载好的影评信息进行过滤筛选,将高频率出现的词语通过影评词云图的形式展现在面前。这样的爬取信息大大的提高了爬取信息的准确性,提高了资源的利用率,节约了查找信息的时间,真正的实现了有目的性的抓取信息。并且以窗体的形式展示更加具有可用性、易操作性。

开发工具、核心库

import requests
from lxml import etree
import tkinter
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import jieba
import threading

系统相关技术介绍

requests库
Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加 Pythoner。Requests中get请求是常用的请求之一,相对于post请求简单些,对于传参数的get请求有的还是有难度的。使用requests方法后,会返回一个response对象,其存储了服务器响应的内容,对已经提到的内容获取文本方式的响应体实例:当访问时,会使用其响应的文本编码进行解码,并且可以修改其编码使其自定义的编码进行解码。

系统分析与设计

系统功能模块组成

在这里插入图片描述

实现功能和目标

1.爬取豆瓣top250的电影名称和每部电影的链接。
2.保存top250.csv电影信息。
3.输入要爬取的电影名称,爬取前20页的影评信息。
4.保存’电影名称’.csv影评信息。
5.词云展示影评信息关键词。

爬取模块设计

在这里插入图片描述

打开豆瓣电影top250所在的网页;在浏览器上打开源代码页面,找到电影信息的源代码,在div class=”hd”,下找到电影详细链接所在的目录a用@href获取中间内容,即为该电影链接,在其包含的下一目录的第一个span中获取电影名称。获取结果如下所示:
需要提取的数据包括(可以使用 xpath 进行匹配):
详细链接:html.xpath(’//div[@class=“hd”]/a/@href’)
电影名称:html.xpath(’//div[@class=“hd”]/a/span[1]/text()’)
在这里插入图片描述
电影评论:html_elem.xpath(’//div[@class=“comment”]/p/span[1]/text()’)

爬取过程中下一页的处理

首先使用 Chrome 浏览器打开 豆瓣电影 Top250,很容易可以判断出网站是一个静态网页然后分析网站的 URL 规律,以便于通过构造 URL 获取网站中所有网页的内容:
首页:https://movie.douban.com/top250
第二页:https://movie.douban.com/top250?start=25&filter=
第三页:https://movie.douban.com/top250?start=50&filter=
经过验证,很容易可以发现首页的 URL 也满足上面的规律。

窗口界面设计

在这里插入图片描述

系统实现

爬取电影信息模块实现

在这里插入图片描述

在这里插入图片描述
核心实现代码:

#解析、爬取电影。爬取电影信息,包括电影名字和连接
def parse_pagemov(html):
    html_elem = etree.HTML(html)
    links = html_elem.xpath('//div[@class="hd"]/a/@href')#电影连接
    titles = html_elem.xpath('//div[@class="hd"]/a/span[1]/text()')#名字
    data = zip(links,titles)
    return data

def crawlmov():
    try:
        scr.insert(INSERT, '开始爬取电影信息....\n')
        url = 'https://movie.douban.com/top250?start={page}&filter='
        fd = open('MovieTop250.csv', 'w', encoding='utf-8', newline='')
        print('开始爬取')
        for page in range(0,250,25):
            scr.insert(INSERT,'正在爬取第 ' + str(page+1) + ' 页至第 ' + 					str(page+25) + ' 页......\n')
            html = get_page(url.format(page=str(page)))
            data = parse_pagemov(html)
            save2file(fd,data)
        fd.close()
        print('电影TOP250爬取结束')
        scr.insert(INSERT,'电影TOP250爬取结束,文件保存成功\n')
    except EXCEPTION as ex:
        scr.insert(INSERT, '爬取电影信息错误!\n')
        tkinter.messagebox.showerror(title='Hi', message=ex)

#多线程爬取电影信息,防止页面卡死
def thcrawmv():
    sart=time.time()
    p=threading.Thread(target=crawlmov)
    p.start()
    stop=time.time()

爬取评论实现

在这里插入图片描述
在这里插入图片描述
核心实现代码:

#封装
def get_page1(url):
    #头部
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'}
    response=requests.get(url=url,headers=headers)
    txt=response.text
    return txt

#爬取电影评论内容
def crawlcom(k,i):
    try:
        scr.insert(INSERT, '开始爬取评论信息....\n')
        url_base=i+'comments?limit=20&status=P&sort=new_score'
        fd = open('{}.csv'.format(k), 'w', encoding='utf-8', newline='')
        print("开始爬取")
        for page in range(0,200,20):
            scr.insert(INSERT,'正在爬取第 ' + str(page+1) + ' 条至第 ' + 				  str(page+20) + ' 条评论'+'\n')
            if page<20:
                txt = get_page1(url_base)
            else:
                txt=get_page1(url.format(page=page))
            data = par_pagecom(txt)
            save2file(fd, data)
            time.sleep(random.random())
            url = i+'comments?start={page}&limit=20&status=P&sort=new_score'
        fd.close()
        tkinter.messagebox.showinfo(title='Hi', message='{}评论爬取结束,文件保         		 存成功'.format(k))
        show(k)
        scr.insert(INSERT,"{}评论爬取结束,文件保存成功.\n".format(k))
        print("{}评论爬取结束".format(k))

    except EXCEPTION as ex:
        scr.insert(INSERT, '爬取电影评论错误!\n')
        tkinter.messagebox.showerror(title='Hi', message=ex)

#多线程
def thcrawcom():
    start=time.time()
    p=threading.Thread(target=crawlcom ,args=(En.get(),seach(En.get())))
    p.start()
    stop=time.time()

#根据电影名字获取该电影的详细连接
def seach(k):
    with open('MovieTop250.csv', encoding='utf-8') as f:
        data_list = [i for i in csv.reader(f)]
    dict = {}
    for i in data_list:
        dict[i[1]] = i[0]
    return dict.get(k)

词云模块实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
核心实现代码:

#生成词云并保存图片
def wordcd(c):
    try:
        scr.insert(INSERT, "{}词云开始生成\n".format(c))
        path_txt = '{}.csv'.format(c)
        f = open(path_txt, 'r', encoding='UTF-8').read()
        #屏蔽出现率高的无用词汇,提高精准度
        stop = {'的', '我', '我们', '你们', '他们', '它', '她', '他', '你', '她们', '电影', '是', '还是','了', '就', '也','和', '看','一个','在','都','不','有','没有','那','那个','				这','这个','啊','又'}
        cut_txt = " ".join(jieba.cut(f))
        wordcloud = WordCloud(font_path="C:/Windows/Font/simfang.ttf", 							background_color="white", width=1000,
                              height=900,stopwords=stop).generate(cut_txt)
        plt.imshow(wordcloud, interpolation="bilinear")
        plt.axis("off")
        plt.show()
        wordcloud.to_file('{}.jpg'.format(c))
    except:
        tkinter.messagebox.showerror(title='Hi', message='生成词云出错')

系统开发总结

在对电影和评论爬取过程中,为了更能简化操作,本文特意增加了窗口显示界面,然而在增加了窗体后,也遇到了很多麻烦,在电影信息和评论爬取的时候,会有卡屏未响应情况,为了解决这个问题,通过查阅资料,发现是爬取过程中占用了开发工具的cpu,为此添加了多线程,顺利的解决了该问题。再者是按钮控件绑定有参数函数的时候,需要传递参数,但一直未能传递成功,后来查阅资料才知道需要用到lambda表达式来传递参数。
当然,因为自己的能力有限,程序也存在一些问题,比如程序未能连入数据库保存文件;实现过程较冗余复杂;窗口界面太简陋;实现的功能较少。

全部代码附录

import requests
from lxml import etree
import json
import csv
import time
import random
import tkinter
import csv
import time
from tkinter import *
from tkinter import messagebox
from tkinter import scrolledtext
from tkinter import ttk
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import jieba
import threading
# 获取网页源代码,封装电影界面
def get_page(url):
    headers = {'USER-AGENT':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
    response = requests.get(url=url,headers=headers)
    html = response.text
    return html
#封装
def get_page1(url):
    #头部
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'}
    response=requests.get(url=url,headers=headers)
    txt=response.text
    return txt
#解析、爬取电影
def parse_pagemov(html):
    html_elem = etree.HTML(html)
    links = html_elem.xpath('//div[@class="hd"]/a/@href')#电影连接
    titles = html_elem.xpath('//div[@class="hd"]/a/span[1]/text()')#名字
    data = zip(links,titles)
    return data
#解析、爬取评论
def par_pagecom(txt):
    txt_elem = etree.HTML(txt)
    name = txt_elem.xpath('//div[@class="comment"]/p/span[1]/text()')#评论
    data = zip(name)
    return data
#写入保存文件
def save2file(fd,data):
    writer = csv.writer(fd)
    for item in data:
        writer.writerow(item)
#爬取电影信息,包括电影名字和连接
def crawlmov():
    try:
        scr.insert(INSERT, '开始爬取电影信息....\n')
        #tkinter.messagebox.showinfo(title='Hi', message='正在爬取电影信息,大约5s')
        url = 'https://movie.douban.com/top250?start={page}&filter='
        fd = open('MovieTop250.csv', 'w', encoding='utf-8', newline='')
        print('开始爬取')
        for page in range(0,250,25):
            scr.insert(INSERT,'正在爬取第 ' + str(page+1) + ' 页至第 ' + str(page+25) + ' 页......\n')
            html = get_page(url.format(page=str(page)))
            data = parse_pagemov(html)
            save2file(fd,data)
        fd.close()
        print('电影TOP250爬取结束')
        scr.insert(INSERT,'电影TOP250爬取结束,文件保存成功\n')
        #tkinter.messagebox.showinfo(title='Hi', message='爬取结束,文件保存成功')
    except EXCEPTION as ex:
        scr.insert(INSERT, '爬取电影信息错误!\n')
        tkinter.messagebox.showerror(title='Hi', message=ex)
#多线程爬取电影信息,防止页面卡死
def thcrawmv():
    sart=time.time()
    p=threading.Thread(target=crawlmov)
    p.start()
    stop=time.time()
#爬取电影评论内容
def crawlcom(k,i):
    try:
        scr.insert(INSERT, '开始爬取评论信息....\n')
        url_base=i+'comments?limit=20&status=P&sort=new_score'
        fd = open('{}.csv'.format(k), 'w', encoding='utf-8', newline='')
        print("开始爬取")
        for page in range(0,200,20):
            scr.insert(INSERT,'正在爬取第 ' + str(page+1) + ' 条至第 ' + str(page+20) + ' 条评论'+'\n')
            if page<20:
                txt = get_page1(url_base)
            else:
                txt=get_page1(url.format(page=page))
            data = par_pagecom(txt)
            save2file(fd, data)
            time.sleep(random.random())
            url = i+'comments?start={page}&limit=20&status=P&sort=new_score'
        fd.close()
        tkinter.messagebox.showinfo(title='Hi', message='{}评论爬取结束,文件保存成功'.format(k))
        show(k)
        scr.insert(INSERT,"{}评论爬取结束,文件保存成功.\n".format(k))
        print("{}评论爬取结束".format(k))
    except EXCEPTION as ex:
        scr.insert(INSERT, '爬取电影评论错误!\n')
        tkinter.messagebox.showerror(title='Hi', message=ex)
#多线程爬取电影评论
def thcrawcom():
    start=time.time()
    p=threading.Thread(target=crawlcom ,args=(En.get(),seach(En.get())))
    p.start()
    stop=time.time()
#根据电影名字获取该电影的详细连接
def seach(k):
    with open('MovieTop250.csv', encoding='utf-8') as f:
        data_list = [i for i in csv.reader(f)]
    dict = {}
    for i in data_list:
        dict[i[1]] = i[0]
    return dict.get(k)
#窗体展示电影信息和评论内容
def show(k):
    #显示评论窗体
    master=tkinter.Tk()
    master.geometry('400x400')
    scr = scrolledtext.ScrolledText(master,width=90,height=80)
    scr.pack()
    if k==1:
        master.title('电影显示')
        with open('MovieTop250.csv', encoding='utf-8') as fp:
            data_list = [i for i in csv.reader(fp)]
        for item in data_list:
            scr.insert(15000.0,item[1]+'\n')
    else:
        master.title('{}评论显示'.format(k))
        with open('{}.csv'.format(k), encoding='utf-8') as fp:
            data_list = [i for i in csv.reader(fp)]
        for item in data_list:
            scr.insert(15000.0,item[0]+'\n')
    master.mainloop()
#生成词云并保存图片
def wordcd(c):
    try:
        scr.insert(INSERT, "{}词云开始生成\n".format(c))
        path_txt = '{}.csv'.format(c)
        f = open(path_txt, 'r', encoding='UTF-8').read()
        #屏蔽出现率高的无用词汇,提高精准度
        stop = {'的', '我', '我们', '你们', '他们', '它', '她', '他', '你', '她们', '电影', '是', '还是','了', '就', '也','和', '看','一个','在','都','不','有','没有','那','那个','这','这个','啊','又'}
        cut_txt = " ".join(jieba.cut(f))
        wordcloud = WordCloud(font_path="C:/Windows/Font/simfang.ttf", 	background_color="white", width=1000,
height=900,stopwords=stop).generate(cut_txt)
        plt.imshow(wordcloud, interpolation="bilinear")
        plt.axis("off")
        plt.show()
        wordcloud.to_file('{}.jpg'.format(c))
    except:
        tkinter.messagebox.showerror(title='Hi', message='生成词云出错')
#主函数
if __name__=='__main__':
    try:
        #窗口布局
        window = tkinter.Tk()
        window.title('爬取电影评论')
        window.geometry('400x450')
        btn1 = tkinter.Button(window, text='爬取电影信息', font=('Arial', 11), width=10, height=1, command=thcrawmv)
        btn1.place(x=155,y=10)
        btn2 = tkinter.Button(window, text='显示电影信息', font=('Arial', 11), width=10, height=1, command=lambda :show(1))
        btn2.place(x=155,y=50)
        l=tkinter.Label(window, text='输入要查询的电影:', font=('Arial', 11), width=30, height=2)
        l.place(x=85,y=80)
        En=tkinter.Entry(window,width=15)
        En.place(x=155,y=115)
        btn3 = tkinter.Button(window, text='爬取', font=('Arial', 12), width=13, height=1,
                              command=thcrawcom)
        btn3.place(x=50,y=150)
        btn4 = tkinter.Button(window, text='生成词云并保存', font=('Arial', 12), width=13, height=1,
                              command=lambda: wordcd(En.get()))
        btn4.place(x=240,y=150)
        #window.geometry('600x600')
        scr = scrolledtext.ScrolledText(window,width=54,height=18)
        scr.place(y=200)
        window.mainloop()
    except:
        tkinter.messagebox.showerror(title='Hi', message='出错了!')
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Python爬取豆瓣电影词云图的步骤: 1.导入需要的库和模块 ```python import requests from bs4 import BeautifulSoup import jieba from wordcloud import WordCloud, ImageColorGenerator import matplotlib.pyplot as plt from PIL import Image import numpy as np ``` 2.获取网页源代码并解析 ```python url = 'https://movie.douban.com/subject/26363254/comments?status=P' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') ``` 3.获取评论内容并进行分词 ```python comments = soup.find_all('span', class_='short') comment_text = '' for comment in comments: comment_text += comment.text words = jieba.cut(comment_text) ``` 4.统计词频并生成词云图 ```python word_counts = {} for word in words: if len(word) == 1: continue else: word_counts[word] = word_counts.get(word, 0) + 1 wordcloud = WordCloud(font_path='msyh.ttc', background_color='white', max_words=200, max_font_size=100, width=800, height=600) wordcloud.generate_from_frequencies(word_counts) plt.imshow(wordcloud, interpolation='bilinear') plt.axis('off') plt.show() ``` 5.生成带有图片的词云图 ```python mask = np.array(Image.open('movie.png')) image_colors = ImageColorGenerator(mask) wordcloud = WordCloud(font_path='msyh.ttc', background_color='white', max_words=200, max_font_size=100, width=800, height=600, mask=mask) wordcloud.generate_from_frequencies(word_counts) plt.imshow(wordcloud.recolor(color_func=image_colors), interpolation='bilinear') plt.axis('off') plt.show() ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值