mirror of
https://github.com/czp3009/bilibili-api.git
synced 2025-02-19 20:50:28 +08:00
添加追番页面的 API
This commit is contained in:
parent
7c6297f6d2
commit
e33af1de88
@ -1,6 +1,8 @@
|
||||
# Bilibili API JVM 调用库
|
||||
该项目提供 Bilibili API 的 JVM 调用, 协议来自 Bilibili Android APP 的逆向工程以及截包分析.
|
||||
|
||||
使用一台虚拟的 `Pixel 2` 设备来截取数据包, 一些固定参数可能与真实设备不一致.
|
||||
|
||||
# 技术说明
|
||||
`BilibiliClient` 类表示一个模拟的客户端, 实例化此类即表示打开了 Bilibili APP.
|
||||
|
||||
|
@ -18,6 +18,9 @@ fun InputStream.readInt(): Int {
|
||||
(byteArray[3].toInt())
|
||||
}
|
||||
|
||||
/**
|
||||
* 以大端模式从流中读取一个 unsigned int
|
||||
*/
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
fun InputStream.readUInt() = readInt().toUInt()
|
||||
|
||||
|
@ -33,13 +33,17 @@ interface AppAPI {
|
||||
|
||||
/**
|
||||
* 侧边栏中动态增加的按钮, 返回信息包含 URI 地址(到对应的 activity)
|
||||
* 侧拉抽屉
|
||||
*/
|
||||
@GET("/x/resource/sidebar")
|
||||
fun sidebar(): Deferred<Sidebar>
|
||||
|
||||
/**
|
||||
* 首页内容(客户端通过解析返回的内容来生成页面内容, 下同)
|
||||
* 该 API 没有翻页参数, 同样的参数每次请求都会返回不一样的内容. 刷新和下拉只是简单的重新访问此接口.
|
||||
* 首页 -> 推荐
|
||||
*
|
||||
* @param pull 如果是通过滑动到最顶端来刷新页面的, 那么将是 true, 将页面滑动到最底端来获取更多内容将是 false
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@GET("/x/v2/feed/index")
|
||||
@ -65,6 +69,9 @@ interface AppAPI {
|
||||
/**
|
||||
* 热门页面
|
||||
* 首页 -> 热门
|
||||
*
|
||||
* @param index 翻页参数, 一开始为 0, 然后每次滑动到底端就会加 10
|
||||
* @param ver 第一次请求时没有这个参数, 第二次开始这个参数为上一次请求此接口时的返回值中的 `ver`
|
||||
*/
|
||||
@GET("/x/v2/show/popular/index")
|
||||
fun popularPage(
|
||||
@ -75,7 +82,7 @@ interface AppAPI {
|
||||
@Query("last_param") lastParam: String? = null,
|
||||
@Query("login_event") loginEvent: Int = 0,
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("ver") ver: Long? = null //ver 的值为上一次请求该接口时的 timestamp-1
|
||||
@Query("ver") ver: Long? = null
|
||||
): Deferred<PopularPage>
|
||||
|
||||
/**
|
||||
|
@ -1,9 +1,6 @@
|
||||
package com.hiczp.bilibili.api.main
|
||||
|
||||
import com.hiczp.bilibili.api.main.model.ChildReply
|
||||
import com.hiczp.bilibili.api.main.model.Recommend
|
||||
import com.hiczp.bilibili.api.main.model.Reply
|
||||
import com.hiczp.bilibili.api.main.model.Season
|
||||
import com.hiczp.bilibili.api.main.model.*
|
||||
import kotlinx.coroutines.Deferred
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
@ -52,8 +49,8 @@ interface MainAPI {
|
||||
): Deferred<ChildReply>
|
||||
|
||||
/**
|
||||
* 获得一个番剧的分季信息, 包含默认季(通常是最新的一季)的分集信息
|
||||
* seasonId 或 episodeId 必须有一个, 返回的结果是一样的
|
||||
* 获得一个番剧的分季信息(生成番剧页面所需的信息), 包含当前选择的季的分集信息
|
||||
* seasonId 或 episodeId 必须有一个, 如果用 episodeId 将跳转到对应的 season 的页面
|
||||
* 返回值中, 每个 episode 都有 aid 和 cid
|
||||
*
|
||||
* @param seasonId 季的唯一标识
|
||||
@ -74,4 +71,47 @@ interface MainAPI {
|
||||
*/
|
||||
@GET("/pgc/season/app/related/recommend")
|
||||
fun recommend(@Query("season_id") seasonId: Long): Deferred<Recommend>
|
||||
|
||||
/**
|
||||
* 我的追番动态(追番页面上方的那一条 "我的追番")
|
||||
* 首页 -> 追番 -> 我的追番
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@GET("/pgc/app/page/bangumi/mine")
|
||||
fun myBangumiNews(
|
||||
@Query("fnval") fnval: Int = 16,
|
||||
@Query("fnver") fnver: Int = 0
|
||||
): Deferred<MyBangumiNews>
|
||||
|
||||
/**
|
||||
* 追番页面(客户端用这里面的数据来生成追番页面)
|
||||
* 每个模块(module)的数据(item)全部超过三个.
|
||||
* 每个板块下面的 换一换 按钮并不重新请求数据, 而是从每个模块的数据里选出另一批
|
||||
* 首页 -> 追番
|
||||
*
|
||||
* @param pgcHomeTimelineABTest 与 A/B Test 有关, 不明确其值含义, 有可能使得返回内容不一样
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@GET("/pgc/app/page/bangumi")
|
||||
fun bangumiPage(
|
||||
@Query("fnval") fnval: Int = 16,
|
||||
@Query("fnver") fnver: Int = 0,
|
||||
@Query("pgc_home_timeline_abtest") pgcHomeTimelineABTest: Int? = 13
|
||||
): Deferred<BangumiPage>
|
||||
|
||||
/**
|
||||
* 获得更多 "编辑推荐"
|
||||
* 首页 -> 追番 -> (下拉)
|
||||
*
|
||||
* @param cursor 表示时间(ms), 但是可能是科学计数法. 每次请求所用的 cursor 在上一次的返回值里的最后一个 item 里. 第一次请求所用的 cursor 在追番页面的返回值的最后.
|
||||
* @param size 分页大小
|
||||
* @param wid 不明确, 有可能是一些 padding, margin, 用于计算位置
|
||||
*
|
||||
* @see bangumiPage
|
||||
*/
|
||||
fun bangumiMore(
|
||||
@Query("cursor") cursor: String,
|
||||
@Query("size") size: Int = 10,
|
||||
@Query("wid") wid: String? = "78,79,80,81,59"
|
||||
): Deferred<BangumiMore>
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.hiczp.bilibili.api.main.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class BangumiMore(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("message")
|
||||
var message: String, // success
|
||||
@SerializedName("result")
|
||||
var result: List<Result>
|
||||
) {
|
||||
data class Result(
|
||||
@SerializedName("cover")
|
||||
var cover: String, // http://i0.hdslb.com/bfs/bangumi/5bac9515a50c880e55a772c194241ff9943e0004.png
|
||||
/**
|
||||
* cursor 的值有可能是科学计数法, 例如 1.550210400638E12
|
||||
* 如果不是最后一个 item 将没有这个字段
|
||||
*/
|
||||
@SerializedName("cursor")
|
||||
var cursor: String?, // 1548172800112.0
|
||||
@SerializedName("desc")
|
||||
var desc: String, // 正在就读白凰女学院3年级的加藤茉莉香,是个拥有“私掠船免状”的合法宇宙海贼。她不仅是学生、宇宙艇部的部长、咖啡馆的服务员,还是宇宙海贼船·弁天丸的船长,每天都过着繁忙而充实的生活。某天,正在豪华客船上开展工作的茉莉香,在乘客名单中发现了拥有银河通行证的少年·无限彼方的名字……。少年与海贼的亚空冒险就此展开!
|
||||
@SerializedName("id")
|
||||
var id: Int, // 33409
|
||||
@SerializedName("is_new")
|
||||
var isNew: Int, // 0
|
||||
@SerializedName("link")
|
||||
var link: String, // https://www.bilibili.com/read/cv1831506
|
||||
@SerializedName("link_type")
|
||||
var linkType: Int, // 4
|
||||
@SerializedName("link_value")
|
||||
var linkValue: Int, // 0
|
||||
@SerializedName("pub_time")
|
||||
var pubTime: String, // 2019-01-23 00:00:00
|
||||
@SerializedName("simg")
|
||||
var simg: String,
|
||||
@SerializedName("title")
|
||||
var title: String, // 化身为刃,除魔四方——《多罗罗》
|
||||
@SerializedName("wid")
|
||||
var wid: Int // 81
|
||||
)
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.hiczp.bilibili.api.main.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class BangumiPage(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("message")
|
||||
var message: String, // success
|
||||
@SerializedName("result")
|
||||
var result: Result
|
||||
) {
|
||||
data class Result(
|
||||
@SerializedName("modules")
|
||||
var modules: List<Module>,
|
||||
@SerializedName("regions")
|
||||
var regions: List<Region>
|
||||
) {
|
||||
data class Module(
|
||||
@SerializedName("attr")
|
||||
var attr: Attr,
|
||||
@SerializedName("headers")
|
||||
var headers: List<Any>,
|
||||
@SerializedName("items")
|
||||
var items: List<Item>,
|
||||
@SerializedName("module_id")
|
||||
var moduleId: Int, // 6
|
||||
@SerializedName("size")
|
||||
var size: Int, // 10
|
||||
@SerializedName("style")
|
||||
var style: String, // fall
|
||||
@SerializedName("title")
|
||||
var title: String, // 编辑推荐
|
||||
@SerializedName("wid")
|
||||
var wid: List<Int>
|
||||
) {
|
||||
data class Item(
|
||||
@SerializedName("badge")
|
||||
var badge: String, // NEW
|
||||
@SerializedName("badge_type")
|
||||
var badgeType: Int, // 0
|
||||
@SerializedName("cover")
|
||||
var cover: String, // http://i0.hdslb.com/bfs/bangumi/57e00f9995459ab0cf40800358ee7f3b392b38a4.jpg
|
||||
@SerializedName("cursor")
|
||||
var cursor: String, // 1.55021040036E12
|
||||
@SerializedName("desc")
|
||||
var desc: String, // 明明是最差劲的相遇,但雏却不知何时开始无法停止心动。雏被初中时的学长·恋雪所吸引,决定和他进入同所高中而拼命学习。并且,和青梅竹马的虎太朗一同进入了樱丘高中。曾经单调乏味的恋雪,为了自己单相思的对象,而在假日结束后改换了形象,变得受欢迎起来。在这种状况下,雏决定要「告白」,但是——!?
|
||||
@SerializedName("is_new")
|
||||
var isNew: Int, // 0
|
||||
@SerializedName("item_id")
|
||||
var itemId: Int, // 34265
|
||||
@SerializedName("link")
|
||||
var link: String, // https://www.bilibili.com/blackboard/topic/activity-dm4qK4-BI.html
|
||||
@SerializedName("title")
|
||||
var title: String, // 【资讯档】2019年第7周
|
||||
@SerializedName("wid")
|
||||
var wid: Int // 78
|
||||
)
|
||||
|
||||
data class Attr(
|
||||
@SerializedName("follow")
|
||||
var follow: Int, // 0
|
||||
@SerializedName("header")
|
||||
var header: Int, // 1
|
||||
@SerializedName("random")
|
||||
var random: Int // 0
|
||||
)
|
||||
}
|
||||
|
||||
data class Region(
|
||||
@SerializedName("icon")
|
||||
var icon: String, // http://i0.hdslb.com/bfs/bangumi/3b66adc7339e62d469ea5b89a45c74e14e3ae831.png
|
||||
@SerializedName("title")
|
||||
var title: String, // 点评
|
||||
@SerializedName("url")
|
||||
var url: String // bilibili://pgc/review/index
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.hiczp.bilibili.api.main.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class MyBangumiNews(
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@SerializedName("message")
|
||||
var message: String, // success
|
||||
@SerializedName("result")
|
||||
var result: Result
|
||||
) {
|
||||
data class Result(
|
||||
@SerializedName("delay")
|
||||
var delay: List<Any>,
|
||||
@SerializedName("follow")
|
||||
var follow: Int, // 34
|
||||
@SerializedName("follows")
|
||||
var follows: List<Follow>,
|
||||
@SerializedName("follows_type")
|
||||
var followsType: Int, // 1
|
||||
@SerializedName("update")
|
||||
var update: Int // 1
|
||||
) {
|
||||
data class Follow(
|
||||
@SerializedName("badge")
|
||||
var badge: String, // 会员抢先
|
||||
@SerializedName("badge_type")
|
||||
var badgeType: Int, // 0
|
||||
@SerializedName("cover")
|
||||
var cover: String, // http://i0.hdslb.com/bfs/bangumi/f34ff3975c39913af936c133ae60a5891babba08.png
|
||||
@SerializedName("is_finish")
|
||||
var isFinish: Int, // 0
|
||||
@SerializedName("is_started")
|
||||
var isStarted: Int, // 1
|
||||
@SerializedName("new_ep")
|
||||
var newEp: NewEp,
|
||||
/**
|
||||
* 如果 progress 为 null 说明尚未观看
|
||||
*/
|
||||
@SerializedName("progress")
|
||||
var progress: Progress?,
|
||||
@SerializedName("season_id")
|
||||
var seasonId: Int, // 25681
|
||||
@SerializedName("title")
|
||||
var title: String, // JOJO的奇妙冒险 黄金之风
|
||||
@SerializedName("total_count")
|
||||
var totalCount: Int, // 39
|
||||
@SerializedName("url")
|
||||
var url: String // https://www.bilibili.com/bangumi/play/ss25681
|
||||
) {
|
||||
data class NewEp(
|
||||
@SerializedName("cover")
|
||||
var cover: String, // http://i0.hdslb.com/bfs/archive/c3af18bf85040dfacb081db46e033f056318a8f0.jpg
|
||||
@SerializedName("id")
|
||||
var id: Int, // 250631
|
||||
@SerializedName("index_show")
|
||||
var indexShow: String // 更新至第20话
|
||||
)
|
||||
|
||||
data class Progress(
|
||||
@SerializedName("last_ep_desc")
|
||||
var lastEpDesc: String, // 看到第2话
|
||||
@SerializedName("last_ep_id")
|
||||
var lastEpId: Int, // 250837
|
||||
@SerializedName("last_ep_index")
|
||||
var lastEpIndex: String, // 2
|
||||
@SerializedName("last_time")
|
||||
var lastTime: Int // 1377
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user