首页 > 编程语言 >Python生成词云--豆瓣电影短评(初学菜鸡版)

Python生成词云--豆瓣电影短评(初学菜鸡版)

时间:2024-02-19 20:13:36浏览次数:35  
标签:comment 短评 name Python movie list -- 词云 del

Python生成词云--豆瓣电影短评(初学菜鸡版)

目录


1.主要涉及的库

  • 主要页面处理

    selenium

  • 数据处理,输出、读取CSV

    pandas、numpy

  • 对所有数据进行分词处理

    jieba

  • 处理图片,生成词云图

    wordcloud、PIL、matplotlib

  • 多线程爬取数据

    threading


2.获取数据

  1. 大致思路

  2. 获取影片ID

    在豆瓣电影页面,按名称搜索后,结果列表的第一个即为我们需要的影片

    其实总觉得这样不严谨,但多次尝试后,发现只要影片名称输入正确,暂时均为列表第一个结果

    毕竟是“菜鸡版”,先凑合着用吧 ╮(╯▽╰)╭

    KIZ64U.png

    此时我们可以直接通过selenium获取到ID,相关代码:

    # 搜索结果页
    url_search = 'https://search.douban.com/movie/subject_search?search_text=' + name + '&cat=1002'
    driver.get(url_search)
    driver.implicitly_wait(5)
    url = driver.find_element_by_xpath("//a[@class='title-text']").get_attribute('href')
    mid = url.split('/')[-2]
    name_display = driver.find_element_by_xpath("//a[@class='title-text']").text
    

    name:脚本执行时,通过手动输入的影片名称,用于拼接搜索结果页的URL

    url:本影片的页面URL

    mid:影片ID,通过斜杠'/'分割URL字符串,并取倒数第二个结果

    name_display:影片在系统的显示名称

  3. 定义一个列表,把所需用到短评URL先保存起来。

    也可以每获取一页数据,再拼接出下一页的URL,先保存到列表只是我的个人习惯

    相关代码:

    # 定义短评URL列表
    url_comment_page_list = []
    # 目前豆瓣即使登录,也只能显示最多500条(25页)
    for page_num in range(0, 520, 20):
        url_comment_temp = 'https://movie.douban.com/subject/' + movie_id + '/comments?start=' + str(page_num) + '&limit=20&sort=new_score&status=P'
        url_comment_page_list.append(url_comment_temp)
    
  4. 逐页获取短评数据,并插入到pandas的DataFrame。

    所需获取的参数,可根据个人需要而修改。

    实际上短评ID、用户名、用户域名,都是因为我程序(除了短评,还有长篇影评的菜鸡版)是涉及sqlite3数据库的,我的库表需要有相关的保存和关联。

    在主函数部分定义一个DataFrame:

    # 创建DataFrame
    data_total = pd.DataFrame(columns=('短评内容', '短评ID', '用户名', '用户域名'))
    

    相关代码:

    备注:

    这段代码,我是偷懒把最后的多线程版直接贴出来了……其实单线程就够了,只需做如下修改:

    1.前两行修改,只需通过for循环遍历短评url列表:

    for page in range url_comment_page_list:
        driver.get(page)
    

    2.最后几行,删除多线程的同步锁相关代码:

    thread_lock.acquire()
    thread_lock.release()
    
    for page in range(list_num, list_num+5):
        driver.get(url_comment_page_list[page])
        sleep(1)
        # 获取comment列表的内容
        for comment_info in driver.find_elements_by_xpath("//div[@class='comment-item']"):
            # 获取用户名
            user_name = comment_info.find_element_by_xpath(".//div/a").get_attribute('title')
            # 获取用户域名
            url_user = comment_info.find_element_by_xpath(".//div/a").get_attribute('href')
            user_link = url_user.split('/')[-2]
            # 获取comment ID
            comment_id = comment_info.get_attribute('data-cid')
            # 获取comment内容
            comment_content = comment_info.find_element_by_xpath(".//div[@class='comment']/p").text
            global data_total
            # 插入数据到DataFrame,每次只允许一个线程操作数据
            thread_lock.acquire()
            data_total = data_total.append(pd.DataFrame({'短评内容': [comment_content],
                                                         '短评ID': [comment_id],
                                                         '用户名': [user_name],
                                                         '用户域名': [user_link]}),                                                                    ignore_index=True)
            thread_lock.release()
    
  5. 将DataFrame的数据输出到CSV文件,可使用to_csv()方法

    相关代码:

    # 导出到CSV
    comment_total = data_total
    csv_path = 'comment_source/' + movie_name_display + '短评.csv'
    comment_total.to_csv(csv_path, index_label='序号')
    

