5.23 QQ音乐数据源(新)抓取完整步骤

抓获数据源思路:
1、任意打开一首歌,进入QQ音乐网页播放界面。先不播放歌曲,查看network发现,服务端传来music.fcg?-=getplaysongvkey,这是当前歌曲的vkey。
在这里插入图片描述
2、分析该XHR应答。在req_0->data->midurlinfo[0]->purl。就是正确参数的后半截。
在这里插入图片描述
3、继续分析XHR,在 req_0->data->sip中,发现可能是正确参数的前半截。
在这里插入图片描述
4、尝试将参数拼接访问
在这里插入图片描述

5、正确解析,那就是,只要获取歌曲的getplaysongkey,就能拼接出正确的Url。

注:其实这是不断尝试的过程,因为QQ音乐返回的数据源的域名并不是dl.stream.qqmusic而是变化的ip。但是sip映射的接口,也可以正确解析数据源。

可能你还没看懂,反正是一个接口抓获,以及分析的过程。接下来就是具体实现代码。

和ustbhuangyi导师一样,直接jsonp访问即可。在api/singer中
在这里插入图片描述

// 文件写在singer.js中
// 传入歌曲的mid即可,获得正确的songkey

export function getPlaySongKey(mid) {
  const url = 'https://u.y.qq.com/cgi-bin/musicu.fcg'
  const data = Object.assign({}, commonParams, {
    loginUin: 0,
    hostUin: 0,
    platform: 'yqq.json',
    needNewCode: 0,
    data: `{"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"1933776370","songmid":["${mid}"],"songtype":[0],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":24,"cv":0}}`
  })
  return jsonp(url, data, '')
}
// 这一段代码为的是拼接出正确参数,promise方法。你也可以不用这段代码。看你个人水平了。这是promise应答
如果不用这段代码,你直接使用getPlaySongKey,然后通过then(res => {这里是拼接参数的方法})也可以。

export function getSongUrl(mid) {
  return getPlaySongKey(mid).then(res => {
    if (res.code === 0) {
      const purl = res.req_0.data.midurlinfo[0].purl
      const host = res.req_0.data.sip[0]
      return Promise.resolve({code: 0, url: host + purl})
    }
  })
}

我这里还是用getSongUrl来讲咯。
成功获取到歌曲的url,那么接下来就是将url保存到song对象中。我的做法呢。就是遍历song数组,给每一首song增加对应的url

比如在singer-detail.vue组件中的_normalizeSongs方法中调用getSongUrl接口,在标准化数据的同时将url获取,并放入该对象中。

  methods: {
    _getDetail () {
      if (!this.singer.id) {
        this.$router.push('/singer')
        return
      }
      getSingerDetail(this.singer.id).then(res => {
        if (res.code === ERR_OK) {
          this.songs = this._normalizeSongs(res.singer.data.songlist)
          // console.log(this.songs)
        }
      })
    },
    _normalizeSongs(list) {
      let ret = []
      list.forEach((item, index) => {
        let musicData = item
        ret.push(createSong(musicData))
        if (musicData.id && musicData.album.id) {
          // 解析正确Vkey拼装url
          this._getSongUrl(musicData.mid).then(url => {
            // 指向正确的url
            ret[index].url = url
          })
        }
      })
      return ret
    },
    _getSongUrl (mid) {
      return getSongUrl(mid).then(res => {
        return Promise.resolve(res.url)
      })
    }
  }

简言之,你只需要获得播放源url就可以了,至于后续的数据渲染问题,方法可以有很多,不一定要标准化数据时扔url进去,如果歌曲长度50,则会发送50个XHR请求,很耗资源。好的做法就是侦听currentSong的变化,根据变化重新发送getSongUrl并将url丢给currentSong即可。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值