鱼C论坛

 找回密码
 立即注册
查看: 2051|回复: 30

[技术交流] 网易云热评词云

[复制链接]
发表于 2022-1-17 20:38:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 大马强 于 2022-1-18 11:34 编辑


这个程序去年就写好了,但由于学业问题以及一些bug,菜鸡的我到现在放假还没搞好(用是还能用的)

程序功能实现:歌曲的获取,热评获取,词云生成,界面图形化

程序截图

                               
登录/注册后可看大图


需要完善的地方
  • 歌曲只有20首,我在网页版搜索也是这样
  • 窗口大小改变,但生成的词云就不会按照我期望的大小改变

程序包含三个文件 wyy ,wc以及网易云热评词云

网易云热评词云代码
from tkinter import messagebox
from tkinter import *
from wyy import Wyy
from wc import *

class comment_wordcloud:

    def __init__(self, root) -> None:
        self.song_list = []   # 歌曲的名字
        self.id_list = []
        self.wc = None
        self.photo = None
        self.w = Wyy()
        self.root = root

        # 主窗口和主框架
        self.cv = Canvas(self.root,  background="gray")  # 右边 词云显示地方
        self.lf = LabelFrame(self.root, background="blue")  # 左边输入框 按钮 歌曲列表
        # 左上方输入框和两个按钮
        self.lf1 = LabelFrame(self.lf, height=250, width=200)
        self.e1 = Entry(self.lf1, width=27)
        self.b1 = Button(self.lf1, text="获取信息", width=13,
                         command=self.get_song_list, cursor="hand2")  # 获取歌曲
        self.b2 = Button(self.lf1, text="生成词云", width=13,
                         command=self.get_hotcomment, cursor="hand2")  # 获取歌曲
        # 左下显示歌曲列表的地方
        self.lf2 = LabelFrame(self.lf, height=250, width=200)
        self.sb = Scrollbar(self.lf2)
        self.lb = Listbox(self.lf2, yscrollcommand=self.sb,
                          height=450, width=200)
        # 组件的摆放
        self.show_widget()
        # s刷新词云大小
        self.root.bind("<Configure>", self.refresh)

    def show_wordcloud(self):
        self.cv.delete(ALL)
        height_ = self.cv.winfo_height()
        width_ = self.cv.winfo_width()

        try:
            self.wc = WC(width_, height_)
            with open("content.txt", "r", encoding="utf-8") as fp:
                content = fp.read()
            self.photo
            self.wc.to_file(content)
            self.photo = PhotoImage(file="./wc.png")
            self.cv.create_image(width_/2, height_/2,
                                 anchor=CENTER, image=self.photo)
        except:
            pass

    def get_song_list(self):
        self.lb.delete(0, END)  # 将上一次的数据清除
        if(self.e1.get()):
            self.song_list[:] = self.w.get_song_list(self.e1.get())
            for name in self.song_list:
                self.lb.insert(END, name["name"])
                self.id_list.append(name["id"])

    def get_hotcomment(self):
        if (self.lb.curselection()):

            # print(id_list)
            index = self.lb.curselection()[0]
            param = self.id_list[index]
            comment_list = self.w.get_hotcomment(param)

            if comment_list != -1:
                if comment_list:
                    # 将数据写入一个文本文件中
                    with open("评论.txt", "w", encoding="utf-8") as fp:
                        for content in comment_list:
                            fp.write(content["content"])
                    self.show_wordcloud()
                else:
                    messagebox.showerror(
                        title="粗错啦!", message="该歌曲是纯音乐,无歌词!", icon="info")
            else:
                messagebox.showerror(
                    title="粗错啦!", message="你被反爬了,休息下吧!", icon="info")

    def refresh(self, event):  # 窗口大小的改变
        # a = event.height
        # b = event.width
        # print(self.cv.winfo_height(), self.cv.winfo_width())
        height_ = self.root.winfo_height()
        width_ = self.root.winfo_width()
        print("当前", height_, width_)
        print("上一次", self.cv_h, self.cv_w)
        self.cv.place(x=200, y=0, width=width_-200, height=height_ - 10)
        self.lf.place(x=0, y=0, width=200, height=height_)
        print(abs(width_ - self.cv_w), abs(height_ - self.cv_h))
        # 长宽改变超过一定数值才会改变,要不然太卡了
        if self.photo and (abs(width_ - self.cv_w) > 25 or abs(height_ - self.cv_h) > 10):
            self.cv_w = width_
            self.cv_h = height_
            self.show_wordcloud()

    def show_widget(self):
        self.cv_h = self.lf_h = 500
        self.cv_w = 400
        self.lf_w = 200

        self.cv.place(x=200, y=0, height=self.cv_h, width=self.cv_w)
        self.lf.place(x=0, y=0, height=self.cv_h, width=self.lf_w)
        self.lf1.pack()
        self.lf2.pack()
        self.e1.grid(row=0, columnspan=2, pady=5)
        self.b1.grid(row=1, column=0, sticky=W)
        self.b2.grid(row=1, column=1, sticky=E)
        self.sb.pack(side=RIGHT, fill=Y)
        self.lb.pack()


