跳至内容

Jixun's Blog 填坑还是开坑,这是个好问题。

网易云音乐数据抓取

需要在云音乐页面上执行,因为是直接调用网页上的加密。

async function enc_ajax (url, payload) {
  // 加密参数
  const rsaE = '010001';
  const rsaN = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7';
  const aesIV = '0CoJUm6Qyw8W8jud';

  // 构建 url
  const csrfTokenName = window.NEJ_CONF.p_csrf.param;
  const csrfTokenValue = document.cookie.match(new RegExp(window.NEJ_CONF.p_csrf.cookie + '=(\\w+)'))?.[1] || '';
  if (csrfTokenValue) {
    url += url.includes('?') ? '&' : '?';
    url += csrfTokenName + '=' + encodeURIComponent(csrfTokenValue);
  }

  // CSRF 处理
  const payloadWithCSRF = JSON.stringify({ ...payload, [csrfTokenName]: csrfTokenValue });

  // 加密 payload
  const { encText, encSecKey } = window.asrsea(payloadWithCSRF, rsaE, rsaN, aesIV);

  // 对 payload 进行最终的编码
  const postData = 'params=' + encodeURIComponent(encText) +
      '&encSecKey=' + encodeURIComponent(encSecKey);

  // 起飞!!
  return fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: postData,
  }).then(r => r.json());
}

// 获取单曲信息
enc_ajax('/weapi/song/detail/', {
  ids: [27584970]
}).then(data => {
  console.info(data);
});

// 获取某个歌单的所有曲目信息
enc_ajax('/weapi/v6/playlist/detail', {
  id: '5150975094',
  offset: '0',
  total: 'true',
  limit: '1000',
  n: '1000',
}).then(async (playlistResp) => {
  const tracksResp = await enc_ajax('/weapi/song/detail/', {
    ids: playlistResp.playlist.trackIds.map((x) => x.id),
  });

  console.info(tracksResp);
});

更新记录 #

2023.07.30 #

  • 添加获取歌单信息的示例

2023.07.25 #

  • 使用 fetch API 代替之前的 XMLHttpRequest 写法。

知识共享许可协议 本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

评论区