Skip to content
Zonyitoo@SYSU edited this page Aug 24, 2013 · 18 revisions
  • 豆瓣并没有开放 douban.fm 的API

  • 以下的分析只是通过抓包,并结合网上前人的研究,猜测参数的作用

以下分析的 douban.fm 接口使用的是 http://douban.fm/radio 这一个小播放器,它是一个flash写的小播放器,豆瓣用它来开发了 AIR 版桌面客户端。

登录接口

使用 douban.fm 并不需要使用豆瓣的 OAuth 认证,只需要简单地把用户名密码 POST 过去,并保存 Token 和 Expire 即可。

  • URL: http://www.douban.com/j/app/login

  • Method: POST

  • Arguments:

    • app_name: radio_desktop_win

    • version: 100

    • email: 用户帐号

    • password: 明文密码

  • Header: Content-Type: application/x-www-form-urlencoded

  • Response ( application/json )

登录成功(r的值为0

{
    "user_id": "<user_id>",
    "err": "ok",
    "token": "<token_string>",
    "expire": "<expire_time_in_millisecond>",
    "r": 0,
    "user_name": "钟小腾",
    "email": "<user_account>"
}

登录失败(r1err会给出错误原因)

{
    "r": 1,
    "err": "wrong_password"
}

在获得user_idtokenexpire后,保存起来,在使用获取歌曲列表、红心等API时,把它们放到请求参数中即可。

若使用 http://douban.fm 这个页面所使用的接口,则需要先获取Cookies,并在每次请求都要发Cookies,相对比较麻烦

获取频道列表

这个接口获取的频道列表是一个比较固定的列表,并非douban.fm网页版上那么多样的列表。网页版的频道列表是直接服务器生成在HTML里面的,无法获得,但它的channel_id可以用,如有兴趣可把这些channel_id收集起来。

  • URL: http://www.douban.com/j/app/radio/channels

  • Method: GET

  • Arguments: None

  • Response ( application/json ):

{
    "channels": [
        {
            "name": "私人兆赫",
            "seq_id": 0,
            "abbr_en": "My",
            "channel_id": 0,
            "name_en": "Personal Radio"
        },
        {
            "name": "华语",
            "seq_id": 1,
            "abbr_en": "CH",
            "channel_id": 1,
            "name_en": "Chinese"
        },
        {
            "name": "欧美",
            "seq_id": 2,
            "abbr_en": "EN",
            "channel_id": 2,
            "name_en": "Euro-American"
        },
        ...
}

如上可看出,有频道名,有channel_id,这个id用于请求相应的歌曲列表。seq_id只是一个简单的列表排序index,可忽略

歌曲列表

歌曲列表的获取最为复杂,其参数也比较多

  • URL: http://www.douban.com/j/app/radio/people

  • Method: GET

  • Arguments:

参数名 是否必选 参数类型 备注
app_name 必选 string radio_desktop_win 固定
version 必选 int 100 固定
user_id 非必选 string user_id 若已登录,则填入
expire 非必选 int expire 若已登录,则填入
token 非必选 string token 若已登录,则填入
sid 非必选 int song id 在需要针对单曲操作时需要
h 非必选 string 最近播放列表 单次报告曲目播放状态,其格式是 |sid:报告类型
channel 非必选 int 频道id 获取频道时取得的channel_id
type 必选 string 报告类型 需要调用的接口类型,也是使用下表的报告类型

其中报告类型是以下的一种类型,都是一个字母。

类型 需要参数 含义 报告长度
b sid bye,不再播放 短报告
e sid end,当前歌曲播放完毕,但是歌曲队列中还有歌曲 短报告
n new,没有歌曲播放,歌曲队列也没有任何歌曲,需要返回新播放列表 长报告
p playing,歌曲正在播放,队列中还有歌曲,需要返回新的播放列表 长报告
s sid skip,歌曲正在播放,队列中还有歌曲,适用于用户点击下一首 短报告
r sid rate,歌曲正在播放,标记喜欢当前歌曲 短报告
s sid skip,歌曲正在播放,队列中还有歌曲,适用于用户点击下一首 短报告
u sid unrate,歌曲正在播放,标记取消喜欢当前歌曲 短报告
  • Response ( application/json ):

所有的这些都会返回一个json字符串,其中都会返回歌曲列表(WHY?),而r若为1即出错,err里面会写上出错原因,而r0即成功。

其中的歌曲列表格式是

{
    "r": 0,
    "version_max": 100,
    "song": [
        {
            "album": "/subject/5952615/",
            "picture": "http://img3.douban.com/mpic/s4616653.jpg",
            "ssid": "e1b2",
            "artist": "Bruno Mars / B.o.B",
            "url": "http://mr3.douban.com/201308250247/4a3de2e8016b5d659821ec76e6a2f35d/view/song/small/p1562725.mp3",
            "company": "EMI",
            "title": "Nothin' On You",
            "rating_avg": 4.04017,
            "length": 267,
            "subtype": "",
            "public_time": "2011",
            "sid": "1562725",
            "aid": "5952615",
            "sha256": "2422b6fa22611a7858060fd9c238e679626b3173bb0d161258b4175d69f17473",
            "kbps": "64",
            "albumtitle": "2011 Grammy Nominees",
            "like": 1
        },
        ...
    }
}

参数都可以直接从名字看出其意义

  • album 专辑跳转地址
  • picture 专辑图片地址
  • ssid 未知
  • artist 艺术家
  • url 歌曲的URL
  • company 唱片公司
  • title 歌曲名
  • rating_avg 平均分数
  • length 长度
  • subtype 子类型(有些广告的字类型会是T)
  • public_time 出版年份
  • sid 歌曲id
  • aid 专辑id
  • kbps 码率
  • albumtitle 专辑名
  • like 是否已喜欢,0为false,1为true
Clone this wiki locally