Bangumi 番组计划是一个专注于动漫、音乐、游戏领域,帮助你分享、发现与结识同好的ACGN网络。前几天,我在某些收费主题中见到了基于Bangumi的追剧目录功能,感觉很有意思。但Bangumi并没有公开API接口,我也没有渠道去搞一份有此功能的收费主题。幸好,在GITHUB上billgateshxk开发的IOS版BangumiAPP中,我找到了关于BangumiAPI的部分。后来,我写了段很简单的PHP代码调用了一下。

用到的API

完整API目录请见:https://github.com/billgateshxk/bangumi

登陆(post)

URL:https://api.bgm.tv/auth?source=$appName
PostData:username
PostData:password
参数:appName:必填;username:必填,邮箱;password:必填,密码;
返回值:Json(用户信息不存在时返回HTML),包含个人信息及auth,authEncode等,如果错误,会包含error信息。

获取所有收藏内容(Get)

URL:https://api.bgm.tv/user/$userId/collection?cat=$cat
参数:$userId:必填,用户id;$cat:不明,瞎填都行;
返回值:Json数组,内包含收藏剧集对象,如果没有收藏内容,返回字符串null。

获取某用户某部剧观看详细信息(Get)

URL:https://api.bgm.tv/user/$userId/progress?subject_id=$subjectId&source=$appName&auth=$authEncode
参数:$userId:必填,用户id;$subjectId:必填,剧ID;$appName:必填;$authEncode,必填。
返回值:Json,包含用户对于该剧的详细信息(仅包含已经观看或操作的剧集),如果没有详细信息,返回null。

获取某部剧的摘要描述(Get)

URL:https://api.bgm.tv/subject/$subjectId?responseGroup=simple
参数:$subjectId:必填,剧ID;
返回值:Json,包含该剧的摘要信息,如果没有详细信息,返回json code 404。

获取某部剧的详细描述(Get)

URL:https://api.bgm.tv/subject/$subjectId?responseGroup=large
参数:$subjectId:必填,剧ID;
返回值:Json,包含该剧的详细信息,如果没有详细信息,返回json code 404。

PHP测试访问的代码

简单的效果图

完整代码

