大马强 发表于 2022-1-17 20:38:13

网易云热评词云

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


这个程序去年就写好了,但由于学业问题以及一些bug,菜鸡的我到现在放假还没搞好{:5_107:}(用是还能用的)
程序功能实现:歌曲的获取,热评获取,词云生成,界面图形化

程序截图
https://static01.imgkr.com/temp/ebf54af793e14fcd808b21d4722d9a12.jpg

需要完善的地方

[*]歌曲只有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()
            param = self.id_list
            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")

求路过的到大佬看看{:9_220:} {:9_220:}

最后祝鱼油们新年快乐,快快乐乐过大年{:10_298:} {:10_288:}

hornwong 发表于 2022-1-17 22:18:15

感谢楼主

大马强 发表于 2022-1-17 22:39:38

hornwong 发表于 2022-1-17 22:18
感谢楼主

{:10_297:}

心驰神往 发表于 2022-1-18 08:08:15

厉害!

ohhohh 发表于 2022-1-18 08:37:24

{:10_254:}

阿萨德按时 发表于 2022-1-18 08:38:41

{:10_254:}

hy2009090003 发表于 2022-1-18 09:12:33

可以的很厉害

村里小黑 发表于 2022-1-18 09:18:14

{:5_95:}

会飞的猪xk 发表于 2022-1-18 09:27:54

牛牛牛!{:10_254:}

涟漪袅袅 发表于 2022-1-18 09:33:57

666

1molHF 发表于 2022-1-18 09:38:55


感谢楼主!

1449620085 发表于 2022-1-18 10:52:11

{:10_254:}{:10_254:}{:10_254:}

fxj2002 发表于 2022-1-18 11:16:19

666

JingClytze 发表于 2022-1-18 12:44:32

太强了

伽羅~ 发表于 2022-1-18 14:00:24

{:5_106:}{:5_106:}

tianlai7266 发表于 2022-1-18 15:03:41

{:10_254:}

junkersykj 发表于 2022-1-18 16:39:15

厉害厉害

junkersykj 发表于 2022-1-18 16:39:54

全世界特效最佳的Python教程

枫落雪散 发表于 2022-1-18 17:24:09

666

lantuuuuu 发表于 2022-1-18 17:50:03

厉害
页: [1] 2
查看完整版本: 网易云热评词云