mirror of
https://github.com/2061360308/NeteaseCloudMusic_PythonSDK.git
synced 2024-11-24 15:59:19 +00:00
chore:update publish.yml
This commit is contained in:
parent
f34639a9ce
commit
fb1d5fa298
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.1.8
|
||||
current_version = 0.1.7
|
||||
commit = True
|
||||
tag = True
|
||||
|
||||
|
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: |
|
||||
cd package
|
||||
python setup.py build
|
||||
python setup.py upload
|
||||
ls ./dist/
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
|
@ -17,6 +17,7 @@ Description-Content-Type: text/markdown
|
||||
License-File: LICENSE
|
||||
|
||||
|
||||
|
||||
# NeteaseCloudMusic_PythonSDK
|
||||
> 基于 [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 封装的 Python SDK。
|
||||
> 网易云API Python版本。
|
||||
@ -54,15 +55,48 @@ print(api_list())
|
||||
|
||||
> 注意: request(self, name, query=None) 的第一个参数为API名称,第二个参数为API参数,具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com),name支持`/song/url/v1`和`song_url_v1`两种写法。
|
||||
|
||||
> api已加入自动缓存,在测试接口时,如果频繁调用获取结果在query里应该加上timestamp参数来区分,例如
|
||||
> ```python
|
||||
> response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh", "timestamp": time.time()})
|
||||
> ```
|
||||
|
||||
### 开发
|
||||
- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git`
|
||||
- 安装依赖 `pip install -r requirements.txt`
|
||||
- 目录/文件说明
|
||||
```
|
||||
├── package 项目包根目录
|
||||
├── test_gender 生成测试代码的脚本
|
||||
├── test.py 手动测试/ 使用示例
|
||||
```
|
||||
|
||||
### 更新
|
||||
项目使用towncrier自动生成更新日志
|
||||
|
||||
在 newsfragments 目录下,创建一个新的文本文件。这个文件的名字应该是一个唯一的编号,后缀是 .rst。
|
||||
例如,如果你正在处理编号为 123 的问题,你可以创建一个名为 123.feature.rst 的文件。
|
||||
|
||||
注意在 towncrier 中,新闻片段的类型通常由文件名的后缀决定。以下是一些常见的新闻片段类型:
|
||||
- .feature: 用于描述新的特性或者功能。
|
||||
- .bugfix: 用于描述一个 bug 修复。
|
||||
- .doc: 用于描述文档的更改。
|
||||
- .removal: 用于描述移除的特性或者功能。
|
||||
- .misc: 用于描述其他类型的更改。
|
||||
-
|
||||
在这个文件中,写下你的更改的描述。这个描述应该是简短的,通常只有一到两句话。
|
||||
例如`Added support for the XYZ feature.`
|
||||
|
||||
### 发布新版本
|
||||
使用bumpversion自动更新版本号,提交并发布标签
|
||||
你需要安装bumpversion然后执行
|
||||
```bash
|
||||
bumpversion patch # for a patch level increase (e.g., 1.0.0 to 1.0.1)
|
||||
bumpversion minor # for a minor level increase (e.g., 1.0.0 to 1.1.0)
|
||||
bumpversion major # for a major level increase (e.g., 1.0.0 to 2.0.0)
|
||||
```
|
||||
|
||||
接下来会自动更新版本号并提交到远程仓库,然后发布一个新的标签
|
||||
workflow会依据标签自动发布相应资源并且发布到pypi
|
||||
|
||||
### 改进
|
||||
> 下列API未支持
|
||||
@ -107,3 +141,8 @@ print(api_list())
|
||||
- /fm_trash
|
||||
|
||||
### 欢迎提交PR
|
||||
|
||||
更正request库返回多个cookie时自动用分号拼接导致后续cookie不好解析的问题
|
||||
添加了对cookie中Max-Age为0的处理
|
||||
改进判断cookie是否过期的逻辑
|
||||
添加了自动处理cookie的更新操作
|
||||
|
@ -7,6 +7,7 @@ NeteaseCloudMusic/__init__.py
|
||||
NeteaseCloudMusic/config.json
|
||||
NeteaseCloudMusic/help.py
|
||||
NeteaseCloudMusic/main.py
|
||||
NeteaseCloudMusic/utils.py
|
||||
NeteaseCloudMusic.egg-info/PKG-INFO
|
||||
NeteaseCloudMusic.egg-info/SOURCES.txt
|
||||
NeteaseCloudMusic.egg-info/dependency_links.txt
|
||||
|
@ -1,2 +1,3 @@
|
||||
py_mini_racer
|
||||
requests
|
||||
diskcache
|
||||
|
@ -2,4 +2,4 @@ from .main import NeteaseCloudMusicApi
|
||||
from .help import api_help, api_list
|
||||
from .utils import format_cookie_str, prase_cookie_str
|
||||
|
||||
__version__ = '0.1.8'
|
||||
__version__ = '0.1.7'
|
||||
|
@ -35,15 +35,48 @@ print(api_list())
|
||||
|
||||
> 注意: request(self, name, query=None) 的第一个参数为API名称,第二个参数为API参数,具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com),name支持`/song/url/v1`和`song_url_v1`两种写法。
|
||||
|
||||
> api已加入自动缓存,在测试接口时,如果频繁调用获取结果在query里应该加上timestamp参数来区分,例如
|
||||
> ```python
|
||||
> response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh", "timestamp": time.time()})
|
||||
> ```
|
||||
|
||||
### 开发
|
||||
- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git`
|
||||
- 安装依赖 `pip install -r requirements.txt`
|
||||
- 目录/文件说明
|
||||
```
|
||||
├── package 项目包根目录
|
||||
├── test_gender 生成测试代码的脚本
|
||||
├── test.py 手动测试/ 使用示例
|
||||
```
|
||||
|
||||
### 更新
|
||||
项目使用towncrier自动生成更新日志
|
||||
|
||||
在 newsfragments 目录下,创建一个新的文本文件。这个文件的名字应该是一个唯一的编号,后缀是 .rst。
|
||||
例如,如果你正在处理编号为 123 的问题,你可以创建一个名为 123.feature.rst 的文件。
|
||||
|
||||
注意在 towncrier 中,新闻片段的类型通常由文件名的后缀决定。以下是一些常见的新闻片段类型:
|
||||
- .feature: 用于描述新的特性或者功能。
|
||||
- .bugfix: 用于描述一个 bug 修复。
|
||||
- .doc: 用于描述文档的更改。
|
||||
- .removal: 用于描述移除的特性或者功能。
|
||||
- .misc: 用于描述其他类型的更改。
|
||||
-
|
||||
在这个文件中,写下你的更改的描述。这个描述应该是简短的,通常只有一到两句话。
|
||||
例如`Added support for the XYZ feature.`
|
||||
|
||||
### 发布新版本
|
||||
使用bumpversion自动更新版本号,提交并发布标签
|
||||
你需要安装bumpversion然后执行
|
||||
```bash
|
||||
bumpversion patch # for a patch level increase (e.g., 1.0.0 to 1.0.1)
|
||||
bumpversion minor # for a minor level increase (e.g., 1.0.0 to 1.1.0)
|
||||
bumpversion major # for a major level increase (e.g., 1.0.0 to 2.0.0)
|
||||
```
|
||||
|
||||
接下来会自动更新版本号并提交到远程仓库,然后发布一个新的标签
|
||||
workflow会依据标签自动发布相应资源并且发布到pypi
|
||||
|
||||
### 改进
|
||||
> 下列API未支持
|
||||
@ -88,3 +121,8 @@ print(api_list())
|
||||
- /fm_trash
|
||||
|
||||
### 欢迎提交PR
|
||||
|
||||
更正request库返回多个cookie时自动用分号拼接导致后续cookie不好解析的问题
|
||||
添加了对cookie中Max-Age为0的处理
|
||||
改进判断cookie是否过期的逻辑
|
||||
添加了自动处理cookie的更新操作
|
||||
|
@ -44,6 +44,7 @@ if (typeof window === "undefined") {
|
||||
}
|
||||
|
||||
function encodeURIComponent(str) {
|
||||
str = String(str); // 将输入转换为字符串 以免True,False等非字符无法转换
|
||||
var result = "";
|
||||
|
||||
if (str !== undefined && str !== null) {
|
||||
@ -37928,7 +37929,7 @@ const hug_comment_resourceTypeMap = config_namespaceObject.A;
|
||||
});
|
||||
|
||||
;// CONCATENATED MODULE: ./package.json
|
||||
const package_namespaceObject = {"i8":"0.1.1"};
|
||||
const package_namespaceObject = {"i8":"0.1.2"};
|
||||
;// CONCATENATED MODULE: ./module/inner_version.js
|
||||
|
||||
/* harmony default export */ const inner_version = ((query, request) => {
|
||||
@ -38338,30 +38339,19 @@ var crypto_js = __webpack_require__(1292);
|
||||
;// CONCATENATED MODULE: ./module/login_refresh.js
|
||||
// 登录刷新
|
||||
|
||||
/* harmony default export */ const login_refresh = (async (query, request) => {
|
||||
let result = await request(
|
||||
'POST',
|
||||
/* harmony default export */ const login_refresh = ((query, request) => {
|
||||
return request(
|
||||
"POST",
|
||||
`https://music.163.com/weapi/login/token/refresh`,
|
||||
{},
|
||||
{
|
||||
crypto: 'weapi',
|
||||
ua: 'pc',
|
||||
crypto: "weapi",
|
||||
ua: "pc",
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
},
|
||||
)
|
||||
if (result.body.code === 200) {
|
||||
result = {
|
||||
status: 200,
|
||||
body: {
|
||||
...result.body,
|
||||
cookie: result.cookie.join(';'),
|
||||
},
|
||||
cookie: result.cookie,
|
||||
}
|
||||
}
|
||||
return result
|
||||
);
|
||||
});
|
||||
|
||||
;// CONCATENATED MODULE: ./module/login_status.js
|
||||
@ -42852,6 +42842,7 @@ const weapi = (object) => {
|
||||
for (let i = 0; i < 16; i++) {
|
||||
secretKey += base62.charAt(Math.round(Math.random() * 61))
|
||||
}
|
||||
|
||||
return {
|
||||
params: aesEncrypt(
|
||||
aesEncrypt(text, 'cbc', presetKey, iv),
|
||||
@ -43181,6 +43172,27 @@ function beforeRequest(name, query) {
|
||||
return response;
|
||||
});
|
||||
|
||||
;// CONCATENATED MODULE: ./afterRequest/login_refresh.js
|
||||
/* harmony default export */ const afterRequest_login_refresh = ((response) => {
|
||||
response = JSON.parse(response);
|
||||
let cookie = response.cookie;
|
||||
if (Array.isArray(cookie)) {
|
||||
cookie = cookie.join(";");
|
||||
}
|
||||
if (response.body.code === 200) {
|
||||
response = {
|
||||
status: 200,
|
||||
body: {
|
||||
...response.body,
|
||||
cookie: cookie,
|
||||
},
|
||||
cookie: cookie,
|
||||
};
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
;// CONCATENATED MODULE: ./afterRequest/login_status.js
|
||||
/* harmony default export */ const afterRequest_login_status = ((response) => {
|
||||
response = JSON.parse(response);
|
||||
@ -43255,9 +43267,11 @@ function beforeRequest(name, query) {
|
||||
|
||||
|
||||
|
||||
|
||||
/* harmony default export */ const afterRequestApi = ({
|
||||
'check_music':afterRequest_check_music,
|
||||
'login_cellphone':afterRequest_login_cellphone,
|
||||
'login_refresh':afterRequest_login_refresh,
|
||||
'login_status':afterRequest_login_status,
|
||||
'related_playlist':afterRequest_related_playlist,
|
||||
'top_playlist':afterRequest_top_playlist,
|
||||
|
@ -1,2 +1,5 @@
|
||||
from .main import NeteaseCloudMusicApi
|
||||
from .help import api_help, api_list
|
||||
from .utils import format_cookie_str, prase_cookie_str
|
||||
|
||||
__version__ = '0.1.7'
|
||||
|
@ -1,26 +1,36 @@
|
||||
import json
|
||||
import os.path
|
||||
import socket
|
||||
import time
|
||||
from pprint import pprint
|
||||
import http.cookies
|
||||
import datetime
|
||||
from diskcache import Cache
|
||||
|
||||
import pkg_resources
|
||||
import requests
|
||||
from py_mini_racer import py_mini_racer
|
||||
from .help import api_list
|
||||
from .utils import format_cookie_str, prase_cookie_str
|
||||
import urllib.parse
|
||||
|
||||
|
||||
class NeteaseCloudMusicApi:
|
||||
__cookie = None
|
||||
__ip = None
|
||||
|
||||
def __init__(self, debug=False):
|
||||
cache = Cache('cache', timeout=120) # 设置缓存目录和过期时间
|
||||
|
||||
# cache = TTLCache(maxsize=100, ttl=120) # 设置缓存大小为100,缓存项的生存时间为120秒
|
||||
|
||||
def __init__(self, debug=False, cache=False):
|
||||
self.DEBUG = debug # 是否开启调试模式
|
||||
self.CACHE = cache # 是否开启缓存
|
||||
|
||||
self.special_api = {"/playlist/track/all": self.playlist_track_all,
|
||||
"/login/cellphone": self.login_cellphone,
|
||||
"/inner/version": self.inner_version}
|
||||
"/inner/version": self.inner_version,
|
||||
"/login/refresh": self.login_refresh}
|
||||
|
||||
# 载入js代码
|
||||
resource_path = pkg_resources.resource_filename(__name__, 'NeteaseCloudMusicApi.js')
|
||||
@ -66,8 +76,21 @@ class NeteaseCloudMusicApi:
|
||||
if name not in yubei_special.values():
|
||||
raise Exception(f"apiName: {name} not found,please use ”api_list()“ to view the interface list")
|
||||
|
||||
# 生成一个唯一的键,用于在缓存中查找结果
|
||||
cache_key = (name, frozenset(query.items()) if query else None)
|
||||
|
||||
if self.CACHE:
|
||||
# 检查缓存中是否已经有了结果
|
||||
if self.cache.get(cache_key):
|
||||
return self.cache.get(cache_key)
|
||||
|
||||
if query is None:
|
||||
query = {}
|
||||
else:
|
||||
# 如果存在timestamp参数,那么删除它
|
||||
if query.get("timestamp"):
|
||||
del query["timestamp"]
|
||||
|
||||
if query.get("cookie") is None:
|
||||
query["cookie"] = self.cookie
|
||||
|
||||
@ -82,7 +105,9 @@ class NeteaseCloudMusicApi:
|
||||
else:
|
||||
result = self.call_api(name, query)
|
||||
|
||||
#
|
||||
if self.CACHE:
|
||||
# 将结果存入缓存
|
||||
self.cache.set(cache_key, result)
|
||||
|
||||
return result
|
||||
|
||||
@ -105,46 +130,47 @@ class NeteaseCloudMusicApi:
|
||||
if self.__cookie is None:
|
||||
if os.path.isfile("cookie_storage"):
|
||||
with open("cookie_storage", "r", encoding='utf-8') as f:
|
||||
self.cookie = f.read()
|
||||
content = f.read()
|
||||
try:
|
||||
cookie_storage = json.loads(content)
|
||||
# 验证cookie是否过期
|
||||
create_time_stamp = cookie_storage['create_time_stamp']
|
||||
|
||||
if time.time() - create_time_stamp > 1296010:
|
||||
# cookie过期了
|
||||
self.__cookie = ""
|
||||
else:
|
||||
# 判断cookie生成时间是否超过1天
|
||||
if time.time() - create_time_stamp > 86400:
|
||||
# 更新cookie
|
||||
# Todo login_refresh接口返回cookie好像少一些值
|
||||
# self.request("/login/refresh", {"cookie": cookie_storage['cookie'], "timestamp": time.time()})
|
||||
self.cookie = cookie_storage['cookie']
|
||||
else:
|
||||
self.__cookie = cookie_storage['cookie']
|
||||
except json.JSONDecodeError and KeyError:
|
||||
self.__cookie = ""
|
||||
else:
|
||||
self.__cookie = "" # 如果没有cookie文件,就设置为空
|
||||
|
||||
return self.__cookie
|
||||
|
||||
@cookie.setter
|
||||
def cookie(self, cookie):
|
||||
if cookie is None:
|
||||
cookie = ""
|
||||
def cookie(self, value):
|
||||
if value is None:
|
||||
self.__cookie = ""
|
||||
return
|
||||
|
||||
_cookie = cookie
|
||||
"判断cookie是否合法, 简单检查一下关键的键"
|
||||
necessary_keys = ["__csrf", "MUSIC_A_T", "MUSIC_R_T"]
|
||||
cookie_dict = prase_cookie_str(value)
|
||||
for key in necessary_keys:
|
||||
if cookie_dict.get(key) is None:
|
||||
raise Exception(f"cookie is illegal, missing key: {key}.")
|
||||
|
||||
'''判断cookie是否过期'''
|
||||
|
||||
# 创建一个Morsel对象,它可以解析cookie字符串
|
||||
morsel = http.cookies.SimpleCookie(cookie)
|
||||
# 获取当前时间
|
||||
now = datetime.datetime.now()
|
||||
|
||||
# 只判断 __csrf 是否过期
|
||||
if not morsel.get('__csrf'):
|
||||
# __csrf 不存在,不是有效cookie
|
||||
_cookie = ""
|
||||
else:
|
||||
# 将过期时间字符串转换为datetime对象
|
||||
expires = morsel.get('__csrf')['expires']
|
||||
expires_datetime = datetime.datetime.strptime(expires, "%a, %d %b %Y %H:%M:%S GMT")
|
||||
|
||||
# 判断cookie是否过期
|
||||
if now > expires_datetime:
|
||||
# 过期了
|
||||
_cookie = ""
|
||||
else:
|
||||
# 未过期
|
||||
pass
|
||||
|
||||
self.__cookie = _cookie
|
||||
self.__cookie = value
|
||||
with open("cookie_storage", "w+", encoding='utf-8') as f:
|
||||
f.write(_cookie)
|
||||
f.write(json.dumps({"cookie": value, "create_time_stamp": time.time()}, indent=2, ensure_ascii=False))
|
||||
|
||||
@property
|
||||
def ip(self):
|
||||
@ -155,18 +181,17 @@ class NeteaseCloudMusicApi:
|
||||
def call_api(self, name, query):
|
||||
request_param = self.ctx.call('NeteaseCloudMusicApi.beforeRequest', name, query) # 拿到请求头和请求参数
|
||||
|
||||
# Todo 了解 py_mini_racer 返回没有自动编码 而 node可以
|
||||
param_data = {}
|
||||
if request_param["data"] != "":
|
||||
for item in request_param["data"].split("&"):
|
||||
# param_data[item.split("=")[0]] = urllib.parse.quote(item.split("=")[1], safe='') # 不需要编码后反而出错
|
||||
param_data[item.split("=")[0]] = item.split("=")[1]
|
||||
|
||||
# print("url", request_param["url"], "data", param_data, "headers\n", json.dumps(request_param["headers"], indent=2, ensure_ascii=False))
|
||||
|
||||
if request_param.get("method") == "GET":
|
||||
response = requests.get(request_param["url"], params=param_data, headers=request_param["headers"])
|
||||
else:
|
||||
response = requests.post(request_param["url"], data=param_data, headers=request_param["headers"])
|
||||
# response = requests.post(request_param["url"], data=param_data, headers=request_param["headers"])
|
||||
|
||||
try:
|
||||
data = json.loads(response.text)
|
||||
@ -179,12 +204,6 @@ class NeteaseCloudMusicApi:
|
||||
"status": response.status_code,
|
||||
}
|
||||
|
||||
# print("headers", response.headers)
|
||||
# print("headers_dict", dict(response.headers))
|
||||
|
||||
# with open("response_result.json", "w+", encoding='utf-8') as f:
|
||||
# f.write(json.dumps(response_result, indent=2, ensure_ascii=False))
|
||||
|
||||
result = self.ctx.call('NeteaseCloudMusicApi.afterRequest',
|
||||
json.dumps(response_result),
|
||||
request_param.get('crypto', None),
|
||||
@ -230,8 +249,29 @@ class NeteaseCloudMusicApi:
|
||||
"""
|
||||
result = self.call_api("/login/cellphone", query)
|
||||
|
||||
# 自动 填充cookie
|
||||
# 自动 更新cookie
|
||||
if result["code"] == 200:
|
||||
if result.get("data").get("cookie"):
|
||||
self.cookie = result.get("data").get("cookie")
|
||||
# cookie_str = format_cookie_str(result.get("data").get("cookie"))
|
||||
cookie_str = result.get("data").get("cookie")
|
||||
result["data"]["cookie"] = cookie_str
|
||||
self.cookie = cookie_str
|
||||
return result
|
||||
|
||||
def login_refresh(self, query):
|
||||
"""
|
||||
刷新登录状态
|
||||
:param query:
|
||||
:return:
|
||||
"""
|
||||
result = self.call_api("/login/refresh", query)
|
||||
|
||||
# 自动 更新cookie
|
||||
# if result["code"] == 200:
|
||||
# if result.get("data").get("cookie"):
|
||||
# # cookie_str = format_cookie_str(result.get("data").get("cookie"))
|
||||
# cookie_str = result.get("data").get("cookie")
|
||||
# result["data"]["cookie"] = cookie_str
|
||||
# pprint(cookie_str)
|
||||
# self.cookie = cookie_str
|
||||
return result
|
||||
|
124
package/build/lib/NeteaseCloudMusic/utils.py
Normal file
124
package/build/lib/NeteaseCloudMusic/utils.py
Normal file
@ -0,0 +1,124 @@
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
def format_cookie_str(cookie_str: str) -> str:
|
||||
"""
|
||||
格式化cookie字符串
|
||||
功能
|
||||
处理以逗号分割的cookie字符串
|
||||
删除max-age为0的cookie
|
||||
注意:
|
||||
传入cookie字符串必须是以 逗号+空格 或 分号+空格 分割的规范cookie字符串
|
||||
:param cookie_str:
|
||||
:return: 格式化后的cookie str
|
||||
"""
|
||||
|
||||
if not cookie_str:
|
||||
return ""
|
||||
|
||||
# 解析cookie字符串
|
||||
cookie_dict = prase_cookie_str(cookie_str)
|
||||
|
||||
cookie_valid_dict = {}
|
||||
# 删除max-age为0的cookie
|
||||
for item in cookie_dict.keys():
|
||||
max_age = cookie_dict[item].get("Max-Age")
|
||||
if max_age:
|
||||
max_age = int(max_age)
|
||||
if max_age != 0:
|
||||
cookie_valid_dict[item] = cookie_dict[item]
|
||||
|
||||
# 重新拼接cookie字符串
|
||||
cookie = ""
|
||||
for item in cookie_valid_dict.keys():
|
||||
cookie += item + "=" + cookie_valid_dict[item]["value"] + "; "
|
||||
for key in cookie_valid_dict[item].keys():
|
||||
if key != "value":
|
||||
cookie += key + "=" + cookie_valid_dict[item][key] + "; "
|
||||
|
||||
return cookie[: -2]
|
||||
|
||||
|
||||
def prase_cookie_str(cookie_str: str) -> dict:
|
||||
"""
|
||||
解析cookie字符串
|
||||
功能
|
||||
处理以逗号分割的cookie字符串
|
||||
注意:
|
||||
传入cookie字符串必须是以 逗号+空格 或 分号+空格 分割的规范cookie字符串
|
||||
:param cookie_str:
|
||||
:return: cookie dict
|
||||
"""
|
||||
if not cookie_str:
|
||||
return {}
|
||||
|
||||
# 解决用逗号分割的问题
|
||||
cookie_part = []
|
||||
for item in cookie_str.split(", "):
|
||||
cookie_part.extend(item.split("; "))
|
||||
|
||||
cookies = []
|
||||
for item in cookie_part:
|
||||
if "=" not in item:
|
||||
# 属于上一个cookie的一部分
|
||||
cookies[-1] = cookies[-1] + item
|
||||
else:
|
||||
cookies.append(item)
|
||||
|
||||
cookie_dict = {}
|
||||
|
||||
current_name = ""
|
||||
for cookie in cookies:
|
||||
# print(cookie)
|
||||
if cookie[-1] == "=":
|
||||
name = cookie[:-1]
|
||||
value = ""
|
||||
else:
|
||||
part = cookie.split("=")
|
||||
name = part[0]
|
||||
value = part[1]
|
||||
|
||||
if name in ["Max-Age", "Expires", "Path", "Domain"]:
|
||||
cookie_dict[current_name][name] = value
|
||||
else:
|
||||
cookie_dict[name] = {"value": value}
|
||||
current_name = name
|
||||
|
||||
return cookie_dict
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cookie = ("MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/openapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
|
||||
"02 Jan 2092 11:39:38 GMT; Path=/wapi/feedback; Domain=.music.163.com, __remember_me=true; "
|
||||
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/; Domain=.music.163.com, "
|
||||
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/api/feedback; "
|
||||
"Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/eapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
|
||||
"02 Jan 2092 11:39:38 GMT; Path=/api/clientlog; Domain=.music.163.com, MUSIC_R_T=1579622000495; "
|
||||
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/wapi/feedback; Domain=.music.163.com, "
|
||||
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/weapi/clientlog; "
|
||||
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/neapi/feedback; Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, "
|
||||
"02 Jan 2092 11:39:38 GMT; Path=/eapi/clientlog; Domain=.music.163.com, MUSIC_R_T=1579622000495; "
|
||||
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/api/feedback; Domain=.music.163.com, "
|
||||
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/weapi/feedback; "
|
||||
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/eapi/feedback; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
|
||||
"02 Jan 2092 11:39:38 GMT; Path=/neapi/clientlog; Domain=.music.163.com, MUSIC_R_T=1579622000495; "
|
||||
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/wapi/clientlog; Domain=.music.163.com, "
|
||||
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/wapi/clientlog; "
|
||||
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/weapi/feedback; Domain=.music.163.com, NMTID=00OLqRn-wykrFFXdElLpZA3_-aaQtIAAAGMbJSp9A; "
|
||||
"Max-Age=315360000; Expires=Mon, 12 Dec 2033 08:25:31 GMT; Path=/; Domain=music.163.com, "
|
||||
"__csrf=4d5e515015723fd3d7edaa5b05f35b4d; Max-Age=1296010; Expires=Sat, 30 Dec 2023 08:25:41 GMT; Path=/; "
|
||||
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/neapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
|
||||
"02 Jan 2092 11:39:38 GMT; Path=/openapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; "
|
||||
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/eapi/feedback; Domain=.music.163.com, "
|
||||
"MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/weapi/clientlog; "
|
||||
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
|
||||
"Path=/api/clientlog; Domain=.music.163.com, MUSIC_SNS=; Max-Age=0; Expires=Fri, 15 Dec 2023 08:25:31 GMT; "
|
||||
"Path=/, "
|
||||
"MUSIC_U=00CCEEF2F7A9825637C9869A455B5CA8E009D905415134A7EDAC2E404A940B2D58BFF7129A413193E9A8FD6D1D497E1E8E9023611BA91D2CB28FA94B53DBE4C42699A30FF1448C8EFAF5B00E73ADD353C52F2E004C094AEAC4BA4D83C6FFBB4CD532DEEAEA8D5584E69AC78110BBA682829C263DA72F5AA290AD826A47F640CA3903AC652E4DDE946ACC4EB8A63E5853FA695B480A919CF84498B7084C5CA9A91297F2CF5AF45C2D545AC0D5C03A1641306BAC0FB6FFD57BC653A91F2483FB52BFE85DE39280B012BC036DF244883D9700480E5FDDCD5A417C60241AE08CD6AA84BFC1C8890AE4A08286144D9D1146E33C67CF7797CDB5A961C85DB5AC492B232601D80D4DB07E4F170F635ABC01E080B4D32408FA0698DAD95AD80CDB99F2F672638048F5116214319175B596BF68B2A7A0269746EABFD919D62C165353725E6B1253A7C5D6774D453DDDCC28524D3378; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/neapi/feedback; Domain=.music.163.com")
|
||||
pprint(prase_cookie_str(cookie))
|
Binary file not shown.
BIN
package/dist/NeteaseCloudMusic-0.1.7.tar.gz
vendored
BIN
package/dist/NeteaseCloudMusic-0.1.7.tar.gz
vendored
Binary file not shown.
@ -19,7 +19,7 @@ URL = 'https://github.com/2061360308/NeteaseCloudMusic_PythonSDK'
|
||||
EMAIL = '2061360308@qq.com'
|
||||
AUTHOR = '盧瞳'
|
||||
REQUIRES_PYTHON = '>=3.6.0'
|
||||
VERSION = '0.1.8'
|
||||
VERSION = '0.1.7'
|
||||
UPDATA_INFO = ('修复了初次使用时没有cookie导致的一系列问题\n'
|
||||
'修复了NeteaseCloudMusicApi.js没有更新的问题\n'
|
||||
'添加了对于cookie的判断,现在可以正常判断cookie是否过期了')
|
||||
@ -114,13 +114,6 @@ class UploadCommand(Command):
|
||||
self.status('Building Source and Wheel (universal) distribution…')
|
||||
os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))
|
||||
|
||||
self.status('Uploading the package to PyPI via Twine…')
|
||||
os.system('twine upload dist/*')
|
||||
|
||||
self.status('Pushing git tags…')
|
||||
os.system(f'git tag -a {about["__version__"]} -m {UPDATA_INFO}')
|
||||
os.system('git push --tags')
|
||||
|
||||
sys.exit()
|
||||
|
||||
|
||||
@ -193,6 +186,5 @@ setup(
|
||||
# $ setup.py publish support.
|
||||
cmdclass={
|
||||
'upload': UploadCommand,
|
||||
'build': BuildCommand,
|
||||
},
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user