提交 8bb37684 编写于 作者: B binaryify

修复取消喜欢歌曲失败问题 #360 补充已喜欢音乐列表接口说明文档 #370 默认关闭 debug 模式 #365 更新 Dockerfile 文件 #367

上级 aea538c8
# 更新日志 # 更新日志
### 3.0.2 | 2018.10.31 ### 3.0.3 | 2018.11.09
- 修复取消喜欢歌曲失败问题 [#360](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/360)
- 补充已喜欢音乐列表接口说明文档 [#370](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/370)
- 默认关闭 debug 模式 [#365](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/365)
- 更新 Dockerfile 文件 [#367](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/367)
### 3.0.1 | 2018.10.21 ### 3.0.1 | 2018.10.21
......
...@@ -99,6 +99,14 @@ ...@@ -99,6 +99,14 @@
77. 热门评论 77. 热门评论
78. 视频评论 78. 视频评论
79. 退出登录 79. 退出登录
80. 所有榜单内容摘要
81. 收藏视频
82. 收藏 MV
83. 视频详情
84. 相关视频
85. 关注用户
86. 新歌速递
87. 喜欢音乐列表(无序)
## 环境要求 ## 环境要求
......
...@@ -102,30 +102,46 @@ ...@@ -102,30 +102,46 @@
84. 相关视频 84. 相关视频
85. 关注用户 85. 关注用户
86. 新歌速递 86. 新歌速递
87. 喜欢音乐列表(无序)
## 安装 ## 安装
```shell ```shell
$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git $ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git
$ npm install $ npm install
``` ```
## 运行 ## 运行
```shell ```shell
$ node app.js $ node app.js
``` ```
服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux 服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux
```shell ```shell
$ PORT=4000 node app.js $ PORT=4000 node app.js
``` ```
windows 下使用 git-bash 或者 cmder 等终端执行以下命令 : windows 下使用 git-bash 或者 cmder 等终端执行以下命令 :
```shell ```shell
$ set PORT=4000 && node app.js $ set PORT=4000 && node app.js
``` ```
## 可以使用代理 ## 可以使用代理
...@@ -162,18 +178,42 @@ request 相关的环境变量 ...@@ -162,18 +178,42 @@ request 相关的环境变量
```shell ```shell
docker pull twesix/netease-cloud-music docker pull twesix/netease-cloud-music
docker run -d -p 3000:3000 --name netease-cloud-music twesix/netease-music-api docker run -d -p 3000:3000 --name netease-cloud-music twesix/netease-music-api
// 去掉或者设置相关的环境变量 // 去掉或者设置相关的环境变量
docker run -d -p 3000:3000 --name netease-cloud-music -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= netease-cloud-music docker run -d -p 3000:3000 --name netease-cloud-music -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= netease-cloud-music
``` ```
> 由于 docker 镜像更新不是很及时,推荐自己 build, 以下为 build 镜像的方式 > 由于 docker 镜像更新不是很及时,推荐自己 build, 以下为 build 镜像的方式
``` ```
$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi $ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi
$ sudo docker build . -t netease-music-api $ sudo docker build . -t netease-music-api
$ sudo docker run -d -p 3000:3000 netease-music-api $ sudo docker run -d -p 3000:3000 netease-music-api
``` ```
## 接口文档 ## 接口文档
...@@ -182,7 +222,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api ...@@ -182,7 +222,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
!> 为使用方便,降低门槛,登录接口直接使用了 get 明文请求,请按实际需求对源码修改 !> 为使用方便,降低门槛,登录接口直接使用了 get 明文请求,请按实际需求对源码修改
!> 由于接口做了缓存处理 ( 缓存 2 分钟 , 可在 app.js 设置 , 可能会导致登陆后获取不 !> 由于接口做了缓存处理 ( 缓存 2 分钟,不缓存数据极容易引起网易服务器高频ip错误 , 可在 app.js 设置 , 可能会导致登陆后获取不
到 cookie), 相同的 url 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓 到 cookie), 相同的 url 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓
存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 : 存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 :
`/simi/playlist?id=347230&timestamp=1503019930000` `/simi/playlist?id=347230&timestamp=1503019930000`
...@@ -280,11 +320,29 @@ Cookies ...@@ -280,11 +320,29 @@ Cookies
``` ```
gender: 性别 0:保密 1:男性 2:女性 gender: 性别 0:保密 1:男性 2:女性
birthday: 出生日期,时间戳 unix timestamp birthday: 出生日期,时间戳 unix timestamp
nickname: 用户昵称 nickname: 用户昵称
province: 省份id province: 省份id
city: 城市id city: 城市id
signature:用户签名 signature:用户签名
``` ```
**接口地址 :** `/user/subcount` **接口地址 :** `/user/subcount`
...@@ -311,9 +369,21 @@ signature:用户签名 ...@@ -311,9 +369,21 @@ signature:用户签名
``` ```
id:歌单id id:歌单id
name:歌单名字 name:歌单名字
desc:歌单描述 desc:歌单描述
tags:歌单tag tags:歌单tag
``` ```
**接口地址 :** `/playlist/update` **接口地址 :** `/playlist/update`
...@@ -369,6 +439,7 @@ tags:歌单tag ...@@ -369,6 +439,7 @@ tags:歌单tag
**必选参数 :** `uid` : 用户 id **必选参数 :** `uid` : 用户 id
**可选参数 :** **可选参数 :**
`limit` : 返回数量 , 默认为 30 `limit` : 返回数量 , 默认为 30
`offset` : 偏移数量,用于分页 , 如 `offset` : 偏移数量,用于分页 , 如
...@@ -443,6 +514,7 @@ tags:歌单tag ...@@ -443,6 +514,7 @@ tags:歌单tag
说明 : 调用此接口,可获取歌手分类列表 说明 : 调用此接口,可获取歌手分类列表
**必选参数 :** `cat` : 即 category Code,歌手类型,默认 1001,返回华语男歌手数据 **必选参数 :** `cat` : 即 category Code,歌手类型,默认 1001,返回华语男歌手数据
**可选参数 :** **可选参数 :**
`limit` : 返回数量 , 默认为 30 `limit` : 返回数量 , 默认为 30
`offset` : 偏移数量,用于分页 , 如 `offset` : 偏移数量,用于分页 , 如
...@@ -453,21 +525,69 @@ category Code 取值: ...@@ -453,21 +525,69 @@ category Code 取值:
``` ```
入驻歌手 5001 入驻歌手 5001
华语男歌手 1001 华语男歌手 1001
华语女歌手 1002 华语女歌手 1002
华语组合/乐队 1003 华语组合/乐队 1003
欧美男歌手 2001 欧美男歌手 2001
欧美女歌手 2002 欧美女歌手 2002
欧美组合/乐队 2003 欧美组合/乐队 2003
日本男歌手 6001 日本男歌手 6001
日本女歌手 6002 日本女歌手 6002
日本组合/乐队 6003 日本组合/乐队 6003
韩国男歌手 7001 韩国男歌手 7001
韩国女歌手 7002 韩国女歌手 7002
韩国组合/乐队 7003 韩国组合/乐队 7003
其他男歌手 4001 其他男歌手 4001
其他女歌手 4002 其他女歌手 4002
其他组合/乐队 4003 其他组合/乐队 4003
``` ```
**接口地址 :** `/artist/list` **接口地址 :** `/artist/list`
...@@ -560,7 +680,9 @@ category Code 取值: ...@@ -560,7 +680,9 @@ category Code 取值:
返回数据如下图 : 返回数据如下图 :
![精选碟](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/top_playlist.png) ![精选碟](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/top_playlist.png)
![对应位置](https://ws2.sinaimg.cn/large/006tKfTcgy1fr3wnpyg6jj317e0vcqdc.jpg) ![对应位置](https://ws2.sinaimg.cn/large/006tKfTcgy1fr3wnpyg6jj317e0vcqdc.jpg)
![返回数据](https://ws4.sinaimg.cn/large/006tKfTcgy1fr3wqs5lw9j31ic1re4c4.jpg) ![返回数据](https://ws4.sinaimg.cn/large/006tKfTcgy1fr3wqs5lw9j31ic1re4c4.jpg)
### 获取精品歌单 ### 获取精品歌单
...@@ -673,6 +795,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -673,6 +795,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
**必选参数 :** `keywords` : 关键词 **必选参数 :** `keywords` : 关键词
**可选参数 :** **可选参数 :**
`limit` : 返回数量 , 默认为 30 `limit` : 返回数量 , 默认为 30
`offset` : 偏移数量,用于分页 , 如 `offset` : 偏移数量,用于分页 , 如
...@@ -713,6 +836,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -713,6 +836,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单 说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单
**必选参数 :** **必选参数 :**
`t` : 类型,1:收藏,2:取消收藏 `t` : 类型,1:收藏,2:取消收藏
`id` : 歌单 id `id` : 歌单 id
...@@ -728,6 +852,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -728,6 +852,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 ) 说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 )
**必选参数 :** **必选参数 :**
`op`: 从歌单增加单曲为 add, 删除为 del `op`: 从歌单增加单曲为 add, 删除为 del
`pid`: 歌单 id `pid`: 歌单 id
...@@ -760,10 +885,25 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -760,10 +885,25 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
``` ```
全部:0 全部:0
华语:7 华语:7
欧美:96 欧美:96
日本:8 日本:8
韩国:16 韩国:16
``` ```
`limit`: 取出数量 , 默认为 100 `limit`: 取出数量 , 默认为 100
...@@ -879,11 +1019,29 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -879,11 +1019,29 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
``` ```
0: 歌曲 0: 歌曲
1: mv 1: mv
2: 歌单 2: 歌单
3: 专辑 3: 专辑
4: 电台 4: 电台
5: 视频 5: 视频
``` ```
**接口地址 :** `/comment/hot` **接口地址 :** `/comment/hot`
...@@ -905,11 +1063,29 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -905,11 +1063,29 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
``` ```
0: 歌曲 0: 歌曲
1: mv 1: mv
2: 歌单 2: 歌单
3: 专辑 3: 专辑
4: 电台 4: 电台
5: 视频 5: 视频
``` ```
**接口地址 :** `comment/like` **接口地址 :** `comment/like`
...@@ -925,17 +1101,36 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -925,17 +1101,36 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
1. 发送评论 1. 发送评论
**必选参数** **必选参数**
`t`:1 发送 `t`:1 发送
`tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 `tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
``` ```
0: 歌曲 0: 歌曲
1: mv 1: mv
2: 歌单 2: 歌单
3: 专辑 3: 专辑
4: 电台 4: 电台
5: 视频 5: 视频
``` ```
`id`:对应资源 id `id`:对应资源 id
...@@ -947,17 +1142,36 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -947,17 +1142,36 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
2. 删除评论 2. 删除评论
**必选参数** **必选参数**
`t`:0 删除 `t`:0 删除
`tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 `tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
``` ```
0: 歌曲 0: 歌曲
1: mv 1: mv
2: 歌单 2: 歌单
3: 专辑 3: 专辑
4: 电台 4: 电台
5: 视频 5: 视频
``` ```
`id`:对应资源 id `id`:对应资源 id
...@@ -983,8 +1197,17 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -983,8 +1197,17 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
``` ```
1: mv 1: mv
4: 电台 4: 电台
5: 视频 5: 视频
``` ```
`t`: 操作,1 为点赞,其他未取消点赞 `t`: 操作,1 为点赞,其他未取消点赞
...@@ -1195,6 +1418,16 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具 ...@@ -1195,6 +1418,16 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
![喜欢成功截图](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png) ![喜欢成功截图](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png)
### 喜欢音乐列表
说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组)
**必选参数 :** `uid`: 用户 id
**接口地址 :** `/likelist`
**调用例子 :** `/likelist?uid=32953014`
### 垃圾桶 ### 垃圾桶
说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶 说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶
...@@ -1340,6 +1573,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等 ...@@ -1340,6 +1573,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
**接口地址 :** `/mv/url` **接口地址 :** `/mv/url`
**调用例子 :** **调用例子 :**
`/mv/url?id=5436712` `/mv/url?id=5436712`
### 相关视频 ### 相关视频
...@@ -1385,29 +1619,101 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等 ...@@ -1385,29 +1619,101 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
``` ```
"0": 云音乐新歌榜, "0": 云音乐新歌榜,
"1": 云音乐热歌榜, "1": 云音乐热歌榜,
"2": 网易原创歌曲榜, "2": 网易原创歌曲榜,
"3": 云音乐飙升榜, "3": 云音乐飙升榜,
"4": 云音乐电音榜, "4": 云音乐电音榜,
"5": UK排行榜周榜, "5": UK排行榜周榜,
"6": 美国Billboard周榜 "6": 美国Billboard周榜
"7": KTV嗨榜, "7": KTV嗨榜,
"8": iTunes榜, "8": iTunes榜,
"9": Hit FM Top榜, "9": Hit FM Top榜,
"10": 日本Oricon周榜 "10": 日本Oricon周榜
"11": 韩国Melon排行榜周榜, "11": 韩国Melon排行榜周榜,
"12": 韩国Mnet排行榜周榜, "12": 韩国Mnet排行榜周榜,
"13": 韩国Melon原声周榜, "13": 韩国Melon原声周榜,
"14": 中国TOP排行榜(港台榜), "14": 中国TOP排行榜(港台榜),
"15": 中国TOP排行榜(内地榜) "15": 中国TOP排行榜(内地榜)
"16": 香港电台中文歌曲龙虎榜, "16": 香港电台中文歌曲龙虎榜,
"17": 华语金曲榜, "17": 华语金曲榜,
"18": 中国嘻哈榜, "18": 中国嘻哈榜,
"19": 法国 NRJ EuroHot 30周榜, "19": 法国 NRJ EuroHot 30周榜,
"20": 台湾Hito排行榜, "20": 台湾Hito排行榜,
"21": Beatport全球电子舞曲榜, "21": Beatport全球电子舞曲榜,
"22": 云音乐ACG音乐榜, "22": 云音乐ACG音乐榜,
"23": 云音乐嘻哈榜 "23": 云音乐嘻哈榜
``` ```
**接口地址 :** `/top/list` **接口地址 :** `/top/list`
...@@ -1517,6 +1823,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009` ...@@ -1517,6 +1823,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**必选参数 :** `rid`: 电台 的 id **必选参数 :** `rid`: 电台 的 id
**可选参数 :** **可选参数 :**
`limit` : 返回数量 , 默认为 30 `limit` : 返回数量 , 默认为 30
`offset` : 偏移数量,用于分页 , 如 `offset` : 偏移数量,用于分页 , 如
......
// 红心与取消红心歌曲 // 红心与取消红心歌曲
const { toBoolean } = require('../util')
module.exports = (query, request) => { module.exports = (query, request) => {
query.like = (query.like ? true : false) query.like = query.like ? true : false
const data = { const data = {
trackId: query.id, trackId: query.id,
like: query.like like: query.like
} }
return request( return request(
'POST', `http://music.163.com/weapi/radio/like?alg=${query.alg || 'itembased'}&trackId=${query.id}&like=${query.like}&time=${query.time || 25}`, data, 'POST',
{crypto: 'weapi', cookie: query.cookie, proxy: query.proxy} `http://music.163.com/weapi/radio/like?alg=${query.alg ||
) 'itembased'}&trackId=${query.id}&like=${query.like}&time=${query.time ||
} 25}`,
\ No newline at end of file data,
{ crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }
)
}
{ {
"name": "NeteaseCloudMusicApi", "name": "NeteaseCloudMusicApi",
"version": "3.0.2", "version": "3.0.3",
"description": "网易云音乐 NodeJS 版 API", "description": "网易云音乐 NodeJS 版 API",
"scripts": { "scripts": {
"start": "node app.js", "start": "node app.js",
......
module.exports = {
toBoolean(val) {
if (val === '') return val
return val === 'true' || val == '1'
}
}
...@@ -2,88 +2,103 @@ const encrypt = require('./crypto') ...@@ -2,88 +2,103 @@ const encrypt = require('./crypto')
const request = require('request') const request = require('request')
const queryString = require('querystring') const queryString = require('querystring')
const chooseUserAgent = (ua) => { // request.debug = true // 开启可看到更详细信息
const userAgentList = [
'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1', const chooseUserAgent = ua => {
'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1', const userAgentList = [
'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36', 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36', 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36', 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper', 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1', 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1', 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0', 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36', 'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586' 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0',
] 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
let index = 0 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586'
if(typeof(ua) == 'undefined') ]
index = Math.floor(Math.random() * userAgentList.length) let index = 0
else if(ua == 'mobile') if (typeof ua == 'undefined')
index = Math.floor(Math.random() * 7) index = Math.floor(Math.random() * userAgentList.length)
else if(ua == 'pc') else if (ua == 'mobile') index = Math.floor(Math.random() * 7)
index = Math.floor(Math.random() * 5) + 8 else if (ua == 'pc') index = Math.floor(Math.random() * 5) + 8
else else return ua
return ua return userAgentList[index]
return userAgentList[index]
} }
const createRequest = (method, url, data, options) => { const createRequest = (method, url, data, options) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let headers = { 'User-Agent': chooseUserAgent(options.ua) }
if (method.toUpperCase() == 'POST')
headers['Content-Type'] = 'application/x-www-form-urlencoded'
if (url.includes('music.163.com'))
headers['Referer'] = 'http://music.163.com'
// headers['X-Real-IP'] = '118.88.88.88'
let headers = {'User-Agent': chooseUserAgent(options.ua)} if (typeof options.cookie === 'object')
if(method.toUpperCase() == 'POST') headers['Content-Type'] = 'application/x-www-form-urlencoded' headers['Cookie'] = Object.keys(options.cookie)
if(url.includes('music.163.com')) headers['Referer'] = 'http://music.163.com' .map(
// headers['X-Real-IP'] = '118.88.88.88' key =>
encodeURIComponent(key) +
'=' +
encodeURIComponent(options.cookie[key])
)
.join('; ')
else if (options.cookie) headers['Cookie'] = options.cookie
if(typeof(options.cookie) === 'object') if (options.crypto == 'weapi') {
headers['Cookie'] = Object.keys(options.cookie).map(key => (encodeURIComponent(key) + '=' + encodeURIComponent(options.cookie[key]))).join('; ') let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/)
else if(options.cookie) data.csrf_token = csrfToken ? csrfToken[1] : ''
headers['Cookie'] = options.cookie data = encrypt.weapi(data)
url = url.replace(/\w*api/, 'weapi')
} else if (options.crypto == 'linuxapi') {
data = encrypt.linuxapi({
method: method,
url: url.replace(/\w*api/, 'api'),
params: data
})
headers['User-Agent'] =
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36'
url = 'http://music.163.com/api/linux/forward'
}
if(options.crypto == 'weapi'){ const answer = { status: 500, body: {}, cookie: [] }
let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/) request(
data.csrf_token = (csrfToken ? csrfToken[1] : '') {
data = encrypt.weapi(data) method: method,
url = url.replace(/\w*api/,'weapi') url: url,
} headers: headers,
else if(options.crypto == 'linuxapi'){ body: queryString.stringify(data),
data = encrypt.linuxapi({'method': method, url: url.replace(/\w*api/,'api'), 'params': data}) proxy: options.proxy
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36' },
url = 'http://music.163.com/api/linux/forward' (err, res, body) => {
if (err) {
answer.status = 502
answer.body = { code: 502, msg: err.stack }
reject(answer)
} else {
answer.cookie = (res.headers['set-cookie'] || []).map(x =>
x.replace(/\s*Domain=[^(;|$)]+;*/, '')
)
try {
answer.body = JSON.parse(body)
answer.status = answer.body.code || res.statusCode
} catch (e) {
answer.body = body
answer.status = res.statusCode
}
answer.status =
100 < answer.status && answer.status < 600 ? answer.status : 400
if (answer.status == 200) resolve(answer)
else reject(answer)
} }
}
const answer = {status: 500, body: {}, cookie: []} )
request( })
{method: method, url: url, headers: headers, body: queryString.stringify(data), proxy: options.proxy},
(err, res, body) => {
if(err){
answer.status = 502
answer.body = {code: 502, msg: err.stack}
reject(answer)
}
else{
answer.cookie = (res.headers['set-cookie'] || []).map(x => x.replace(/\s*Domain=[^(;|$)]+;*/, ''))
try{
answer.body = JSON.parse(body)
answer.status = answer.body.code || res.statusCode
}
catch(e){
answer.body = body
answer.status = res.statusCode
}
answer.status = (100 < answer.status && answer.status < 600) ? answer.status : 400
if(answer.status == 200)
resolve(answer)
else
reject(answer)
}
}
)
})
} }
module.exports = createRequest module.exports = createRequest
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册