|  | 
 
| 
本帖最后由 大马强 于 2022-1-18 11:34 编辑
x
马上注册,结交更多好友,享用更多功能^_^您需要 登录 才可以下载或查看,没有账号?立即注册  
 
 
 这个程序去年就写好了,但由于学业问题以及一些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")
 求路过的到大佬看看
     
 最后祝鱼油们新年快乐,快快乐乐过大年
     
 | 
 |