XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/bilibili-API-collect

update io and time (#769)

56d0126
PACI <emkqson@outlook.com>
提交于

代码差异

1 个文件 +143 -127
Modified docs/misc/sign/wbi.md +143 -127
@@ -279,147 +279,163 @@ bar=514&baz=1919810&foo=114&wts=1684805578&w_rid=bb97e15f28edf445a0e4420d36f0157
279 279 package main
280 280
281 281 import (
282 "crypto/md5"
283 "encoding/hex"
284 "fmt"
285 "io/ioutil"
286 "net/http"
287 "net/url"
288 "sort"
289 "strconv"
290 "strings"
291 "sync"
292 "time"
293
294 "github.com/tidwall/gjson"
282 "crypto/md5"
283 "encoding/hex"
284 "fmt"
285 "io"
286 "net/http"
287 "net/url"
288 "sort"
289 "strconv"
290 "strings"
291 "sync"
292 "time"
293
294 "github.com/tidwall/gjson"
295 295 )
296 296
297 var mixinKeyEncTab = []int{
298 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
299 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
300 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
301 36, 20, 34, 44, 52,
302 }
297 var (
298 mixinKeyEncTab = []int{
299 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
300 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
301 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
302 36, 20, 34, 44, 52,
303 }
304 cache sync.Map
305 lastUpdateTime time.Time
306 )
303 307
304 func getMixinKey(orig string) string {
305 var str strings.Builder
306 for _, v := range mixinKeyEncTab {
307 if v < len(orig) {
308 str.WriteByte(orig[v])
309 }
310 }
311 return str.String()[:32]
308 func main() {
309 urlStr := "https://api.bilibili.com/x/space/wbi/acc/info?mid=1850091"
310 newUrlStr, err := signAndGenerateURL(urlStr)
311 if err != nil {
312 fmt.Printf("Error: %s", err)
313 return
314 }
315 req, err := http.NewRequest("GET", newUrlStr, nil)
316 if err != nil {
317 fmt.Printf("Error: %s", err)
318 return
319 }
320 req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
321 response, err := http.DefaultClient.Do(req)
322 if err != nil {
323 fmt.Printf("Request failed: %s", err)
324 return
325 }
326 defer response.Body.Close()
327 body, err := io.ReadAll(response.Body)
328 if err != nil {
329 fmt.Printf("Failed to read response: %s", err)
330 return
331 }
332 fmt.Println(string(body))
312 333 }
313 func EncWbi(params map[string]string, imgKey string, subKey string) map[string]string {
314 mixinKey := getMixinKey(imgKey + subKey)
315 currTime := strconv.FormatInt(time.Now().Unix(), 10)
316 params["wts"] = currTime
317 // Sort keys
318 keys := make([]string, 0, len(params))
319 for k := range params {
320 keys = append(keys, k)
321 }
322 sort.Strings(keys)
323 // Remove unwanted characters
324 for k, v := range params {
325 v = strings.ReplaceAll(v, "!", "")
326 v = strings.ReplaceAll(v, "'", "")
327 v = strings.ReplaceAll(v, "(", "")
328 v = strings.ReplaceAll(v, ")", "")
329 v = strings.ReplaceAll(v, "*", "")
330 params[k] = v
331 }
332 // Build URL parameters
333 var str strings.Builder
334 for _, k := range keys {
335 str.WriteString(fmt.Sprintf("%s=%s&", k, params[k]))
336 }
337 query := strings.TrimSuffix(str.String(), "&")
338 // Calculate w_rid
339 hash := md5.Sum([]byte(query + mixinKey))
340 params["w_rid"] = hex.EncodeToString(hash[:])
341 return params
334
335 func signAndGenerateURL(urlStr string) (string, error) {
336 urlObj, err := url.Parse(urlStr)
337 if err != nil {
338 return "", err
339 }
340 imgKey, subKey := getWbiKeysCached()
341 query := urlObj.Query()
342 params := map[string]string{}
343 for k, v := range query {
344 params[k] = v[0]
345 }
346 newParams := encWbi(params, imgKey, subKey)
347 for k, v := range newParams {
348 query.Set(k, v)
349 }
350 urlObj.RawQuery = query.Encode()
351 newUrlStr := urlObj.String()
352 return newUrlStr, nil
342 353 }
343 354
344 var cache sync.Map
345 var lastUpdateTime time.Time
355 func encWbi(params map[string]string, imgKey, subKey string) map[string]string {
356 mixinKey := getMixinKey(imgKey + subKey)
357 currTime := strconv.FormatInt(time.Now().Unix(), 10)
358 params["wts"] = currTime
346 359
347 func updateCache() {
348 if time.Now().Sub(lastUpdateTime).Minutes() < 10 {
349 return
350 }
351 imgKey, subKey := GetWbiKeys()
352 cache.Store("imgKey", imgKey)
353 cache.Store("subKey", subKey)
354 lastUpdateTime = time.Now()
360 // Sort keys
361 keys := make([]string, 0, len(params))
362 for k := range params {
363 keys = append(keys, k)
364 }
365 sort.Strings(keys)
366
367 // Remove unwanted characters
368 for k, v := range params {
369 v = sanitizeString(v)
370 params[k] = v
371 }
372
373 // Build URL parameters
374 query := url.Values{}
375 for _, k := range keys {
376 query.Set(k, params[k])
377 }
378 queryStr := query.Encode()
379
380 // Calculate w_rid
381 hash := md5.Sum([]byte(queryStr + mixinKey))
382 params["w_rid"] = hex.EncodeToString(hash[:])
383 return params
355 384 }
356 385
357 func GetWbiKeysCached() (string, string) {
358 updateCache()
359 imgKeyI, _ := cache.Load("imgKey")
360 subKeyI, _ := cache.Load("subKey")
361 return imgKeyI.(string), subKeyI.(string)
386 func getMixinKey(orig string) string {
387 var str strings.Builder
388 for _, v := range mixinKeyEncTab {
389 if v < len(orig) {
390 str.WriteByte(orig[v])
391 }
392 }
393 return str.String()[:32]
362 394 }
363 395
364 func GetWbiKeys() (string, string) {
365 resp, err := http.Get("https://api.bilibili.com/x/web-interface/nav")
366 if err != nil {
367 fmt.Println("Error:", err)
368 return "", ""
369 }
370 defer resp.Body.Close()
371 body, err := ioutil.ReadAll(resp.Body)
372 if err != nil {
373 fmt.Println("Error:", err)
374 return "", ""
375 }
376 json := string(body)
377 imgURL := gjson.Get(json, "data.wbi_img.img_url").String()
378 subURL := gjson.Get(json, "data.wbi_img.sub_url").String()
379 imgKey := strings.Split(strings.Split(imgURL, "/")[len(strings.Split(imgURL, "/"))-1], ".")[0]
380 subKey := strings.Split(strings.Split(subURL, "/")[len(strings.Split(subURL, "/"))-1], ".")[0]
381 return imgKey, subKey
396 func sanitizeString(s string) string {
397 unwantedChars := []string{"!", "'", "(", ")", "*"}
398 for _, char := range unwantedChars {
399 s = strings.ReplaceAll(s, char, "")
400 }
401 return s
382 402 }
383 403
384 func SignURL(urlStr string) string {
385 urlObj, _ := url.Parse(urlStr)
386 imgKey, subKey := GetWbiKeysCached()
387 fmt.Println(imgKey, subKey)
388 query := urlObj.Query()
389 params := map[string]string{}
390 for k, v := range query {
391 params[k] = v[0]
392 }
393 newParams := EncWbi(params, imgKey, subKey)
394 for k, v := range newParams {
395 query.Set(k, v)
396 }
397 urlObj.RawQuery = query.Encode()
398 newUrlStr := urlObj.String()
399 return newUrlStr
404 func updateCache() {
405 if time.Since(lastUpdateTime).Minutes() < 10 {
406 return
407 }
408 imgKey, subKey := getWbiKeys()
409 cache.Store("imgKey", imgKey)
410 cache.Store("subKey", subKey)
411 lastUpdateTime = time.Now()
400 412 }
401 func main() {
402 urlStr := "https://api.bilibili.com/x/space/wbi/acc/info?mid=1850091"
403 newUrlStr := utils.SignURL(urlStr) // 签名
404 req, err := http.NewRequest("GET", newUrlStr, nil)
405 if err != nil {
406 return nil, err
407 }
408 // 设置请求头,模拟浏览器
409 req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
410 response, err := http.DefaultClient.Do(req)
411 fmt.Println(newUrlStr)
412 if err != nil {
413 fmt.Printf("请求发送失败:%s", err)
414 return nil, err
415 }
416 defer response.Body.Close()
417 body, err := ioutil.ReadAll(response.Body)
418 if err != nil {
419 fmt.Printf("读取响应失败:%s", err)
420 return nil, err
421 }
422 fmt.Println(string(body))
413
414 func getWbiKeysCached() (string, string) {
415 updateCache()
416 imgKeyI, _ := cache.Load("imgKey")
417 subKeyI, _ := cache.Load("subKey")
418 return imgKeyI.(string), subKeyI.(string)
419 }
420
421 func getWbiKeys() (string, string) {
422 resp, err := http.Get("https://api.bilibili.com/x/web-interface/nav")
423 if err != nil {
424 fmt.Printf("Error: %s", err)
425 return "", ""
426 }
427 defer resp.Body.Close()
428 body, err := io.ReadAll(resp.Body)
429 if err != nil {
430 fmt.Printf("Error: %s", err)
431 return "", ""
432 }
433 json := string(body)
434 imgURL := gjson.Get(json, "data.wbi_img.img_url").String()
435 subURL := gjson.Get(json, "data.wbi_img.sub_url").String()
436 imgKey := strings.Split(strings.Split(imgURL, "/")[len(strings.Split(imgURL, "/"))-1], ".")[0]
437 subKey := strings.Split(strings.Split(subURL, "/")[len(strings.Split(subURL, "/"))-1], ".")[0]
438 return imgKey, subKey
423 439 }
424 440 ```
425 441