|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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")
复制代码
求路过的到大佬看看
最后祝鱼油们新年快乐,快快乐乐过大年
|
|