3.生成词云图

  1. 读取CSV内容。

    前四行代码,是因为我通过数据库保存了影片显示名称、ID,所以通过ID查询名称,再利用名称拼接CSV文件路径。

    如果不使用数据库,其实完全可以在“file_path=”这行开始,直接定义CSV文件路径。

    最后两行的【进行分词】【生成词云图】函数,会在第二第三步提到。

    movie_id = str(input('请输入影片ID:'))
    # 查询对应影片的显示名称
    sql_search_movie_name = "SELECT movie_name FROM table_movie_info WHERE movie_id = ?"
    movie_name_display_temp = cur_now.execute(sql_search_movie_name, (movie_id,))
    movie_name_display = movie_name_display_temp.fetchone()[0]
    
    file_path = 'comment_source/' + movie_name_display + '短评.csv'
    str_uncut = pd.read_csv(file_path, usecols=[1], skiprows=[0])
    str_uncut = str_uncut.to_string(index=False)
    
    # 进行分词
    str_source = get_str_csv()
    # 生成词云图
    create_wordcloud(str_source)
    
  2. 通过jieba库进行分词

    对字符串str_uncut进行分词的话,只需要使用方法jieba.cut(str_uncut)即可。

    def get_str_csv():
        # 自定义词库
        for to_del_temp in common_methods.to_del_list_total:
            jieba.del_word(to_del_temp)
        # 对string分词
        cut_str = " ".join(jieba.cut(str_uncut))
        return cut_str
    

    上述代码使用到jieba库的自定义词库相关方法,可使用add_word()、del_word()、suggest_freq()进行动态调整词库,即只在本次执行有效。

    这次我只使用了del_word(),去排除一些语法相关的词语,例如连接词。还可以考虑把影片里的角色名称排除,不然人名的词频一般都比较高。

    至于我为什么要分这么多个list,最后再拼起来……是因为太长了我觉得看得不顺眼,顺便按词语分个类而已……Σ(っ °Д °;)っ

    而且这个自定义词库,还有很大的调整空间。

    我是写在另一个py文件common_methods里的,所以前面调用时是common_methods.to_del_list_total

    # 自定义排除词库
    to_del_list_1 = ('虽然', '但是', '还是', '因为', '所以', '不但', '而且')
    to_del_list_2 = ('一个', '可以', '这个', '那个', '这样', '那样', '这么', '那么', '不是', '只是', '就是', '真的', '没有')
    to_del_list_3 = ('非常', '知道', '其实')
    
    to_del_list_total = to_del_list_1 + to_del_list_2 + to_del_list_3
    
  3. 生成词云图

    # 生成词云图片
    def create_wordcloud(jieba_source):
        # 定义背景图、字体路径
        path_img = '输入你的图片路径'
        font_path = '输入你的字体路径'
    
        background_img = np.array(Image.open(path_img))
    
        # mask参数=图片背景,必须要写上,另外有mask参数再设定宽高是无效的
        wordcloud = WordCloud(font_path=font_path, background_color='white', mask=background_img).generate(jieba_source)
        # 生成颜色值
        image_colors = ImageColorGenerator(background_img)
    
        plt.imshow(wordcloud.recolor(color_func=image_colors), interpolation='bilinear')
        plt.axis('off')
        plt.show()
    
  4. 执行结果

    K5TvvR.png

标签:comment,短评,name,Python,movie,list,--,词云,del
From: https://www.cnblogs.com/xpecially/p/11768833.html

