fix:fix errors encountered during initial startup without cookies

This commit is contained in:
2061360308 2023-12-15 15:55:04 +08:00
parent 2af84ab8ff
commit 40d96dcbe8
13 changed files with 789 additions and 410 deletions

View File

@ -17,13 +17,13 @@
### 使用 ### 使用
- 安装 `pip install NeteaseCloudMusic` - 安装 `pip install NeteaseCloudMusic`
- 导入API进行使用(具体查看`test.py`中的示例) - 导入API进行使用(具体查看`example.py`中的示例)
```python ```python
from NeteaseCloudMusic import NeteaseCloudMusicApi, api_help, api_list from NeteaseCloudMusic import NeteaseCloudMusicApi, api_help, api_list
import os import os
netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API
netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie netease_cloud_music_api.cookie = "你的cookie" # 设置cookie 如果没有cookie需要先登录 具体见example.py
response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh"}) # 调用API response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh"}) # 调用API
# 获取帮助 # 获取帮助

View File

@ -307763,5 +307763,15 @@
"result": {} "result": {}
} }
] ]
},
"/login/status": {
"name": "登录状态",
"explain": "说明 : 调用此接口,可获取登录状态",
"example": [
{
"query":{},
"result": {}
}
]
} }
} }

110
example.py Normal file
View File

@ -0,0 +1,110 @@
"""
description: 网易云音乐API使用示例,这个示例引导你进行登录操作然后下载一首歌曲
author: LuTong
date: 2020-10-07 10:00
"""
from pprint import pprint
import requests
from package.NeteaseCloudMusic import NeteaseCloudMusicApi, api_help, api_list
netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API
def captcha_sent(_phone):
response = netease_cloud_music_api.request("/captcha/sent", {"phone": f"{_phone}"})
return response
def login_cellphone(_phone, _captcha):
response = netease_cloud_music_api.request("/login/cellphone", {"phone": f"{_phone}", "captcha": f"{_captcha}"})
return response
def song_url_v1(song_id):
# 获取歌曲mp3地址
response = netease_cloud_music_api.request("song_url_v1", {"id": song_id, "level": "exhigh"})
return response
def song_detail(song_id):
# 获取歌曲详情
response = netease_cloud_music_api.request("song_detail", {"ids": str(song_id)})
# 这里记得传一个字符串,其实所有参数都传字符串就行,需要数字的话内部会自己转换的,但是它默认你传入的时候是字符串,所以你传数字他不会自动转字符串,
# 这时如果遇到操作字符串的方法就会报错,所以最好都传字符串,避免出现意外
return response
def login_status():
response = netease_cloud_music_api.request("/login/status")
return response
# 登录
if not netease_cloud_music_api.cookie:
print("请设置cookie")
phone = input("请输入手机号:")
result = captcha_sent(phone)
print(result)
if result.get("code") == 200:
print("验证码已发送,请查收")
captcha = input("请输入验证码:")
result = login_cellphone(phone, captcha)
if result.get("code") == 200:
print("登录成功")
if netease_cloud_music_api.cookie:
print("cookie已自动设置")
else:
print("登录失败")
"""
调用登录接口后会自动设置cookie如果cookie失效需要重新登录登录过后api会在你的当前工作目录下创建cookie_storage文件保存你的cookie
在下次调用运行程序时他会判断cookie是否过期没有过期就自动读取cookie_storage文件中的cookie
总的来说你不需要手动管理cookie只需要调用登录接口然后调用其他接口即可cookie会自动设置如果cookie过期再次调用登录接口就好
更好的办法是在cookie还没有失效之前使用refresh_login接口刷新cookie这样就不需要重新登录了建议在你每次启动软件时都刷新当然频繁重启调试的时候另算
如果你想判断当前是否已经登录if not netease_cloud_music_api.cookie 就可以了或者调用/login/status接口
"""
# 获取登录状态
login_status_result = login_status()
# pprint(login_status_result)
if login_status_result['data']['data']["code"] == 200:
print(f'当前登录账号:{login_status_result["data"]["data"]["profile"]["nickname"]}')
version_result = netease_cloud_music_api.request("inner_version")
print(
f'当前使用NeteaseCloudMusicApi版本号{version_result["NeteaseCloudMusicApi"]}\n当前使用NeteaseCloudMusicApi_V8版本号{version_result["NeteaseCloudMusicApi_V8"]}') # 退出登录
# 获取歌曲mp3地址
song_url_result = song_url_v1(33894312)
if song_url_result.get("code") == 200:
song_url = song_url_result['data']["data"][0]['url']
else:
print("获取歌曲mp3地址失败")
exit(1)
# 获取歌曲详情
song_detail_result = song_detail(33894312)
if song_detail_result.get("code") == 200:
song_name = song_detail_result['data']['songs'][0]['name']
song_artist = song_detail_result['data']['songs'][0]['ar'][0]['name']
else:
print("获取歌曲详情失败")
exit(1)
# 下载歌曲mp3
print(f"正在下载歌曲:{song_name} - {song_artist}")
result = requests.get(song_url)
with open(f"{song_name} - {song_artist}.mp3", "wb") as f:
f.write(result.content)
print("下载完成")
"""
示例程序结束如果你运行成功了那么你的执行目录下应该有一个cookie_storage文件里面保存了你的cookie还有一个mp3文件就是你下载的歌曲
有关其他API的使用方法请参考https://docs.neteasecloudmusicapi.binaryify.com/
再次注明一下我之前也想过要不要将登录状态管理和cookie刷新等等封装到NeteaseCloudMusicApi类中
但最后我想的是这毕竟这是一个api接口类就让他保持最原始简洁的状态就好其他的留给大家去自由发挥吧
友情提示单个账户每天发送验证码的次数有限制千万别一直调试登录接口
"""

