qiuyaohong / kuwomusicapi Goto Github PK
View Code? Open in Web Editor NEW酷我音乐API Node.js 版 酷我音乐 API
License: Apache License 2.0
酷我音乐API Node.js 版 酷我音乐 API
License: Apache License 2.0
接口的完整路径是什么?
当我调用 search/searchMusicBykeyWord, 提示 "The request is illegal", 我需要获取什么权限吗? 或者说接口已经修改
这项目跑起来日志文件不会自动删除,跑了一晚上把我200多G的磁盘跑满了
每次请求接口都有一定概率崩溃,信息如下
nodejs.JSONResponseFormatError: Unexpected token E in JSON at position 0 (data json format: "Error occured while trying to proxy to: www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"), GET http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175 504 (connected: true, keepalive socket: false, agent status: {"createSocketCount":249,"createSocketErrorCount":0,"closeSocketCount":248,"errorSocketCount":0,"timeoutSocketCount":247,"requestCount":401,"freeSockets":{},"sockets":{"www.kuwo.cn:80:":1},"requests":{}}, socketHandledRequests: 1, socketHandledResponses: 1)
headers: {"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"}
headers: {"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"}
at JSON.parse ()
at parseJSON (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:1227:24)
at C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:932:23
at decodeContent (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:733:14)
at handleResponseCloseAndEnd (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:913:7)
at IncomingMessage. (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:957:7)
at IncomingMessage.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
name: "JSONResponseFormatError"
data: "Error occured while trying to proxy to: www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"
path: "/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"
status: 504
headers: {"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"}
res: {"status":504,"statusCode":504,"statusMessage":"Gateway Timeout","headers":{"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"},"size":157,"aborted":false,"rt":1114,"keepAliveSocket":false,"data":"Error occured while trying to proxy to: www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175","requestUrls":["http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"],"timing":null,"remoteAddress":"39.155.179.10","remotePort":80,"socketHandledRequests":1,"socketHandledResponses":1}
pid: 11344
好像用不了了
文本删除
无法获取部分音乐播放链接
您好~
我看到文档里有通过 Playlist ID 获取音乐列表的接口 /kuwo/musicList?pid=1082685104
,但是没有找到通过 Album ID 获取音乐列表的接口。
hello there!tell me please this is for searching music from kuwo?if yes,I am begging you could you increase unlimited results?it would be great!I know kuwo shows few results!please man!!!
自己的项目刚好需要这个接口,需要打包部署一下
npm install iconv-lite
npm install needle
npm install process
npm install zlib
app => service => lrc.ts
const BaseService = require('./BaseService')
export default class Lrc extends BaseService {
async LrcRes (musicId) {
return this.commonRequest(`http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=${musicId}&httpsStatus=1`)
}
}
const BaseService = require('./BaseService')
const needle = require('needle')
const process = require('process')
const deflateRaw = require('zlib')
const { inflate } = require('zlib')
const iconv = require('iconv-lite')
const bufkey = Buffer.from('yeelion')
const bufkeylen = bufkey.length
const buildParams = (id, isGetLyricx) => {
let params = `user=12345,web,web,web&requester=localhost&req=1&rid=MUSIC_${id}`
if (isGetLyricx) params += '&lrcx=1'
const bufstr = Buffer.from(params)
const bufstrlen = bufstr.length
const output = new Uint16Array(bufstrlen)
let i = 0
while (i < bufstrlen) {
let j = 0
while (j < bufkeylen && i < bufstrlen) {
output[i] = bufkey[j] ^ bufstr[i]
i++
j++
}
}
return Buffer.from(output).toString('base64')
}
const cancelHttp = requestObj => {
// console.log(requestObj)
if (!requestObj) return
// console.log('cancel:', requestObj)
if (!requestObj.abort) return
requestObj.abort()
}
const requestMsg = {
fail: '请求异常,可以多试几次,若还是不行就换一首吧',
unachievable: '哦No...接口无法访问了!',
timeout: '请求超时',
// unachievable: '哦No...接口无法访问了!已帮你切换到临时接口,重试下看能不能播放吧~',
notConnectNetwork: '无法连接到服务器',
cancelRequest: '取消http请求',
}
const request = (url, options, callback) => {
let data
if (options.body) {
data = options.body
} else if (options.form) {
data = options.form
// data.content_type = 'application/x-www-form-urlencoded'
options.json = false
} else if (options.formData) {
data = options.formData
// data.content_type = 'multipart/form-data'
options.json = false
}
options.response_timeout = options.timeout
return needle.request(options.method || 'get', url, data, options, (err, resp, body) => {
if (!err) {
body = resp.body = resp.raw.toString()
try {
resp.body = JSON.parse(resp.body)
} catch (_) { }
body = resp.body
}
callback(err, resp, body)
}).request
}
const defaultHeaders = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
}
const handleDeflateRaw: any = data => new Promise((resolve, reject) => {
deflateRaw(data, (err, buf) => {
if (err) return reject(err)
resolve(buf)
})
})
const regx = /(?:\d\w)+/g
const fetchData = async (url, method, {
headers = {},
format = 'json',
timeout = 15000,
...options
}, callback) => {
headers = Object.assign({}, headers)
const bHh = '624868746c'
if (headers[bHh]) {
const path = url.replace(/^https?:\/\/[\w.:]+\//, '/')
let s = Buffer.from(bHh, 'hex').toString()
s = s.replace(s.substr(-1), '')
s = Buffer.from(s, 'base64').toString()
const v = process.versions.app.split('-')[0].split('.').map(n => n.length < 3 ? n.padStart(3, '0') : n).join('')
const v2 = process.versions.app.split('-')[1] || ''
headers[s] = !s || `${(await handleDeflateRaw(Buffer.from(JSON.stringify(`${path}${v}`.match(regx), null, 1).concat(v)).toString('base64'))).toString('hex')}&${parseInt(v)}${v2}`
delete headers[bHh]
}
return request(url, {
...options,
method,
headers: Object.assign({}, defaultHeaders, headers),
timeout,
json: format === 'json',
}, (err, resp, body) => {
if (err) return callback(err, null)
callback(null, resp, body)
})
}
const buildHttpPromose = (url, options) => {
const obj: any = {
isCancelled: false,
}
obj.promise = new Promise((resolve, reject) => {
obj.cancelFn = reject
// console.log(`\nsend request---${url}`)
fetchData(url, options.method, options, (err, resp) => {
// options.isShowProgress && window.api.hideProgress()
// console.log(`\nresponse---${url}`)
// console.log(body)
obj.requestObj = null
obj.cancelFn = null
if (err) return reject(err)
resolve(resp)
}).then(ro => {
obj.requestObj = ro
if (obj.isCancelled) obj.cancelHttp()
})
})
obj.cancelHttp = () => {
if (!obj.requestObj) return obj.isCancelled = true
cancelHttp(obj.requestObj)
obj.requestObj = null
obj.promise = obj.cancelHttp = null
obj.cancelFn(new Error(requestMsg.cancelRequest))
obj.cancelFn = null
}
return obj
}
const httpFetch = (url, options = { method: 'get' }) => {
const requestObj = buildHttpPromose(url, options)
requestObj.promise = requestObj.promise.catch(err => {
if (err.message === 'socket hang up') {
return Promise.reject(new Error(requestMsg.unachievable))
}
switch (err.code) {
case 'ETIMEDOUT':
case 'ESOCKETTIMEDOUT':
return Promise.reject(new Error(requestMsg.timeout))
case 'ENOTFOUND':
return Promise.reject(new Error(requestMsg.notConnectNetwork))
default:
return Promise.reject(err)
}
})
return requestObj
}
const lrcTools: any = {
rxps: {
wordLine: /^(\[\d{1,2}:.*\d{1,4}\])\s*(\S+(?:\s+\S+)*)?\s*/,
tagLine: /\[(ver|ti|ar|al|offset|by|kuwo):\s*(\S+(?:\s+\S+)*)\s*\]/,
wordTimeAll: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/g,
wordTime: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/,
},
offset: 1,
offset2: 1,
isOK: false,
lines: [],
tags: [],
getWordInfo(str, str2, prevWord) {
const offset = parseInt(str)
const offset2 = parseInt(str2)
const startTime = Math.abs((offset + offset2) / (this.offset * 2))
const endTime = Math.abs((offset - offset2) / (this.offset2 * 2)) + startTime
if (prevWord) {
if (startTime < prevWord.endTime) {
prevWord.endTime = startTime
if (prevWord.startTime > prevWord.endTime) {
prevWord.startTime = prevWord.endTime
}
prevWord.newTimeStr = ''
}
}
return {
startTime,
endTime,
timeStr: '',
}
},
parseLine(line) {
if (line.length < 6) return
let result = this.rxps.wordLine.exec(line)
if (result) {
const time = result[1]
let words = result[2]
if (words == null) {
words = ''
}
const wordTimes = words.match(this.rxps.wordTimeAll)
if (!wordTimes) return
// console.log(wordTimes)
let preTimeInfo
for (const timeStr of wordTimes) {
const result = this.rxps.wordTime.exec(timeStr)
const wordInfo = this.getWordInfo(result[1], result[2], preTimeInfo)
words = words.replace(timeStr, wordInfo.timeStr)
if (preTimeInfo?.newTimeStr) words = words.replace(preTimeInfo.timeStr, preTimeInfo.newTimeStr)
preTimeInfo = wordInfo
}
this.lines.push(time + words)
return
}
result = this.rxps.tagLine.exec(line)
if (!result) return
if (result[1] === 'kuwo') {
let content = result[2]
if (content !== null && content.includes('][')) {
content = content.substring(0, content.indexOf(']['))
}
const valueOf = parseInt(content, 8)
this.offset = Math.trunc(valueOf / 10)
this.offset2 = Math.trunc(valueOf % 10)
if (this.offset === 0 || Number.isNaN(this.offset) || this.offset2 === 0 || Number.isNaN(this.offset2)) {
this.isOK = false
}
} else {
this.tags.push(line)
}
},
parse(lrc) {
// console.log(lrc)
const lines = lrc.split(/\r\n|\r|\n/)
const tools = Object.create(this)
tools.isOK = true
tools.offset = 1
tools.offset2 = 1
tools.lines = []
tools.tags = []
for (const line of lines) {
if (!tools.isOK) throw new Error('failed')
tools.parseLine(line)
}
if (!tools.lines.length) return ''
let lrcs = tools.lines.join('\n')
if (tools.tags.length) lrcs = `${tools.tags.join('\n')}\n${lrcs}`
// console.log(lrcs)
return lrcs
},
}
const isGetLyricx = true
const handleInflate = data => new Promise((resolve, reject) => {
inflate(data, (err, result) => {
if (err) return reject(err)
resolve(result)
})
})
const bufKey = Buffer.from('yeelion')
const bufKeyLen = bufKey.length
const decodeLyrics = async (buf, isGetLyricx) => {
if (buf.toString('utf8', 0, 10) !== 'tp=content') return ''
const lrcData: any = await handleInflate(buf.slice(buf.indexOf('\r\n\r\n') + 4))
if (!isGetLyricx) return iconv.decode(lrcData, 'gb18030')
const bufStr = Buffer.from(lrcData.toString(), 'base64')
const bufStrLen = bufStr.length
const output = new Uint16Array(bufStrLen)
let i = 0
while (i < bufStrLen) {
let j = 0
while (j < bufKeyLen && i < bufStrLen) {
output[i] = bufStr[i] ^ bufKey[j]
i++
j++
}
}
return iconv.decode(Buffer.from(output), 'gb18030')
}
const timeExp = /^\[([\d:.]*)\]{1}/g
const sortLrcArr = (arr) => {
const lrcSet = new Set()
const lrc: any = []
const lrcT: any = []
for (const item of arr) {
if (lrcSet.has(item.time)) {
if (lrc.length < 2) continue
const tItem: any = lrc.pop()
tItem.time = lrc[lrc.length - 1].time
lrcT.push(tItem)
lrc.push(item)
} else {
lrc.push(item)
lrcSet.add(item.time)
}
}
return {
lrc,
lrcT,
}
}
const parseLrc = (lrc) => {
const lines = lrc.split(/\r\n|\r|\n/)
const tags: any = []
const lrcArr: any = []
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim()
const result = timeExp.exec(line)
if (result) {
let text = line.replace(timeExp, '').trim()
let time = RegExp.$1
if (/\.\d\d$/.test(time)) time += '0'
const regexp = /<.*?>/g
text = text.replace(regexp, '').replace(/\[by:.*?\](\n|$)/g, '').replace(/\[kuwo:.*?\](\n|$)/g, '')
const times = time.split(':');
time = (parseFloat(times[0]) * 60 + parseFloat(times[1])).toFixed(2);
lrcArr.push({
time,
lineLyric: text,
})
} else if (lrcTools.rxps.tagLine.test(line)) {
tags.push(line)
}
}
const lrcInfo = sortLrcArr(lrcArr)
return lrcInfo
}
const rendererInvoke = async (params) => {
const lrc = await decodeLyrics(Buffer.from(params.lrcBase64, 'base64'), isGetLyricx)
return Buffer.from(lrc).toString('base64')
}
const decodeLyric = base64Data => rendererInvoke(base64Data)
export default class Lrc extends BaseService {
async LrcRes(musicId) {
const requestObj = httpFetch(`http://newlyric.kuwo.cn/newlyric.lrc?${buildParams(musicId, isGetLyricx)}`)
requestObj.promise = requestObj.promise.then(({ statusCode, body, raw }) => {
if (statusCode !== 200) return Promise.reject(new Error(JSON.stringify(body)))
return decodeLyric({ lrcBase64: raw.toString('base64'), isGetLyricx }).then(base64Data => {
let lrcInfo
lrcInfo = parseLrc(Buffer.from(base64Data, 'base64').toString())
try {
lrcInfo = parseLrc(Buffer.from(base64Data, 'base64').toString())
} catch (err) {
return Promise.reject(new Error('Get lyric failed'))
}
const msg = {
data: {
lrclist: lrcInfo.lrc
},
status: 200
}
return msg
})
})
const asd = async () => {
return await new Promise((resolve) => {
requestObj.promise.then((re) => {
resolve(re)
})
})
}
const as = await asd()
return as;
// return this.commonRequest(`http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=${musicId}&httpsStatus=1`)
}
}
.eslintrc
文件,把下面代码替换(此替换不影响其他地方功能){
"extends": ["eslint-config-egg/typescript","eslint-config-standard","eslint:recommended","plugin:jsdoc/recommended"],
"parser": "@typescript-eslint/parser",
"plugins": ["jsdoc"],
"rules": {
"comma-dangle":0,
"operator-linebreak":["error","before"],
"space-before-function-paren":0,
"linebreak-style":0,
"no-var-requires":0,
"no-return-assign":"off",
"default-case":"off",
"no-useless-constructor":"off",
"no-unused-vars":0,
"jsdoc/require-param-description":"off",
"jsdoc/check-tag-names": 0,
"jsdoc/no-undefined-types":0,
"jsdoc/valid-types":0,
"jsdoc/tag-lines":0,
"jsdoc/require-returns":0,
"jsdoc/check-param-names":0,
"no-bitwise":0,
"no-confusing-arrow":0,
"arrow-parens":0,
"semi":0
},
"overrides":[
{
"files":["*.ts"],
"rules":{
"@typescript-eslint/no-unused-vars":0,
"@typescript-eslint/semi":0,
"@typescript-eslint/no-var-requires":0,
"@typescript-eslint/no-useless-constructor":0
}
}
],
"globals": {
"_":"readonly",
"app":true
},
"env": {
"node": true
}
}
npm run ci
编译成 js 代码npm run start
GET http://www.kuwo.cn/api/www/search/searchKey?key=一个人&httpsStatus=1
以下是Header
Cookie: kw_token=3E7JFQ7MRPL; Hm_token=a5k3Rn3zi52eF3zEyQ3EQjb2HfbaCZDr
csrf: 3E7JFQ7MRPL
Host: www.kuwo.cn
Referer: http://www.kuwo.cn/
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36
Cross: 4ef7fff9eeb7a38b89bf3fbb5a6a111e
返回结果:
{
"success": false,
"message": "CSRF token Invalid!",
"now": "2023-07-14T03:40:21.550Z"
}
那边CSRF业务再次更新
找到 app => service => playUrl.ts 替换一下接口,就能同时下载免费和付费歌曲了
const BaseService = require('./BaseService')
export default class PlayUrl extends BaseService {
async getPlayUrl (mid, br = '128kmp3') {
return this.commonRequest(`http://www.kuwo.cn/api/v1/www/music/playUrl?mid=${mid}&type=convert_url3&br=${br}`)
}
}
type为 convert_url3 时,免费/付费音乐都可以听
br为音质,可选 128kmp3、192kmp3 和 320kmp3
接口/kuwo/url?mid=162457325&br=128kmp3
npm run ci
npm run start
这样就可以了
是不是已经不能用了?访问时返回Internal Server Error, real status: 500
搜索接口总是提示
{
"success": false,
"message": "CSRF Token Not Found!",
"now": "2023-07-04T15:05:20.168Z"
}
貌似那边已经更新了,原来写死的token不起作用了
有最新的接口吗,或者先登录vip账号,再获取播放链接的思路也可以了
debian10要装什么版本的node和npm
每次请求接口都有一定概率崩溃,信息如下
nodejs.JSONResponseFormatError: Unexpected token E in JSON at position 0 (data json format: "Error occured while trying to proxy to: www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"), GET http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175 504 (connected: true, keepalive socket: false, agent status: {"createSocketCount":249,"createSocketErrorCount":0,"closeSocketCount":248,"errorSocketCount":0,"timeoutSocketCount":247,"requestCount":401,"freeSockets":{},"sockets":{"www.kuwo.cn:80:":1},"requests":{}}, socketHandledRequests: 1, socketHandledResponses: 1)
headers: {"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"}
headers: {"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"}
at JSON.parse ()
at parseJSON (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:1227:24)
at C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:932:23
at decodeContent (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:733:14)
at handleResponseCloseAndEnd (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:913:7)
at IncomingMessage. (C:\Users\30710\Desktop\kuwoMusicApi\node_modules\urllib\lib\urllib.js:957:7)
at IncomingMessage.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
name: "JSONResponseFormatError"
data: "Error occured while trying to proxy to: www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"
path: "/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"
status: 504
headers: {"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"}
res: {"status":504,"statusCode":504,"statusMessage":"Gateway Timeout","headers":{"server":"nginx","date":"Sun, 27 Feb 2022 14:38:35 GMT","content-type":"application/json; charset=utf-8","content-length":"157","connection":"keep-alive","set-cookie":["kw_token=SVJFKJ3RR68; path=/; expires=Tue, 29 Mar 2022 14:38:34 GMT"],"vary":"Accept-Encoding"},"size":157,"aborted":false,"rt":1114,"keepAliveSocket":false,"data":"Error occured while trying to proxy to: www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175","requestUrls":["http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=12&pn=1&rn=50&httpsStatus=1&reqId=cd177cbe-88de-42ca-9137-24060680b175"],"timing":null,"remoteAddress":"39.155.179.10","remotePort":80,"socketHandledRequests":1,"socketHandledResponses":1}
pid: 11344
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.