相关文章

  • 【FLINK学习笔记】 FLINK WINDOW(窗口)详解
    【FLINK学习笔记】FLINKWINDOW(窗口)详解一、Window分类GlobalWindow和和KeyedWindow在运用窗口计算时,Flink根据上游数据集是否为KeyedStream类型,对应的Windows也会有所不同。KeyedWindow:上游数据集如果是KeyedStream类型,则调用DataStreamAPI的window()方......
  • GaussDB(for MySQL) Serverless全面商用:无感弹性,极致性价比
    本文分享自华为云社区《GaussDB(forMySQL)Serverless全面商用:无感弹性,极致性价比》,作者:GaussDB数据库。技术背景对于现代企业级IT系统,数据库往往是作为底座一般的存在,数据库的稳定性、可靠性如果难以保障,整个系统的平稳运行将无从谈起。出于如上考量,在部署数据库资源时,客户......
  • Rabbitmq
    Rabbitmq官网:https://rabbitmq.com/install-homebrew.html安装brewinstallrabbitmq#查看版本信息,及安装位置brewinforabbitmq#配置环境变量open-e~/.zshrc#添加如下内容exportPATH=/opt/homebrew/Cellar/rabbitmq/3.12.13/sbin:$PATHrabbitmq命令#启动服......
  • 《程序是怎样跑起来的》第八章读后感
    第八章深入讲解了源代码和计算机程序的编译过程,让我们对编程有了更细致的理解。所谓源代码,其实就是我们用诸如C、Java等高级编程语言编写的原始程序代码。在实际操作中,当我们按照教材编写练习题时,那些敲击键盘完成的代码就是源代码。在这一章节里,提到了源代码与源文件(包含了源代......
  • 【学习笔记】后缀数组(SA)
    前言先把SA给写出来,SAM暂时还没学会,学会了应该也不会写,因为构造过程过于繁琐。本文可能对SA的算法流程和代码实现上的介绍相对简略,主要介绍一些常见用途。约定无特殊说明字符串的下标从\(1\)开始。无特殊说明\(s\)表示字符串,\(n\)表示字符串长度。“后缀\(i\)”......
  • 《程序是怎样跑起来的》第九章读后感
    第九章主要阐述了程序与应用之间的关系,以及操作系统如何将两者紧密联系起来。在没有深入学习计算机知识之前,我们通常只知道手机或电脑上的各种应用程序,比如游戏、播放器等,而对“程序”这个概念理解不够清晰。实际上,“程序”是由一系列指令和数据构成的,它是实现特定功能的具体逻辑......
  • PCRec论文阅读笔记
    Abstract联合训练和测特征会影响目标域的预测,因为学习的嵌入被包含偏差信息的源域所主导。于是我们提出了异构跨域推荐的预训练和微调图。我们设计了一个新的跨域推荐的预训练图神经网络(PCRec),它采用了一个图编码器的对比自监督预训练,然后我们转移预先训练好的图编码器来初始化目......
  • JavaScript 内置 Number 类型在处理浮点数时的精度问题 是如何造成的?
    JavaScript内置的Number类型在处理浮点数时的精度问题主要是由以下原因造成的:IEEE754浮点数标准:JavaScript中的数字是基于IEEE754标准实现的双精度浮点数(64位),其中:最高1位为符号位(0表示正数,1表示负数)。接下来的11位用于存储指数部分(范围大约从-1022到1023)。剩余的......
  • 什么是Event Loop?
    什么是EventLoop?js是单线程,意味着只有一个调用栈,同一时刻只能做一件事情什么是阻塞?就是一些执行很慢的代码,比如等待网络请求,这些东西相较于cpu来说是非常慢的就是说它不仅有执行栈,还有任务队列(存放宏任务和微任务)EventLoop要做的事情就是检查执行栈和任务队列,当栈空,就......
  • Python异步编程原理篇之IO多路复用模块selector
    selector简介selector是一个实现了IO复用模型的python包,实现了IO多路复用模型的select、poll和epoll等函数。它允许程序同时监听多个文件描述符(例如套接字),并在其中任何一个就绪时进行相应的操作。这样可以有效地管理并发I/O操作,提高程序的性能和资源利用率。本篇主要......