diff --git a/NeteaseCloudMusicApi.js b/NeteaseCloudMusicApi.js index dae57b6..e541be7 100644 --- a/NeteaseCloudMusicApi.js +++ b/NeteaseCloudMusicApi.js @@ -36597,9 +36597,9 @@ function createRandomString(len) { }); ;// CONCATENATED MODULE: ./util/config.json -const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1":"R_MV_5_","2":"A_PL_0_","3":"R_AL_3_","4":"A_DJ_1_","5":"R_VI_62_","6":"A_EV_2_","7":"A_DR_14_"}}'); +const config_namespaceObject = JSON.parse('{"A":{"0":"R_SO_4_","1":"R_MV_5_","2":"A_PL_0_","3":"R_AL_3_","4":"A_DJ_1_","5":"R_VI_62_","6":"A_EV_2_","7":"A_DR_14_"}}'); ;// CONCATENATED MODULE: ./module/comment.js - +const resourceTypeMap = config_namespaceObject.A; // 发送与删除评论 /* harmony default export */ const comment = ((query, request) => { @@ -36609,7 +36609,7 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" 0: 'delete', 2: 'reply', }[query.t] - query.type = config_namespaceObject[query.type] + query.type = resourceTypeMap[query.type] const data = { threadId: query.type + query.id, } @@ -36707,9 +36707,9 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" }); ;// CONCATENATED MODULE: ./module/comment_floor.js - +const comment_floor_resourceTypeMap = config_namespaceObject.A; /* harmony default export */ const comment_floor = ((query, request) => { - query.type = config_namespaceObject[query.type] + query.type = comment_floor_resourceTypeMap[query.type] const data = { parentCommentId: query.parentCommentId, threadId: query.type + query.id, @@ -36730,12 +36730,12 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" }); ;// CONCATENATED MODULE: ./module/comment_hot.js - +const comment_hot_resourceTypeMap = config_namespaceObject.A; // 热门评论 /* harmony default export */ const comment_hot = ((query, request) => { query.cookie.os = 'pc' - query.type = config_namespaceObject[query.type] + query.type = comment_hot_resourceTypeMap[query.type] const data = { rid: query.id, limit: query.limit || 20, @@ -36756,11 +36756,11 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" }); ;// CONCATENATED MODULE: ./module/comment_hug_list.js - +const comment_hug_list_resourceTypeMap = config_namespaceObject.A; /* harmony default export */ const comment_hug_list = ((query, request) => { query.cookie.os = 'ios' query.cookie.appver = '8.10.90' - query.type = config_namespaceObject[query.type || 0] + query.type = comment_hug_list_resourceTypeMap[query.type || 0] const threadId = query.type + query.sid const data = { targetUserId: query.uid, @@ -36785,13 +36785,13 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" }); ;// CONCATENATED MODULE: ./module/comment_like.js - +const comment_like_resourceTypeMap = config_namespaceObject.A; // 点赞与取消点赞评论 /* harmony default export */ const comment_like = ((query, request) => { query.cookie.os = 'pc' query.t = query.t == 1 ? 'like' : 'unlike' - query.type = config_namespaceObject[query.type] + query.type = comment_like_resourceTypeMap[query.type] const data = { threadId: query.type + query.id, commentId: query.cid, @@ -36861,12 +36861,12 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" }); ;// CONCATENATED MODULE: ./module/comment_new.js - +const comment_new_resourceTypeMap = config_namespaceObject.A; // 评论 /* harmony default export */ const comment_new = ((query, request) => { query.cookie.os = 'pc' - query.type = config_namespaceObject[query.type] + query.type = comment_new_resourceTypeMap[query.type] const threadId = query.type + query.id const pageSize = query.pageSize || 20 const pageNo = query.pageNo || 1 @@ -37250,32 +37250,7 @@ const config_namespaceObject = JSON.parse('{"resourceTypeMap":{"0":"R_SO_4_","1" }); ;// CONCATENATED MODULE: ./util/index.js -// export default { -// toBoolean(val) { -// if (typeof val === 'boolean') return val -// if (val === '') return val -// return val === 'true' || val == '1' -// }, -// cookieToJson(cookie) { -// if (!cookie) return {} -// let cookieArr = cookie.split(';') -// let obj = {} -// cookieArr.forEach((i) => { -// let arr = i.split('=') -// obj[arr[0]] = arr[1] -// }) -// return obj -// }, -// getRandom(num) { -// var random = Math.floor( -// (Math.random() + Math.floor(Math.random() * 9 + 1)) * -// Math.pow(10, num - 1), -// ) -// return random -// }, -// } - -function toBoolean(val) { +function toBoolean (val) { if (typeof val === 'boolean') return val if (val === '') return val return val === 'true' || val == '1' @@ -37927,11 +37902,11 @@ const typeMap = { }); ;// CONCATENATED MODULE: ./module/hug_comment.js - +const hug_comment_resourceTypeMap = config_namespaceObject.A; /* harmony default export */ const hug_comment = ((query, request) => { query.cookie.os = 'ios' query.cookie.appver = '8.10.90' - query.type = config_namespaceObject[query.type || 0] + query.type = hug_comment_resourceTypeMap[query.type || 0] const threadId = query.type + query.sid const data = { targetUserId: query.uid, @@ -40002,11 +39977,11 @@ var crypto_js_default = /*#__PURE__*/__webpack_require__.n(crypto_js); ;// CONCATENATED MODULE: ./module/resource_like.js // 点赞与取消点赞资源 - +const resource_like_resourceTypeMap = config_namespaceObject.A; /* harmony default export */ const resource_like = ((query, request) => { query.cookie.os = 'android' query.t = query.t == 1 ? 'like' : 'unlike' - query.type = config_namespaceObject[query.type] + query.type = resource_like_resourceTypeMap[query.type] const data = { threadId: query.type + query.id, } diff --git a/README.md b/README.md new file mode 100644 index 0000000..5ec00c3 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# NeteaseCloudMusic_PythonSDK +> 基于 [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 封装的 Python SDK + +![](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` 方法。进一步进行了简单封装。 + +### 使用 +- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git` +- 安装依赖 `pip install -r requirements.txt` +- 导入API进行使用(具体查看`test.py`中的示例) +```python +from main import NeteaseCloudMusicApi +import os + +netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API +netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie +response = netease_cloud_music_api.api("song_url_v1", {"id": 33894312, "level": "exhigh"}) # 调用API + +``` + +> 注意: api(self, name, query=None) 的第一个参数为API名称,第二个参数为API参数,具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com),name支持`/song/url/v1`和`song_url_v1`两种写法。 + + +### 改进 +> 下列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未测试,欢迎提交PR diff --git a/main.py b/main.py index e045ced..97b8379 100644 --- a/main.py +++ b/main.py @@ -78,10 +78,18 @@ class NeteaseCloudMusicApi: query["cookie"] = self.cookie if query.get("realIP") is None: - query["ip"] = self.ip + query["realIP"] = self.ip else: - query["ip"] = query.get("realIP") + query["realIP"] = query.get("realIP") result = self.getRequestParam(name, query) - response = requests.post(result["url"], data=result["data"], headers=result["headers"]) + + param_data = {} + for item in result["data"].split("&"): + param_data[item.split("=")[0]] = item.split("=")[1] + + if self.DEBUG: + print(f" - param_data:{param_data}") + + response = requests.post(result["url"], data=param_data, headers=result["headers"]) return response diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fcff4d9 Binary files /dev/null and b/requirements.txt differ diff --git a/result.json b/result.json index e2f29d1..44a1a23 100644 --- a/result.json +++ b/result.json @@ -1 +1 @@ -{"method": "POST", "url": "https://music.163.com/weapi/nuser/account/get", "headers": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.69", "Content-Type": "application/x-www-form-urlencoded", "Referer": "https://music.163.com", "Cookie": "MUSIC_R_T=1579622000495; %20Max-Age=2147483647; %20Expires=Sun%2C%2023%20Dec%202091%2019%3A11%3A46%20GMT; %20Path=%2Fweapi%2Ffeedback; %20HTTPOnly=; MUSIC_A_T=1579621885297; __csrf=f2479af05431c9fe000004d74b9eb43c; =; MUSIC_U=00F5809E26613FA34E24E56B87BB2D71C716ECA62F1D492FDDB5915792654A9C101BE0AFDDFB7A79A405394645D6A0BCCEF96AF99CD68BB226B3AD52F1A990A41E4D4E359E8FBE202B246A605453D0BA8EA9370E2CF943DC198B5ADF131DBD233495C69C0BA6B144FD3EB4A3D356B95B15FF8FA61D19A34DA56A980797377346706BD36CB666B2BA320AFF4E140BB208BBC6CBA15716BF7B98CB0A92EF1032735321FD39465B9E8B34E8C241A1BD5DA0C77501BF407AF6AA382C7B589AB18B92B856600EF1D81FC7A3E5B80339CC9DA04A0D32E85563B018CFDBEDC86F8972B6D78F6704AA10CEDBB7E43F3FC654D0D3EC885D09A503057B92912B28763893F0DDCE9995439D4E047867F8BDEB01C4B3C4C3717D3049C5A13BC16EF182455B02F3F9CA81185292BED1FD7493A07FCAB3B5676A7FD58F8BF4F5B09F752C6F235C034D297711FBE960A3CAF5504E62EF6547; MUSIC_SNS=; __remember_me=; _ntes_nuid=9743f172c9fbf0df0cd5bea497f762a5; NMTID=c6fb4ebb7bed565569b8bfa999a6af17"}, "data": "params=zK+rehRY4wqhBJAW+jl2F/w/2ohUVNlDEzSC9mthy399eXXDw5NB8rscOLoSkz6bXMSSO9wLSLY8978bQ4gdKso3KMtol4oLDrW8Lgw1V8YKYfOXcponbBPa84BUZOwp&encSecKey=4e50790bdfb1043fc3d2295dc65a517184851020ece86d7be5890cb2d7a51a06a429bacb42101137585e79fd6246f5bd5d45d0a35a611c1baee61b56e2f99ba00932294b32fd061b37b7bdd25bfba2179497ac17312c26a2aa67f0286e0e84cf4cdd8a83f698f1338803514768cffa18f22aa8a16a6a53d7358dd09adf40164f", "keepAlive": true, "proxy": false, "httpAgent": null, "httpsAgent": null} \ No newline at end of file +{"method": "POST", "url": "https://music.163.com/eapi/v2/resource/comments", "headers": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded", "Referer": "https://music.163.com", "X-Real-IP": "116.25.146.177", "X-Forwarded-For": "116.25.146.177", "Cookie": "osver=; deviceId=; appver=8.9.70; versioncode=140; mobilename=; buildver=1701847506; resolution=1920x1080; __csrf=f2479af05431c9fe000004d74b9eb43c; os=pc; channel=; requestId=1701847506946_0813; MUSIC_U=00F5809E26613FA34E24E56B87BB2D71C716ECA62F1D492FDDB5915792654A9C101BE0AFDDFB7A79A405394645D6A0BCCEF96AF99CD68BB226B3AD52F1A990A41E4D4E359E8FBE202B246A605453D0BA8EA9370E2CF943DC198B5ADF131DBD233495C69C0BA6B144FD3EB4A3D356B95B15FF8FA61D19A34DA56A980797377346706BD36CB666B2BA320AFF4E140BB208BBC6CBA15716BF7B98CB0A92EF1032735321FD39465B9E8B34E8C241A1BD5DA0C77501BF407AF6AA382C7B589AB18B92B856600EF1D81FC7A3E5B80339CC9DA04A0D32E85563B018CFDBEDC86F8972B6D78F6704AA10CEDBB7E43F3FC654D0D3EC885D09A503057B92912B28763893F0DDCE9995439D4E047867F8BDEB01C4B3C4C3717D3049C5A13BC16EF182455B02F3F9CA81185292BED1FD7493A07FCAB3B5676A7FD58F8BF4F5B09F752C6F235C034D297711FBE960A3CAF5504E62EF6547"}, "data": "params=12F5DE9D45BC43BBFF87CD83BA0668CB45B0B536B3EA520FDBC7DDA41E3DC56FEC27C2566DACAFBD82D091EEF23C2ADCE582909AA818FC4D8BB5653A07B2E8E2235570DEAEF766E41492D1ED74707C6F337B0D2D22DF8196E33D84DA7AF74B3A2346036C93ADA9DC0DC9EFEB1174C6ED81EDEF21958821A537FEF7E9A3175C66E12DB397AB219D4194C5E01591E172D37CBDDB41587257449EB0D4C6DBE370BC5B70161D83CB164F0788E3FD9537A59300F504D0DB6B058540CB790789D97DB9357DD82C52A0ABC124CEC86EA0E0E04D1F60426FA52D19654FD2031E08CDAF854ADD33AECC86D5AFAF8812E46D830DDBA92950E529AFEE0B5AC99714A052B8C7926A027043549A477704E3D226001F74984A407500E57FE116EBA54B85B5D2BB5D566540C0381BAE9F4E0D2BB9B69C886F6743AC6F444F515FC43CD2E78992371E0F44EFAB5A0C3852FD88504B76A8DF81C79C153CA25B02770ECD2C46018E3B26DCFA5E1B96818424553EC6E467C9503A1F1CF659794FEE27951AB4B3E6A256EC5E5B469366660CB62649B55A115703D83086D55B4796161BBA23EBBBB2A0B5CDD6F1B45302DF29ACE2C70A787A98BADAF3D4CC187AD6DCDFAABC7D8FFCCAA5C51871DD109091BC4BC35492AD4AFB82F0388C15A15B05F521759E994DC0A536AE57100F2F5692AB10D105C432B69E36F5E672C022B5F2014F01134AD7DDCD3C1B0929C227756E595FA3DA69347E2663BC7102C74FDA2311BA6934E7BE76BB63D106350EF17E1E61481D35431B2D26DF6099065FDCDB97A2F44C6B5FABD228743C77EAA7663E07864DFCD830E24E2633AE0E6B42D5A8B8F9F0D3BBDE867AADA0BF49E79AB9DDC20DC6EF8C62381B8526FB73BE67D381999A11C37E7F909D1A4816D11DB80653DAD25BB092EF6D4A5FCFBC0E4569048493A39540E6C3B66ABDF0347EEB7DE6DFA9B0B8B4621CF17195E2E10ABECE88812AD41DFED634EE28E7A69B7DF32864CCB0E18F5126C6EEC85B6B1801038E2B9BEEA459F3217F59A728A4508162D19F839BE7E4EAB693BF4E4446880B175281C6A5A597C3C1B8F1DAD210C3A9646BE1B71FABAEA2C6C69979CB0D9584178CFFBAA574096ECD2F4D2254EDB9FE176F7C429E38ADE27434D4FF8D3F0B8CF3E992248082522D7BA8DBC635456558A002D642F71824653EBA2004BEE4A2D7022EA84D686CD0B48D00FD7F1AFFCED9A15D61FE58D2065012EF5E90482F489A4A70EEA47A4D07548895CFB66DA09C351B92FFC1C234BA283ADF3CE37F8AD808C25A28D31ACA4E8FD78402DA14D9C8E55E3C060D90A1CD7692C8EEE56DDB3F35B6D313FBAB8347BE410F4E5937678CFEB82D0521F5A8A5D8C75653C988D80129ABDD1FF5C3EBFB52B23B4DAD2817E56FE15811FECEA65CF0E8956A66390B16AB2AD2455BE6A0A881F430CC747316EB02130B38A7E3DD2DC560A93768E9E9A9296F5D6606DC4A1F6F9F00FBA6D83B987895E699EF06235023A39022F24B4C", "keepAlive": true, "encoding": null, "proxy": false, "httpAgent": null, "httpsAgent": null, "responseType": "arraybuffer"} \ No newline at end of file diff --git a/test.py b/test.py index bcc61b6..d1a1115 100644 --- a/test.py +++ b/test.py @@ -5,11 +5,11 @@ import dotenv from main import NeteaseCloudMusicApi -dotenv.load_dotenv() +dotenv.load_dotenv() # 从.env文件中加载环境变量 -netease_cloud_music_api = NeteaseCloudMusicApi() -netease_cloud_music_api.cookie = os.getenv("COOKIE") -netease_cloud_music_api.DEBUG = True +netease_cloud_music_api = NeteaseCloudMusicApi() # 初始化API +netease_cloud_music_api.cookie = os.getenv("COOKIE") # 设置cookie +netease_cloud_music_api.DEBUG = True # 开启调试模式 def songv1_test(): @@ -21,8 +21,8 @@ def songv1_test(): def search_test(): # 搜索 response = netease_cloud_music_api.api("search", {"keywords": "海阔天空"}) - print("|", response.text, "|") - # pprint(json.loads(response.text)) + # print("|", response.text, "|") + pprint(json.loads(response.text)) def search_default_test(): @@ -34,11 +34,27 @@ def search_default_test(): def user_account_test(): # 获取用户账号信息 response = netease_cloud_music_api.api("user_account") - pprint(response.text) + pprint(json.loads(response.text)) + + +def comment_new_test(): + # 获取用户账号信息 + response = netease_cloud_music_api.api("comment_new", { + "type": "0", + "id": "1407551413", + "sortType": 3, + "cursor": 1602072870260, + "pageSize": 20, + "pageNo": 2, + "realIP": "116.25.146.177", + }) + pprint(json.loads(response.text)) if __name__ == '__main__': + pass # songv1_test() # search_test() # search_default_test() - user_account_test() + # user_account_test() + # comment_new_test()