View File

@ -1,6 +1,6 @@
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: NeteaseCloudMusic Name: NeteaseCloudMusic
Version: 0.1.3 Version: 0.1.4
Summary: 网易云音乐API NeteaseCloudMusicApi项目的 Python SDK Summary: 网易云音乐API NeteaseCloudMusicApi项目的 Python SDK
Home-page: https://github.com/2061360308/NeteaseCloudMusic_PythonSDK Home-page: https://github.com/2061360308/NeteaseCloudMusic_PythonSDK
Author: 盧瞳 Author: 盧瞳
@ -16,4 +16,94 @@ Requires-Python: >=3.6.0
Description-Content-Type: text/markdown Description-Content-Type: text/markdown
License-File: LICENSE License-File: LICENSE
网易云音乐API NeteaseCloudMusicApi项目的 Python SDK
# NeteaseCloudMusic_PythonSDK
> 基于 [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 封装的 Python SDK。
> 网易云API Python版本。
> 现已同步原项目接口且测试通过的有200多个
> 已发布到PyPi可直接使用pip安装
> 项目地址:[GitHub](https://github.com/2061360308/NeteaseCloudMusic_PythonSDK)
![](https://img.shields.io/badge/py_mini_racer-@0.6.0-red.svg)
![License](https://img.shields.io/badge/license-MIT-yellow)
### 依赖于
- [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
- [ NeteaseCloudMusicApi_V8 ](https://github.com/2061360308/NeteaseCloudMusicApi_V8)
### 原理
- 通过 `py_mini_racer` 调用 `NeteaseCloudMusicApi_V8` 的 `js` 方法。进一步进行了简单封装。
### 使用
- 安装 `pip install NeteaseCloudMusic`
- 导入API进行使用(具体查看`test.py`中的示例)
```python
from NeteaseCloudMusic import NeteaseCloudMusicApi, api_help, api_list
import os
netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API
netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie
response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh"}) # 调用API
# 获取帮助
print(api_help())
print(api_help('song_url_v1'))
# 获取API列表
print(api_list())
```
> 注意: request(self, name, query=None) 的第一个参数为API名称第二个参数为API参数具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com)name支持`/song/url/v1`和`song_url_v1`两种写法。
### 开发
- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git`
- 安装依赖 `pip install -r requirements.txt`
- 目录/文件说明
├── package 项目包根目录
├── test_gender 生成测试代码的脚本
├── test.py 手动测试/ 使用示例
### 改进
> 下列API未支持
>
- apicache.js
- memory-cache.js
- request_reference.js
- avatar_upload.js
- cloud.js
- playlist_cover_update.js
- voice_upload.js
- register_anonimous.js
- verify_getQr.js
> 以下api未测试(这些接口测试起来比较繁琐)
>
- /user/replacephone
- /audio/match
- /rebind
- /nickname/check
- /activate/init/profile
- /cellphone/existence/check
- /register/cellphone
- /captcha/verify
- /captcha/sent
- /login/refresh
- /logout
- /user/update
- /pl/count
- /playlist/update
- /playlist/desc/update
- /playlist/name/update
- /playlist/tags/update
- /event/forward
- /event/del
- /share/resource
- /send/text
- /send/playlist
- /playlist/create
- /playlist/tracks
- /daily_signin
- /fm_trash
### 欢迎提交PR

File diff suppressed because it is too large Load Diff

View File

@ -3057,5 +3057,14 @@
} }
} }
] ]
},
"/login/status": {
"name": "登录状态",
"explain": "说明 : 调用此接口,可获取登录状态",
"example": [
{
"query":{}
}
]
} }
} }

View File

@ -2,6 +2,8 @@ import json
import os.path import os.path
import socket import socket
from pprint import pprint from pprint import pprint
import http.cookies
import datetime
import pkg_resources import pkg_resources
import requests import requests
@ -17,6 +19,7 @@ class NeteaseCloudMusicApi:
self.DEBUG = debug # 是否开启调试模式 self.DEBUG = debug # 是否开启调试模式
self.special_api = {"/playlist/track/all": self.playlist_track_all, 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}
# 载入js代码 # 载入js代码
@ -57,7 +60,7 @@ class NeteaseCloudMusicApi:
# 处理俩个云贝接口名称转换问题 # 处理俩个云贝接口名称转换问题
if name in yubei_special.keys(): if name in yubei_special.keys():
name = yubei_special[name] name = yubei_special[name]
print("转换了个麻烦的路由", name) # print("转换了个麻烦的路由", name)
if name not in api_list(): if name not in api_list():
if name not in yubei_special.values(): if name not in yubei_special.values():
@ -79,6 +82,8 @@ class NeteaseCloudMusicApi:
else: else:
result = self.call_api(name, query) result = self.call_api(name, query)
#
return result return result
@staticmethod @staticmethod
@ -100,7 +105,7 @@ class NeteaseCloudMusicApi:
if self.__cookie is None: if self.__cookie is None:
if os.path.isfile("cookie_storage"): if os.path.isfile("cookie_storage"):
with open("cookie_storage", "r", encoding='utf-8') as f: with open("cookie_storage", "r", encoding='utf-8') as f:
self.__cookie = f.read() self.cookie = f.read()
else: else:
self.__cookie = "" # 如果没有cookie文件就设置为空 self.__cookie = "" # 如果没有cookie文件就设置为空
@ -110,9 +115,36 @@ class NeteaseCloudMusicApi:
def cookie(self, cookie): def cookie(self, cookie):
if cookie is None: if cookie is None:
cookie = "" cookie = ""
self.__cookie = cookie
_cookie = cookie
'''判断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
with open("cookie_storage", "w+", encoding='utf-8') as f: with open("cookie_storage", "w+", encoding='utf-8') as f:
f.write(cookie) f.write(_cookie)
@property @property
def ip(self): def ip(self):
@ -147,6 +179,12 @@ class NeteaseCloudMusicApi:
"status": response.status_code, "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', result = self.ctx.call('NeteaseCloudMusicApi.afterRequest',
json.dumps(response_result), json.dumps(response_result),
request_param.get('crypto', None), request_param.get('crypto', None),
@ -184,24 +222,16 @@ class NeteaseCloudMusicApi:
result = self.ctx.call('NeteaseCloudMusicApi.inner_version') result = self.ctx.call('NeteaseCloudMusicApi.inner_version')
return result return result
def login_cellphone(self, query):
"""
手机号登录
:param query:
:return:
"""
result = self.call_api("/login/cellphone", query)
if __name__ == '__main__': # 自动 填充cookie
import json if result["code"] == 200:
import os if result.get("data").get("cookie"):
from pprint import pprint self.cookie = result.get("data").get("cookie")
import dotenv return result
dotenv.load_dotenv("../../.env") # 从.env文件中加载环境变量
netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API
netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie
netease_cloud_music_api.DEBUG = True # 开启调试模式
def songv1_test():
# 获取歌曲详情
response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh"})
pprint(response)
songv1_test()

90
package/README.md Normal file
View File

@ -0,0 +1,90 @@
# NeteaseCloudMusic_PythonSDK
> 基于 [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 封装的 Python SDK。
> 网易云API Python版本。
> 现已同步原项目接口且测试通过的有200多个
> 已发布到PyPi可直接使用pip安装
> 项目地址:[GitHub](https://github.com/2061360308/NeteaseCloudMusic_PythonSDK)
![](https://img.shields.io/badge/py_mini_racer-@0.6.0-red.svg)
![License](https://img.shields.io/badge/license-MIT-yellow)
### 依赖于
- [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
- [ NeteaseCloudMusicApi_V8 ](https://github.com/2061360308/NeteaseCloudMusicApi_V8)
### 原理
- 通过 `py_mini_racer` 调用 `NeteaseCloudMusicApi_V8``js` 方法。进一步进行了简单封装。
### 使用
- 安装 `pip install NeteaseCloudMusic`
- 导入API进行使用(具体查看`test.py`中的示例)
```python
from NeteaseCloudMusic import NeteaseCloudMusicApi, api_help, api_list
import os
netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API
netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie
response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh"}) # 调用API
# 获取帮助
print(api_help())
print(api_help('song_url_v1'))
# 获取API列表
print(api_list())
```
> 注意: request(self, name, query=None) 的第一个参数为API名称第二个参数为API参数具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com)name支持`/song/url/v1`和`song_url_v1`两种写法。
### 开发
- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git`
- 安装依赖 `pip install -r requirements.txt`
- 目录/文件说明
├── package 项目包根目录
├── test_gender 生成测试代码的脚本
├── test.py 手动测试/ 使用示例
### 改进
> 下列API未支持
>
- apicache.js
- memory-cache.js
- request_reference.js
- avatar_upload.js
- cloud.js
- playlist_cover_update.js
- voice_upload.js
- register_anonimous.js
- verify_getQr.js
> 以下api未测试(这些接口测试起来比较繁琐)
>
- /user/replacephone
- /audio/match
- /rebind
- /nickname/check
- /activate/init/profile
- /cellphone/existence/check
- /register/cellphone
- /captcha/verify
- /captcha/sent
- /login/refresh
- /logout
- /user/update
- /pl/count
- /playlist/update
- /playlist/desc/update
- /playlist/name/update
- /playlist/tags/update
- /event/forward
- /event/del
- /share/resource
- /send/text
- /send/playlist
- /playlist/create
- /playlist/tracks
- /daily_signin
- /fm_trash
### 欢迎提交PR

Binary file not shown.

Binary file not shown.

16
test.py
View File

@ -12,7 +12,7 @@ from package.NeteaseCloudMusic import NeteaseCloudMusicApi, api_help, api_list
dotenv.load_dotenv() # 从.env文件中加载环境变量 dotenv.load_dotenv() # 从.env文件中加载环境变量
netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API
netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie # netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie
netease_cloud_music_api.DEBUG = True # 开启调试模式 netease_cloud_music_api.DEBUG = True # 开启调试模式
@ -42,7 +42,6 @@ def user_account_test():
def comment_new_test(): def comment_new_test():
# 获取用户账号信息
response = netease_cloud_music_api.request("comment_new", { response = netease_cloud_music_api.request("comment_new", {
"type": "0", "type": "0",
"id": "1407551413", "id": "1407551413",
@ -73,16 +72,13 @@ def top_playlist_highquality_test():
def captcha_sent_test(): def captcha_sent_test():
response = netease_cloud_music_api.request("/captcha/sent", {"phone": "15234941791"}) response = netease_cloud_music_api.request("/captcha/sent", {"phone": "15229954305"})
pprint(response) pprint(response)
def login_cellphone_test(): def login_cellphone_test():
# 注意这里需要调用login_cellphone方法而不是api方法具体实现可以看main.py response = netease_cloud_music_api.request("/login/cellphone",{"phone": "15229954305", "captcha": "4273"})
# 有后续操作的api都需要自己实现一下 pprint(response)
pass
# response = netease_cloud_music_api.login_cellphone("15234941791", "9464")
# pprint(response)
def personalized_djprogram_test(): def personalized_djprogram_test():
@ -100,7 +96,7 @@ if __name__ == '__main__':
# print(api_list()) # print(api_list())
# print(api_help()) # print(api_help())
# song_url_v1_test() # song_url_v1_test()
top_mv_test() # top_mv_test()
# search_test() # search_test()
# search_default_test() # search_default_test()
# user_account_test() # user_account_test()
@ -109,4 +105,4 @@ if __name__ == '__main__':
# playlist_detail_test() # playlist_detail_test()
# top_playlist_highquality_test() # top_playlist_highquality_test()
# captcha_sent_test() # captcha_sent_test()
# login_cellphone_test() login_cellphone_test()

View File

@ -1,12 +0,0 @@
from pprint import pprint
others = {
}
ignore = []
for i in others.keys():
ignore.append(i)
pprint(ignore)