if __name__ == "__main__":
    root = Tk()
    root.geometry("600x500")
    cw = comment_wordcloud(root)
    root.mainloop()

wyy代码
from Crypto.Cipher import AES
from base64 import b64encode
import requests
import json


class Wyy():

    def __init__(self):
        # 将加密的变量准备好
        self.e = "010001"
        self.d = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
        self.g = "0CoJUm6Qyw8W8jud"
        self.i = "p6xB1rx37AU8O0KO"
        self.song_list = ""

    def get_encSeckey(self):
        return "b742226290709f51abf9ad9a4e9136bd89036078368545a3f9a5ab938068d7a7be4d3f3fc2ea184090def069b85f75e4b443a43b1a872710c22ce983a3785fc074e799bd90d3e22a7a14d8a4864d647a72dc3a0de05a10ac61ef8114b631bf0079708ff79e0c2901ce0db1c26be78503550f65be6490ad08125ebf9744cc41cf"

    # 补位
    def to_16(self, data):
        pd = 16 - len(data) % 16
        data += chr(pd) * pd
        return data

    def enc_param(self, data, key):
        iv = "0102030405060708"
        # 创建一个AES加密器, 设置密钥,偏移量以及模式,前两者要为字符串格式
        # AEs加密的数据格式一定是16的倍数,不到就用chr(x)补齐 格式为 "123456788chr(7)chr(7)"
        data = self.to_16(data)
        aes = AES.new(key=key.encode("utf-8"),
                      iv=iv.encode("utf-8"), mode=AES.MODE_CBC)
        # 加密后返回结果为字节,但需要的是字符串,并且该返回不能被 utf-8 格式所识别,还需要借助其他的库将其转换
        bs = aes.encrypt(data.encode("utf-8"))
        return str(b64encode(bs), "utf-8")

    def get_param(self, data):  # 字典1是加密不了的,需要处理成字符串
        # param 是经过两次加密的
        first = self.enc_param(data, self.g)
        second = self.enc_param(first, self.i)
        return second

    def requset_data(self, url, data):
        req = requests.post(url, data={
            "params": self.get_param(json.dumps(data)),
            "encSecKey": self.get_encSeckey()
        })
        res = req
        req.close()

        return res

    def get_hotcomment(self, data):
        url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="
        self.data = {
            "cursor": "-1",
            "offset": "0",
            "orderType": "1",
            "pageNo": "1",
            "pageSize": "20",
            "rid": f"R_SO_4_{data}",
            "threadId": f"R_SO_4_{data}"
        }
        req = self.requset_data(url, self.data)
        if req.json()["code"] == -460:
            return -1
        else:
            return req.json()["data"]["hotComments"]

    def get_song_list(self, s):
        url = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token="
        data = {
            'csrf_token': "",
            "hlposttag": "</span>",
            "hlpretag": r'"<span class="s-fc7">"',
            "limit": "30",
            "offset": "0",
            "s": s,
            "total": "true",
            'type': "1"
        }
        req = self.requset_data(url, data)
        self.song_list = req.json()["result"]["songs"]
        return self.song_list

if __name__ == "__main__":
    # pass
    # 测试代码
    w = Wyy()

wc代码
import wordcloud
import jieba

# 创建一个词云对象,并且设置相关属性


class WC():
    def __init__(self, width_, height_):
        self.wc = wordcloud.WordCloud(width=width_, height=height_,
                                      background_color="white", font_path="msyh.ttc")

    def to_file(self, data):
        data = str(data)
        # 将字符串用jieba处理
        text = jieba.lcut(data)
        text = " ".join(text)
        self.wc.generate(text)
        self.wc.to_file("wc.png")

求路过的到大佬看看

最后祝鱼油们新年快乐,快快乐乐过大年
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-17 22:18:15 | 显示全部楼层

回帖奖励 +10 鱼币

感谢楼主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-17 22:39:38 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 08:08:15 | 显示全部楼层

回帖奖励 +10 鱼币

厉害!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 08:37:24 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 08:38:41 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 09:12:33 | 显示全部楼层

回帖奖励 +10 鱼币

可以的很厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2022-1-18 09:18:14 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 09:27:54 | 显示全部楼层

回帖奖励 +10 鱼币

牛牛牛!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 09:33:57 | 显示全部楼层

回帖奖励 +10 鱼币

666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 09:38:55 | 显示全部楼层

回帖奖励 +10 鱼币


感谢楼主!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 10:52:11 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 11:16:19 | 显示全部楼层

回帖奖励 +10 鱼币

666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 12:44:32 | 显示全部楼层

回帖奖励 +10 鱼币

太强了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 14:00:24 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 15:03:41 | 显示全部楼层

回帖奖励 +10 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 16:39:15 | 显示全部楼层

回帖奖励 +10 鱼币

厉害厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 16:39:54 | 显示全部楼层
全世界特效最佳的Python教程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 17:24:09 | 显示全部楼层

回帖奖励 +10 鱼币

666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-18 17:50:03 | 显示全部楼层

回帖奖励 +10 鱼币

厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-28 20:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表