我不会php,边翻php手册边写,感觉各种符号好麻烦(c#大法好)。

<?php
class BangumiAPI
{
  /** OooOooOooO **/
  private static $bangumiAPI = null;
  /** 静态成员 **/
  //应用程序名
  private  static $appName = "BGMYetu";
  //api链接
  private static $apiUrl = "https://api.bgm.tv";
  /** 成员 **/
  //用户名(邮箱)
  public  $userName = "";
  //密码
  public  $passWord = "";
  //用户id
  private  $userID = "";
  //auth
  private  $auth = "";
  //auth urlencoding
  private  $authEncode = "";
  //收藏
  private $myCollection;
  //登陆api
  private  $loginApi = "";
  //收藏api
  private  $collectionApi = ""; 
  /** 方法 **/
  //OooOooO
  public static function GetInstance()
      {
    if (BangumiAPI::$bangumiAPI == null) {
      BangumiAPI::$bangumiAPI = new BangumiAPI();
    }
    return BangumiAPI::$bangumiAPI;
  }
  //构造方法
  private function __construct()
      {
    //echo "构造方法";
  }
  //对象属性初始化
  public function init($_userName,$_passWord)
      {
    if ($_userName == null || $_passWord == null) {
      //程序返回
      echo "初始化参数错误!";
      return;
    }
    $this->userName = $_userName;
    $this->passWord = $_passWord;
    //登陆api
    $this->loginApi = BangumiAPI::$apiUrl . "/auth?source=" . BangumiAPI::$appName;
    //用户id为空或auth为空
    if ($this->userID == ""  || $this->authEncode == ""){
      //登陆post字符串
      $postData = array('username' => $this->userName , 'password' => $this->passWord);
      //获取登陆返回json
      $userContent = BangumiAPI::curl_post_contents($this->loginApi,$postData);
      //json to object
      $userData = json_decode($userContent);
      //存在error属性
      if (property_exists($userData, "error")) {
        //输出错误信息
        echo "登陆错误:" . $userData->error;
        //程序返回
        return;
      }
      //初始化
      $this->userID = $userData->id;
      $this->auth = $userData ->auth;
      $this->authEncode = $userData ->auth_encode;
    }
    //初始化收藏字符串
    $this->collectionApi = BangumiAPI::$apiUrl . "/user/" . $this->userID ."/collection?cat=playing";
  }
  //获取收藏json
  public function GetCollection()
      {
    if ($this->userID == "" || $this->collectionApi == "") {
      return null;
    }
    return BangumiAPI::curl_get_contents($this->collectionApi);
  }
  //格式化收藏
  public function ParseCollection()
      {
    $content = $this->GetCollection();
    if ($content == null || $content == "") {
      echo "获取失败";
      return;
    }
    //返回不是json
    if (strpos($content, "[{") != false && $content != "") {
      echo "用户不存在!";
      return;
    }
    $collData = json_decode($content);
    if (sizeof($collData) == 0 || $collData == null) {
      //echo "还没有记录哦~";
      return;
    }
    $index = 0;
    foreach ($collData as $value) {
      $name = $value->name;
      $name_cn = $value->subject->name_cn;
      $theurl = $value->subject->url;
      $img_grid =$value->subject->images->grid;
      $this->myCollection[$index++] = $value;
    }
  }
  //获取详细进度
  public function GetProgress($_subjectID)
      {
    if ($this->authEncode == "" || $this->userID == "") {
      return null;
    }
    $progressApi = BangumiAPI::$apiUrl . "/user/" . $this->userID . "/progress?subject_id=". $_subjectID . "&source=" . self::$appName . "&auth=" . authEncode;
    $content = BangumiAPI::curl_get_contents($progressApi);
    //print_r($content);
    return $content;
  }
  public function ParseProgress($_subjectID)
      {
    $content = $this->GetProgress($_subjectID);
    //不在收藏或没看过
    if ($content == "null") {
      return 0;
    }
    //在收藏中,没看过
    if ($content == "") {
      return 0;
    }
    $progressValue = json_decode($content);
    //返回剧集观看详细进度
    return $progressValue;
  }
  //打印收藏
  public function PrintCollecion($flag = true)
      {
    if ($this->myCollection == null) {
      $this->ParseCollection();
    }
    switch ($flag) {
      case true:
                    if (sizeof($this->myCollection) == 0 || $this->myCollection == null) {
        echo "还没有记录哦~";
        return;
      }
      echo "
          <style>
          div.bangumItem{
            height:60px;
            line-height:20px;
            margin-bottom:5px;
            border:1px solid #ff8c83;
            max-width:280px;
            white-space:nowrap;
          }
          div.bangumItem img{
            width:60px;
            height:auto;
            display:inline-block;
            float:left;
            padding-right:5px;
          }
          div.bangumItem a{
            text-decoration:none;
            color:#ff8c83;
          }
          div.bangumItem p{
            text-overflow:ellipsis;overflow:hidden;
            margin:0 auto auto 0;
          }
          div.bangumItem div.jinduBG{
            position:relative;
            height:16px;
            width:195px;
            background-color:gray;
            display:inline-block;
            border-radius:4px;
          }
          div.bangumItem div.jinduFG
          {
            height:16px;
            background-color:#ff8c83;
            border-radius:4px;
          }
          div.bangumItem div.jinduText
          {
            position:absolute;
            width:100%;height:auto;
            z-index:99;
            text-align:center;
            color:#fff;
            line-height:15px;
            font-size:15px;
          }
          </style>
        ";
      foreach ($this->myCollection as $value) {
        //print_r($value);
        //$id = $value->subject->id;
        $epsNum = $value->subject->eps;
        $progressNum = $value->ep_status;
        $myProgress = $progressNum . "/" . $epsNum;
        $name = $value->name;
        $name_cn = $value->subject->name_cn;
        $theurl = $value->subject->url;
        $img_grid =$value->subject->images->grid;
        $progressWidth = $progressNum / $epsNum * 195;
        echo "
          <div class = 'bangumItem'>
          <a href=" . $theurl ." target='_blank'>
            <img src='$img_grid' />
            <p>$name<br>
            $name_cn<br>
            <div class='jinduBG'>
            <div class='jinduText'>进度:$myProgress</div>
            <div class='jinduFG' style='width:" . $progressWidth . "px;'>
            </div>
            </div>
            </p>
          </a>
          </div>";
      }
      break;
      case false:
                echo $myCollection;
      break;
      default:
            break;
    }
  }
  //get获取内容
  private static function curl_get_contents($_url)
      {
    echo "The GET Url You Request is <span style='color:#ff8c83'>" . $_url . "</span><br/>";
    $myCurl = curl_init($_url);
    //不验证证书
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($myCurl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($myCurl,  CURLOPT_HEADER, false);
    //获取
    $content = curl_exec($myCurl);
    //关闭
    curl_close($myCurl);
    return $content;
  }
  //post获取内容
  private static function curl_post_contents($_url,$_postdata)
      {
    echo "The POST Url You Request is <span style='color:#ff8c83'>" . $_url . "</span><br/>";
    $myCurl = curl_init($_url);
    //不验证证书
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($myCurl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($myCurl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($myCurl, CURLOPT_POST, 1);
    curl_setopt($myCurl, CURLOPT_POSTFIELDS, $_postdata);
    $output = curl_exec($myCurl);
    curl_close($myCurl);
    return $output;
  }
}
$bangum = BangumiAPI::GetInstance();
$bangum->init("you@yourmail.com","123465789");
$bangum->ParseCollection();
$bangum->PrintCollecion(true);
?>

引用资料

1、[头图]【Bangumi】Bangumi Bangumi404小电视标志
2、[资料] 【GITHUB】billgateshxk bangumi

我来吐槽

*

*

9位绅士参与评论

  1. mikusa03-01 00:18 回复

    可以

  2. c0smxsec02-02 23:42 回复

    你说什么?A站凉了?

  3. Mashiro02-02 10:11 回复

    嗯嗯,可以了。再补充一个有用的接口~
    ```
    https://api.bgm.tv/subject/$subjectId?responseGroup=simple # 获取番剧简要信息
    https://api.bgm.tv/subject/$subjectId?responseGroup=large # 获取番剧详细信息
    ```

  4. Mashiro02-01 20:03 回复

    `https://api.bgm.tv/user/$userId/progress?subject_id=$subjectId&source=$authEncode`这个接口为什么我一直是Unauthorized QAQ

    • 野兔02-02 00:01 回复

      不对,好像是真出问题了,我找找原因。

    • 野兔02-02 00:21 回复

      找到原因了,文中的API参数少写了一个,并且参数值也写错了一个,文中对应的API链接已经修改,测试通过。

  5. Mashiro02-01 00:02 回复

    非常棒,装上了,吼吼

  6. answer11-27 11:41 回复

    调用api就是拼接get请求然后服务器端返回json格式的数据,非常方便获取数据啊~ :mrgreen:

  7. 明月清风11-24 23:55 回复

    一个很不错的想法了

  8. 后宫学长11-24 19:57 回复

    签到成功!签到时间:下午7:55:41,每日打卡,生活更精彩哦~

  9. 夕凉11-21 23:44 回复

    签到成功!签到时间:下午11:36:49,每日打卡,生活更精彩哦~