鱼C论坛

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

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

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

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

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

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


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

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

程序截图

                               
登录/注册后可看大图


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

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

网易云热评词云代码
  1. from tkinter import messagebox
  2. from tkinter import *
  3. from wyy import Wyy
  4. from wc import *

  5. class comment_wordcloud:

  6.     def __init__(self, root) -> None:
  7.         self.song_list = []   # 歌曲的名字
  8.         self.id_list = []
  9.         self.wc = None
  10.         self.photo = None
  11.         self.w = Wyy()
  12.         self.root = root

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

  32.     def show_wordcloud(self):
  33.         self.cv.delete(ALL)
  34.         height_ = self.cv.winfo_height()
  35.         width_ = self.cv.winfo_width()

  36.         try:
  37.             self.wc = WC(width_, height_)
  38.             with open("content.txt", "r", encoding="utf-8") as fp:
  39.                 content = fp.read()
  40.             self.photo
  41.             self.wc.to_file(content)
  42.             self.photo = PhotoImage(file="./wc.png")
  43.             self.cv.create_image(width_/2, height_/2,
  44.                                  anchor=CENTER, image=self.photo)
  45.         except:
  46.             pass

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

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

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

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

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

  89.     def show_widget(self):
  90.         self.cv_h = self.lf_h = 500
  91.         self.cv_w = 400
  92.         self.lf_w = 200

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


  102. if __name__ == "__main__":
  103.     root = Tk()
  104.     root.geometry("600x500")
  105.     cw = comment_wordcloud(root)
  106.     root.mainloop()
复制代码


wyy代码
  1. from Crypto.Cipher import AES
  2. from base64 import b64encode
  3. import requests
  4. import json


  5. class Wyy():

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

  13.     def get_encSeckey(self):
  14.         return "b742226290709f51abf9ad9a4e9136bd89036078368545a3f9a5ab938068d7a7be4d3f3fc2ea184090def069b85f75e4b443a43b1a872710c22ce983a3785fc074e799bd90d3e22a7a14d8a4864d647a72dc3a0de05a10ac61ef8114b631bf0079708ff79e0c2901ce0db1c26be78503550f65be6490ad08125ebf9744cc41cf"

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

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

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

  35.     def requset_data(self, url, data):
  36.         req = requests.post(url, data={
  37.             "params": self.get_param(json.dumps(data)),
  38.             "encSecKey": self.get_encSeckey()
  39.         })
  40.         res = req
  41.         req.close()

  42.         return res

  43.     def get_hotcomment(self, data):
  44.         url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="
  45.         self.data = {
  46.             "cursor": "-1",
  47.             "offset": "0",
  48.             "orderType": "1",
  49.             "pageNo": "1",
  50.             "pageSize": "20",
  51.             "rid": f"R_SO_4_{data}",
  52.             "threadId": f"R_SO_4_{data}"
  53.         }
  54.         req = self.requset_data(url, self.data)
  55.         if req.json()["code"] == -460:
  56.             return -1
  57.         else:
  58.             return req.json()["data"]["hotComments"]

  59.     def get_song_list(self, s):
  60.         url = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token="
  61.         data = {
  62.             'csrf_token': "",
  63.             "hlposttag": "</span>",
  64.             "hlpretag": r'"<span class="s-fc7">"',
  65.             "limit": "30",
  66.             "offset": "0",
  67.             "s": s,
  68.             "total": "true",
  69.             'type': "1"
  70.         }
  71.         req = self.requset_data(url, data)
  72.         self.song_list = req.json()["result"]["songs"]
  73.         return self.song_list

  74. if __name__ == "__main__":
  75.     # pass
  76.     # 测试代码
  77.     w = Wyy()
复制代码


wc代码
  1. import wordcloud
  2. import jieba

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


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

  8.     def to_file(self, data):
  9.         data = str(data)
  10.         # 将字符串用jieba处理
  11.         text = jieba.lcut(data)
  12.         text = " ".join(text)
  13.         self.wc.generate(text)
  14.         self.wc.to_file("wc.png")
复制代码


求路过的到大佬看看

最后祝鱼油们新年快乐,快快乐乐过大年
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

感谢楼主
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-17 22:39:38 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

回帖奖励 +10 鱼币

厉害!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

可以的很厉害
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

牛牛牛!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

回帖奖励 +10 鱼币

666
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币


感谢楼主!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

666
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

太强了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

厉害厉害
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-18 16:39:54 | 显示全部楼层
全世界特效最佳的Python教程
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

回帖奖励 +10 鱼币

666
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

回帖奖励 +10 鱼币

厉害
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-30 05:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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