Skip to content

Commit 433bf25

Browse files
RunsTpCuteReimu
andauthored
[feature] #41 实现 WBI 签名 (#43)
* [feature] #41 实现 WBI 签名 * [feature] #41 基于 GetUserVideos 最小实现 * [fix] #41 fix lint check * 填充 GetUserVideos 接口字段 * lint --------- Co-authored-by: CuteReimu <[email protected]>
1 parent f23f41a commit 433bf25

File tree

7 files changed

+475
-10
lines changed

7 files changed

+475
-10
lines changed

client.go

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package bilibili
22

33
import (
4-
"github.com/go-resty/resty/v2"
54
"net/http"
65
"strings"
76
"time"
7+
8+
"github.com/go-resty/resty/v2"
89
)
910

1011
type Client struct {
12+
wbi *WBI
1113
resty *resty.Client
1214
}
1315

@@ -26,7 +28,10 @@ func New() *Client {
2628

2729
// NewWithClient 接收一个自定义的*resty.Client为参数
2830
func NewWithClient(restyClient *resty.Client) *Client {
29-
return &Client{resty: restyClient}
31+
return &Client{
32+
wbi: NewDefaultWbi(),
33+
resty: restyClient,
34+
}
3035
}
3136

3237
func (c *Client) Resty() *resty.Client {
@@ -50,6 +55,25 @@ func (c *Client) SetCookiesString(cookiesString string) {
5055
}}}).Cookies())
5156
}
5257

58+
// SetCookies 设置Cookies
59+
func (c *Client) SetCookies(cookies []*http.Cookie) {
60+
c.resty.SetCookies(cookies)
61+
}
62+
63+
// SetRawCookies 这个 RawCookie 可以直接从浏览器 request的header中复制出来,然后直接设置
64+
func (c *Client) SetRawCookies(rawCookies string) {
65+
header := http.Header{}
66+
header.Add("Cookie", rawCookies)
67+
req := http.Request{Header: header}
68+
69+
c.SetCookies(req.Cookies())
70+
}
71+
72+
// GetCookies 获取当前的cookies
73+
func (c *Client) GetCookies() []*http.Cookie {
74+
return c.resty.Cookies
75+
}
76+
5377
// 根据key获取指定的cookie值
5478
func (c *Client) getCookie(name string) string {
5579
now := time.Now()

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/pkg/errors v0.9.1
99
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
1010
github.com/spf13/cast v1.6.0
11+
golang.org/x/sync v0.7.0
1112
)
1213

