diff --git a/missevan-kit/missevan-kit/missevan-kit.pro b/missevan-kit/missevan-kit/missevan-kit.pro
index 61cd6b8..4ca240d 100644
--- a/missevan-kit/missevan-kit/missevan-kit.pro
+++ b/missevan-kit/missevan-kit/missevan-kit.pro
@@ -1,8 +1,8 @@
#-------------------------------------------------
#
# Project created by Lewis Tian 2018-08-25T11:50:41
-# Email: lewissmith@126.com
-# Link: https://lewistian.github.io/
+# Email: taseikyo@gmail.com
+# Link: https://taseikyo.github.io/
#
#-------------------------------------------------
diff --git a/missevan-kit/missevan-kit/mwin.ui b/missevan-kit/missevan-kit/mwin.ui
index f6af9e7..fb27666 100644
--- a/missevan-kit/missevan-kit/mwin.ui
+++ b/missevan-kit/missevan-kit/mwin.ui
@@ -23,7 +23,7 @@
- 猫耳FM 1.0 - ©Tich
+ 猫耳FM
@@ -207,12 +207,12 @@
false
-
- 250
-
50
+
+ 250
+
true
@@ -222,12 +222,12 @@
false
-
- 30
-
35
+
+ 35
+
false
@@ -323,6 +323,13 @@
+ -
+
+
+ 清除已完成
+
+
+
diff --git a/missevan-kit/src/main.py b/missevan-kit/src/main.py
index 8853f48..60fc731 100644
--- a/missevan-kit/src/main.py
+++ b/missevan-kit/src/main.py
@@ -1,49 +1,73 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2018-08-25 12:51:53
-# @Author : Lewis Tian (chtian@hust.edu.cn)
-# @Link : https://lewistian.github.io/
+# @Author : Lewis Tian (taseikyo@gamil.com)
+# @Link : https://taseikyo.github.io/
# @Version : Python3.6
+"""
+搜索:
+https://www.missevan.com/dramaapi/search?s=关键字&page=1
+
+助眠分类搜索:
+https://www.missevan.com/sound/getsearch?s=关键字&p=1&type=3&page_size=30&cid=71
+
+主播音频列表:
+https://www.missevan.com/主播id/getusersound?page_size=10
+
+单个音频:
+https://www.missevan.com/sound/getsound?soundid=1530133
+
+我的关注:
+https://www.missevan.com/用户id/getuserattention?type=0&page_size=1000&p=1
+"""
+
from ui_mwin import Ui_MWin
from PyQt5 import QtCore
-from PyQt5.QtGui import QDesktopServices
+from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QMessageBox, QProgressBar
+from PyQt5.QtWidgets import (
+ QApplication,
+ QMainWindow,
+ QTableWidgetItem,
+ QMessageBox,
+ QProgressBar,
+)
+import os
import re
import sys
import requests
-import os
import threading
from contextlib import closing
import time
import random
base_headers = {
- 'Accept':'application/json, text/javascript, */*; q=0.01',
- 'Accept-Encoding':'gzip, deflate',
- 'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',
- 'Cache-Control':'no-cache',
- 'Connection':'keep-alive',
- 'Host':'www.missevan.com',
- 'Pragma':'no-cache',
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36',
- 'X-Requested-With':'XMLHttpRequest',
- }
+ "Accept": "application/json, text/javascript, */*; q=0.01",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6",
+ "Cache-Control": "no-cache",
+ "Connection": "keep-alive",
+ "Host": "www.missevan.com",
+ "Pragma": "no-cache",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
+ "X-Requested-With": "XMLHttpRequest",
+}
headers = {
- 'Accept':'*/*',
- 'Accept-Encoding':'gzip, deflate',
- 'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',
- 'Cache-Control':'no-cache',
- 'Connection':'keep-alive',
- 'Pragma':'no-cache',
- 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36',
- 'X-Requested-With':'ShockwaveFlash/30.0.0.113',
+ "Accept": "*/*",
+ "Accept-Encoding": "gzip, deflate",
+ "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6",
+ "Cache-Control": "no-cache",
+ "Connection": "keep-alive",
+ "Pragma": "no-cache",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
+ "X-Requested-With": "ShockwaveFlash/30.0.0.113",
}
listInfo = []
+
class MissevanKit(QMainWindow, Ui_MWin):
def __init__(self, parent=None):
super(MissevanKit, self).__init__(parent)
@@ -53,8 +77,8 @@ def __init__(self, parent=None):
self.tableWidget2.setColumnWidth(0, 350)
self.connectSlots()
- if not os.path.exists('sound'):
- os.mkdir('sound')
+ if not os.path.exists("sound"):
+ os.mkdir("sound")
def connectSlots(self):
"""connect slots with buttons/
@@ -67,16 +91,18 @@ def connectSlots(self):
self.search.clicked.connect(self.searchInfo)
self.search.setShortcut("CTRL+Return")
- self.toolButton.clicked.connect(lambda: QDesktopServices.openUrl(QUrl.fromLocalFile("./sound")))
+ self.toolButton.clicked.connect(
+ lambda: QDesktopServices.openUrl(QUrl.fromLocalFile("./sound"))
+ )
- # self.clearAll.clicked.connect(self.clearAllDownloaded)
+ # self.clearBtn.clicked.connect(self.clearAllDownloaded)
def searchInfo(self):
text = self.lineEdit.text()
if not text:
return
try:
- mid = re.findall(r'\d+', text)[-1]
+ mid = re.findall(r"\d+", text)[-1]
index = self.comboBox.currentIndex()
if index == 0:
self.getSoundSrc(mid)
@@ -87,43 +113,39 @@ def searchInfo(self):
except:
return
- def getSoundSrc(self, sid, single = True):
+ def getSoundSrc(self, sid, single=True):
"""获取对应sid的下载链接
single为假表示为列表,此时需要使用first来判断是否是列表第一个来清楚表格内容
"""
- url = f'http://www.missevan.com/sound/getsound?soundid={sid}'
- base_headers['Referer'] = f'http://www.missevan.com/sound/player?id={sid}'
- r = requests.get(url, headers = base_headers)
+ url = f"http://www.missevan.com/sound/getsound?soundid={sid}"
+ base_headers["Referer"] = f"http://www.missevan.com/sound/player?id={sid}"
+ r = requests.get(url, headers=base_headers)
data = r.json()
print(data)
- # if data['state'] == 'error':
- if not data['success']:
- print('getSoundSrc error')
+ if not data["success"]:
+ print("getSoundSrc error")
return
try:
- user = data['info']['user']['username']
+ user = data["info"]["user"]["username"]
except:
- user = 'user'
+ user = "user"
try:
- title = data['info']['sound']['soundstr']
+ title = data["info"]["sound"]["soundstr"]
except:
- title = 'title'
+ title = "title"
try:
- src = data['info']['sound']['soundurl']
+ src = data["info"]["sound"]["soundurl"]
except Exception as e:
- src = '-无法获取src/付费音频'
- info = f'{user} - {title}'
+ src = "error - 无法获取src/付费音频"
+ info = f"{user} - {title}"
print(info)
if single:
self.tableWidget.clearContents()
self.tableWidget.setRowCount(1)
- item = QTableWidgetItem(sid)
- self.tableWidget.setItem(0, 0, item)
- item = QTableWidgetItem(info)
- self.tableWidget.setItem(0, 1, item)
- item = QTableWidgetItem(src)
- self.tableWidget.setItem(0, 2, item)
- self.statusBar.showMessage('共1个音声')
+ self.tableWidget.setItem(0, 0, QTableWidgetItem(sid))
+ self.tableWidget.setItem(0, 1, QTableWidgetItem(info))
+ self.tableWidget.setItem(0, 2, QTableWidgetItem(src))
+ self.statusBar.showMessage("共1个音声")
else:
item = (sid, info, src)
listInfo.append(item)
@@ -134,14 +156,14 @@ def getListSrc(self, sound):
global listInfo
for x in sound:
self.getSoundSrc(x, False)
- time.sleep(0.1+random.randint(100, 200)/100)
+ time.sleep(0.1 + random.randint(100, 200) / 100)
self.tableWidget.clearContents()
self.tableWidget.setRowCount(len(listInfo))
for r, x in enumerate(listInfo):
for y in range(3):
item = QTableWidgetItem(x[y])
self.tableWidget.setItem(r, y, item)
- self.statusBar.showMessage('共{}个音声'.format(len(listInfo)))
+ self.statusBar.showMessage(f"共{len(listInfo)}个音声")
listInfo.clear()
def getUserSound(self, uid):
@@ -150,20 +172,23 @@ def getUserSound(self, uid):
p = 1
sound = []
while True:
- url = 'http://www.missevan.com/{uid}/getusersound?p={p}&page_size=30'.format(uid=uid, p=p)
- base_headers['Referer'] = 'http://www.missevan.com/{}/'.format(uid)
- r = requests.get(url, headers = base_headers)
- data = r.json()['info']['Datas']
+ url = f"http://www.missevan.com/{uid}/getusersound?p={p}&page_size=30"
+ base_headers["Referer"] = f"http://www.missevan.com/{uid}/"
+ r = requests.get(url, headers=base_headers)
+ data = r.json()["info"]["Datas"]
for x in data:
- count = x['view_count_formatted']
+ count = x["view_count_formatted"]
# if count.find('万') > 0 or count.find('-') >= 0: # 获取播放量大于1万的
# print("次数:",count, x['id'], x['soundstr'])
# sound.append(str(x['id']))
- sound.append(str(x['id']))
- if not r.json()['info']['pagination']['hasMore']:
+ sound.append(str(x["id"]))
+ if not r.json()["info"]["pagination"]["hasMore"]:
break
p += 1
- threading.Thread(target=self.getListSrc, args = (sound, )).start()
+ if not len(sound):
+ self.noSound()
+ return
+ threading.Thread(target=self.getListSrc, args=(sound,)).start()
def getLikeList(self, uid):
"""获取用户喜欢的声音列表
@@ -172,75 +197,92 @@ def getLikeList(self, uid):
p = 1
sound = []
while True:
- url = 'http://www.missevan.com/{uid}/getuserlike?p={p}&page_size=30'.format(uid=uid, p=p)
- base_headers['Referer'] = 'http://www.missevan.com/{}/'.format(uid)
- r = requests.get(url, headers = base_headers)
- # pprint(r.json())
- data = r.json()['info']['Datas']
+ url = f"http://www.missevan.com/{uid}/getuserlike?p={p}&page_size=30"
+ base_headers["Referer"] = f"http://www.missevan.com/{uid}/"
+ r = requests.get(url, headers=base_headers)
+ print(r.json())
+ data = r.json()["info"]["Datas"]
+ if not data:
+ break
for x in data:
- sound.append(str(x['id']))
- if not r.json()['info']['pagination']['hasMore']:
+ sound.append(str(x["id"]))
+ if not r.json()["info"]["pagination"]["hasMore"]:
break
p += 1
- threading.Thread(target=self.getListSrc, args = (sound, )).start()
+ if not len(sound):
+ self.noSound()
+ return
+ threading.Thread(target=self.getListSrc, args=(sound,)).start()
def downloadSound(self):
row = self.tableWidget.rowCount()
row2 = self.tableWidget2.rowCount()
- # self.tableWidget2.clearContents()
if not row:
return
- self.tableWidget2.setRowCount(1+row2)
+ self.tableWidget2.setRowCount(row + row2)
for x in range(row):
- item = QTableWidgetItem(self.tableWidget.item(x, 1).text())
- self.tableWidget2.setItem(x+row2, 0, item)
- self.tableWidget2.setItem(x+row2, 1, QTableWidgetItem("下载中"))
+ self.tableWidget2.setItem(x + row2, 0, QTableWidgetItem(self.tableWidget.item(x, 1).text()))
+ self.tableWidget2.setItem(x + row2, 1, QTableWidgetItem("下载中"))
# qpb = QProgressBar()
# qpb.setValue(0)
# self.tableWidget2.setCellWidget(x, 1, qpb)
- threading.Thread(target=self.downloadSingle, args = (x, row2)).start()
+ threading.Thread(target=self.downloadSingle, args=(x, row2+x)).start()
def downloadSingle(self, index, index2):
- '''index: table1的行数
+ """index: table1的行数
index2: table2的行数
src正常应该类似 201709/13/xxxxxx 若第一个字符为"-" 则说明获取资源失败
- '''
- print(self.tableWidget.item(index, 2).text())
- if self.tableWidget.item(index, 2).text()[0] == '-':
- self.tableWidget2.setItem(index, 1, QTableWidgetItem("付费音频/下载失败"))
+ """
+ url = self.tableWidget.item(index, 2).text()
+ print(url)
+ if url[0] == "e":
+ self.tableWidget2.setItem(index2, 1, QTableWidgetItem("付费音频/下载失败"))
return
- url = f'http://static.missevan.com/MP3/{self.tableWidget.item(index, 2).text()}'
- headers['Referer'] = f'http://www.missevan.com/sound/player?id={self.tableWidget.item(index, 0).text()}'
- title = self.tableWidget.item(index, 1).text().replace('/', '&')
- with closing(requests.get(url, headers = headers, timeout = 3, stream=True)) as r:
+ headers[
+ "Referer"
+ ] = f"http://www.missevan.com/sound/player?id={self.tableWidget.item(index, 0).text()}"
+ title = self.tableWidget.item(index, 1).text()
+ # 替换掉 windows 不允许出现的符号
+ title = re.sub(r"[/\\:*?<>|]", "", title)
+ with closing(requests.get(url, headers=headers, timeout=3, stream=True)) as r:
if r.status_code != 200:
+ self.tableWidget2.setItem(index2, 1, QTableWidgetItem("获取资源失败!"))
print(title, "获取资源失败!")
return
- content_size = int(r.headers['content-length']) # 内容体总大小
- chunk_size = int(content_size/100)
+ content_size = int(r.headers["content-length"]) # 内容体总大小
+ chunk_size = int(content_size / 100)
# count = 0
- with open(f'sound/{title}.mp3', "wb") as file:
+ with open(f"sound/{title}.mp3", "wb") as file:
try:
- for data in r.iter_content(chunk_size=chunk_size):
+ for data in r.iter_content(chunk_size=chunk_size):
file.write(data)
except Exception as e:
print(e)
- self.tableWidget2.setItem(index+index2, 1, QTableWidgetItem("下载失败"))
+ self.tableWidget2.setItem(
+ index2, 1, QTableWidgetItem("下载失败")
+ )
return
# count += len(data)
- self.tableWidget2.setItem(index+index2, 1, QTableWidgetItem("下载完成"))
+ self.tableWidget2.setItem(index2, 1, QTableWidgetItem("下载完成"))
def clearAllDownloaded(self):
row = self.tableWidget2.rowCount()
if not row:
return
- for x in range(row-1, -1, -1):
- if self.tableWidget2.item(x, 1).text() == '下载完成':
+ for x in range(row - 1, -1, -1):
+ if self.tableWidget2.item(x, 1).text() == "下载完成":
self.tableWidget2.removeRow(x)
+
+ def noSound(self):
+ self.statusBar.showMessage("共0个音声")
+ self.tableWidget.clearContents()
+ self.tableWidget.setRowCount(0)
+
+
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MissevanKit()
w.show()
- sys.exit(app.exec_())
\ No newline at end of file
+ sys.exit(app.exec_())