1314
require (

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
3636
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
3737
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
3838
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
39-
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
4039
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
4140
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
4241
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
4342
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4443
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4544
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
45+
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
46+
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
4647
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
4748
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4849
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -53,7 +54,6 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5354
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5455
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5556
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
56-
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
5757
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
5858
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
5959
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

user.go

+70-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,77 @@
11
package bilibili
22

3-
import (
4-
"github.com/pkg/errors"
5-
)
3+
type GetUserVideosParam struct {
4+
Mid int `json:"mid"` // 目标用户mid
5+
Order string `json:"order,omitempty" request:"query,omitempty"` // 排序方式。默认为pubdate。最新发布:pubdate。最多播放:click。最多收藏:stow
6+
Tid int `json:"tid,omitempty" request:"query,omitempty"` // 筛选目标分区。默认为0。0:不进行分区筛选。分区tid为所筛选的分区
7+
Keyword string `json:"keyword,omitempty" request:"query,omitempty"` // 关键词筛选。用于使用关键词搜索该UP主视频稿件
8+
Pn int `json:"pn,omitempty" request:"query,omitempty"` // 页码。默认为 1
9+
Ps int `json:"ps,omitempty" request:"query,omitempty"` // 每页项数。默认为 30
10+
}
11+
12+
type VideoArea struct {
13+
Count int `json:"count"` // 投稿至该分区的视频数
14+
Name string `json:"name"` // 该分区名称
15+
Tid int `json:"tid"` // 该分区tid
16+
}
17+
18+
type UserVideo struct {
19+
Aid int `json:"aid"` // 稿件avid
20+
Attribute int `json:"attribute"`
21+
Author string `json:"author"` // 视频UP主。不一定为目标用户(合作视频)
22+
Bvid string `json:"bvid"` // 稿件bvid
23+
Comment int `json:"comment"` // 视频评论数
24+
Copyright string `json:"copyright"` // 视频版权类型
25+
Created int `json:"created"` // 投稿时间。时间戳
26+
Description string `json:"description"` // 视频简介
27+
EnableVt int `json:"enable_vt"`
28+
HideClick bool `json:"hide_click"` // false。作用尚不明确
29+
IsPay int `json:"is_pay"` // 0。作用尚不明确
30+
IsUnionVideo int `json:"is_union_video"` // 是否为合作视频。0:否。1:是
31+
Length string `json:"length"` // 视频长度。MM:SS
32+
Mid int `json:"mid"` // 视频UP主mid。不一定为目标用户(合作视频)
33+
Meta any `json:"meta"` // 无数据时为 null
34+
Pic string `json:"pic"` // 视频封面
35+
Play int `json:"play"` // 视频播放次数
36+
Review int `json:"review"` // 0。作用尚不明确
37+
Subtitle string `json:"subtitle"` // 空。作用尚不明确
38+
Title string `json:"title"` // 视频标题
39+
Typeid int `json:"typeid"` // 视频分区tid
40+
VideoReview int `json:"video_review"` // 视频弹幕数
41+
}
42+
43+
type UserVideosList struct {
44+
Tlist map[int]VideoArea `json:"tlist"` // 投稿视频分区索引
45+
Vlist []UserVideo `json:"vlist"` // 投稿视频列表
46+
}
47+
48+
type UserVideoPage struct {
49+
Count int `json:"count"` // 总计稿件数
50+
Pn int `json:"pn"` // 当前页码
51+
Ps int `json:"ps"` // 每页项数
52+
}
53+
54+
type EpisodicButton struct {
55+
Text string `json:"text"` // 按钮文字
56+
Uri string `json:"uri"` // 全部播放页url
57+
}
58+
59+
type UserVideos struct {
60+
List UserVideosList `json:"list"` // 列表信息
61+
Page UserVideoPage `json:"page"` // 页面信息
62+
EpisodicButton EpisodicButton `json:"episodic_button"` // “播放全部“按钮
63+
IsRisk bool `json:"is_risk"`
64+
GaiaResType int `json:"gaia_res_type"`
65+
GaiaData any `json:"gaia_data"`
66+
}
667

768
// GetUserVideos 查询用户投稿视频明细
8-
func (c *Client) GetUserVideos() error {
9-
// https://api.bilibili.com/x/space/wbi/arc/search
10-
return errors.New("wbi还未实现,本接口暂时无法使用")
69+
func (c *Client) GetUserVideos(param GetUserVideosParam) (*UserVideos, error) {
70+
const (
71+
method = "GET"
72+
url = "https://api.bilibili.com/x/space/wbi/arc/search"
73+
)
74+
return execute[*UserVideos](c, method, url, param, fillWbiHandler(c.wbi, c.GetCookies()))
1175
}
1276

1377
type GetUserCardParam struct {

util.go

+16
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package bilibili
22

33
import (
44
"encoding/json"
5+
"net/http"
56
"reflect"
67
"strings"
8+
"time"
79
"unicode"
810

911
"github.com/go-resty/resty/v2"
@@ -31,6 +33,20 @@ func fillParam(key, value string) paramHandler {
3133
}
3234
}
3335

36+
func fillWbiHandler(wbi *WBI, cookies []*http.Cookie) func(*resty.Request) error {
37+
return func(r *resty.Request) error {
38+
newQuery, err := wbi.SignQuery(r.QueryParam, time.Now())
39+
if err != nil {
40+
return err
41+
}
42+
43+
r.QueryParam = newQuery
44+
r.Cookies = cookies
45+
r.Header.Del("Referer")
46+
return nil
47+
}
48+
}
49+
3450
// execute 发起请求
3551
func execute[Out any](c *Client, method, url string, in any, handlers ...paramHandler) (out Out, err error) {
3652
r := c.resty.R()

0 commit comments

Comments
 (0)