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

XFEstudio/bilibili-API-collect

修复Demo访问/x/web-interface/nav被ban的问题 (#991)

尝试向demo代码添加referer头和user-agent来解决被ban

64e1bde
Ivan Hanloth <ivan@hanloth.com>
提交于

代码差异

1 个文件 +193 -163
Modified docs/misc/sign/wbi.md +193 -163
@@ -163,7 +163,11 @@ def encWbi(params: dict, img_key: str, sub_key: str):
163 163
164 164 def getWbiKeys() -> tuple[str, str]:
165 165 '获取最新的 img_key 和 sub_key'
166 resp = requests.get('https://api.bilibili.com/x/web-interface/nav')
166 headers = {
167 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
168 'Referer': 'https://www.bilibili.com/'
169 }
170 resp = requests.get('https://api.bilibili.com/x/web-interface/nav', headers=headers)
167 171 resp.raise_for_status()
168 172 json_content = resp.json()
169 173 img_url: str = json_content['data']['wbi_img']['img_url']
@@ -240,7 +244,9 @@ async function getWbiKeys() {
240 244 const res = await fetch('https://api.bilibili.com/x/web-interface/nav', {
241 245 headers: {
242 246 // SESSDATA 字段
243 Cookie: "SESSDATA=xxxxxx"
247 Cookie: "SESSDATA=xxxxxx",
248 User-Agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
249 Referer: 'https://www.bilibili.com/'//对于直接浏览器调用可能不适用
244 250 }
245 251 })
246 252 const { data: { wbi_img: { img_url, sub_url } } } = await res.json()
@@ -283,163 +289,172 @@ bar=514&baz=1919810&foo=114&wts=1684805578&w_rid=bb97e15f28edf445a0e4420d36f0157
283 289 package main
284 290
285 291 import (
286 "crypto/md5"
287 "encoding/hex"
288 "fmt"
289 "io"
290 "net/http"
291 "net/url"
292 "sort"
293 "strconv"
294 "strings"
295 "sync"
296 "time"
297
298 "github.com/tidwall/gjson"
292 "crypto/md5"
293 "encoding/hex"
294 "fmt"
295 "io"
296 "net/http"
297 "net/url"
298 "sort"
299 "strconv"
300 "strings"
301 "sync"
302 "time"
303
304 "github.com/tidwall/gjson"
299 305 )
300 306
301 307 var (
302 mixinKeyEncTab = []int{
303 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
304 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
305 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
306 36, 20, 34, 44, 52,
307 }
308 cache sync.Map
309 lastUpdateTime time.Time
308 mixinKeyEncTab = []int{
309 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
310 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
311 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
312 36, 20, 34, 44, 52,
313 }
314 cache sync.Map
315 lastUpdateTime time.Time
310 316 )
311 317
312 318 func main() {
313 urlStr := "https://api.bilibili.com/x/space/wbi/acc/info?mid=1850091"
314 newUrlStr, err := signAndGenerateURL(urlStr)
315 if err != nil {
316 fmt.Printf("Error: %s", err)
317 return
318 }
319 req, err := http.NewRequest("GET", newUrlStr, nil)
320 if err != nil {
321 fmt.Printf("Error: %s", err)
322 return
323 }
324 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")
325 response, err := http.DefaultClient.Do(req)
326 if err != nil {
327 fmt.Printf("Request failed: %s", err)
328 return
329 }
330 defer response.Body.Close()
331 body, err := io.ReadAll(response.Body)
332 if err != nil {
333 fmt.Printf("Failed to read response: %s", err)
334 return
335 }
336 fmt.Println(string(body))
319 urlStr := "https://api.bilibili.com/x/space/wbi/acc/info?mid=1850091"
320 newUrlStr, err := signAndGenerateURL(urlStr)
321 if err != nil {
322 fmt.Printf("Error: %s", err)
323 return
324 }
325 req, err := http.NewRequest("GET", newUrlStr, nil)
326 if err != nil {
327 fmt.Printf("Error: %s", err)
328 return
329 }
330 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")
331 req.Header.Set("Referer", "https://www.bilibili.com/")
332 response, err := http.DefaultClient.Do(req)
333 if err != nil {
334 fmt.Printf("Request failed: %s", err)
335 return
336 }
337 defer response.Body.Close()
338 body, err := io.ReadAll(response.Body)
339 if err != nil {
340 fmt.Printf("Failed to read response: %s", err)
341 return
342 }
343 fmt.Println(string(body))
337 344 }
338 345
339 346 func signAndGenerateURL(urlStr string) (string, error) {
340 urlObj, err := url.Parse(urlStr)
341 if err != nil {
342 return "", err
343 }
344 imgKey, subKey := getWbiKeysCached()
345 query := urlObj.Query()
346 params := map[string]string{}
347 for k, v := range query {
348 params[k] = v[0]
349 }
350 newParams := encWbi(params, imgKey, subKey)
351 for k, v := range newParams {
352 query.Set(k, v)
353 }
354 urlObj.RawQuery = query.Encode()
355 newUrlStr := urlObj.String()
356 return newUrlStr, nil
347 urlObj, err := url.Parse(urlStr)
348 if err != nil {
349 return "", err
350 }
351 imgKey, subKey := getWbiKeysCached()
352 query := urlObj.Query()
353 params := map[string]string{}
354 for k, v := range query {
355 params[k] = v[0]
356 }
357 newParams := encWbi(params, imgKey, subKey)
358 for k, v := range newParams {
359 query.Set(k, v)
360 }
361 urlObj.RawQuery = query.Encode()
362 newUrlStr := urlObj.String()
363 return newUrlStr, nil
357 364 }
358 365
359 366 func encWbi(params map[string]string, imgKey, subKey string) map[string]string {
360 mixinKey := getMixinKey(imgKey + subKey)
361 currTime := strconv.FormatInt(time.Now().Unix(), 10)
362 params["wts"] = currTime
363
364 // Sort keys
365 keys := make([]string, 0, len(params))
366 for k := range params {
367 keys = append(keys, k)
368 }
369 sort.Strings(keys)
370
371 // Remove unwanted characters
372 for k, v := range params {
373 v = sanitizeString(v)
374 params[k] = v
375 }
376
377 // Build URL parameters
378 query := url.Values{}
379 for _, k := range keys {
380 query.Set(k, params[k])
381 }
382 queryStr := query.Encode()
383
384 // Calculate w_rid
385 hash := md5.Sum([]byte(queryStr + mixinKey))
386 params["w_rid"] = hex.EncodeToString(hash[:])
387 return params
367 mixinKey := getMixinKey(imgKey + subKey)
368 currTime := strconv.FormatInt(time.Now().Unix(), 10)
369 params["wts"] = currTime
370
371 // Sort keys
372 keys := make([]string, 0, len(params))
373 for k := range params {
374 keys = append(keys, k)
375 }
376 sort.Strings(keys)
377
378 // Remove unwanted characters
379 for k, v := range params {
380 v = sanitizeString(v)
381 params[k] = v
382 }
383
384 // Build URL parameters
385 query := url.Values{}
386 for _, k := range keys {
387 query.Set(k, params[k])
388 }
389 queryStr := query.Encode()
390
391 // Calculate w_rid
392 hash := md5.Sum([]byte(queryStr + mixinKey))
393 params["w_rid"] = hex.EncodeToString(hash[:])
394 return params
388 395 }
389 396
390 397 func getMixinKey(orig string) string {
391 var str strings.Builder
392 for _, v := range mixinKeyEncTab {
393 if v < len(orig) {
394 str.WriteByte(orig[v])
395 }
396 }
397 return str.String()[:32]
398 var str strings.Builder
399 for _, v := range mixinKeyEncTab {
400 if v < len(orig) {
401 str.WriteByte(orig[v])
402 }
403 }
404 return str.String()[:32]
398 405 }
399 406
400 407 func sanitizeString(s string) string {
401 unwantedChars := []string{"!", "'", "(", ")", "*"}
402 for _, char := range unwantedChars {
403 s = strings.ReplaceAll(s, char, "")
404 }
405 return s
408 unwantedChars := []string{"!", "'", "(", ")", "*"}
409 for _, char := range unwantedChars {
410 s = strings.ReplaceAll(s, char, "")
411 }
412 return s
406 413 }
407 414
408 415 func updateCache() {
409 if time.Since(lastUpdateTime).Minutes() < 10 {
410 return
411 }
412 imgKey, subKey := getWbiKeys()
413 cache.Store("imgKey", imgKey)
414 cache.Store("subKey", subKey)
415 lastUpdateTime = time.Now()
416 if time.Since(lastUpdateTime).Minutes() < 10 {
417 return
418 }
419 imgKey, subKey := getWbiKeys()
420 cache.Store("imgKey", imgKey)
421 cache.Store("subKey", subKey)
422 lastUpdateTime = time.Now()
416 423 }
417 424
418 425 func getWbiKeysCached() (string, string) {
419 updateCache()
420 imgKeyI, _ := cache.Load("imgKey")
421 subKeyI, _ := cache.Load("subKey")
422 return imgKeyI.(string), subKeyI.(string)
426 updateCache()
427 imgKeyI, _ := cache.Load("imgKey")
428 subKeyI, _ := cache.Load("subKey")
429 return imgKeyI.(string), subKeyI.(string)
423 430 }
424 431
425 432 func getWbiKeys() (string, string) {
426 resp, err := http.Get("https://api.bilibili.com/x/web-interface/nav")
427 if err != nil {
428 fmt.Printf("Error: %s", err)
429 return "", ""
430 }
431 defer resp.Body.Close()
432 body, err := io.ReadAll(resp.Body)
433 if err != nil {
434 fmt.Printf("Error: %s", err)
435 return "", ""
436 }
437 json := string(body)
438 imgURL := gjson.Get(json, "data.wbi_img.img_url").String()
439 subURL := gjson.Get(json, "data.wbi_img.sub_url").String()
440 imgKey := strings.Split(strings.Split(imgURL, "/")[len(strings.Split(imgURL, "/"))-1], ".")[0]
441 subKey := strings.Split(strings.Split(subURL, "/")[len(strings.Split(subURL, "/"))-1], ".")[0]
442 return imgKey, subKey
433 client := &http.Client{}
434 req, err := http.NewRequest("GET", "https://api.bilibili.com/x/web-interface/nav", nil)
435 if err != nil {
436 fmt.Printf("Error creating request: %s", err)
437 return "", ""
438 }
439 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")
440 req.Header.Set("Referer", "https://www.bilibili.com/")
441 resp, err := client.Do(req)
442 if err != nil {
443 fmt.Printf("Error sending request: %s", err)
444 return "", ""
445 }
446 defer resp.Body.Close()
447 body, err := io.ReadAll(resp.Body)
448 if err != nil {
449 fmt.Printf("Error reading response: %s", err)
450 return "", ""
451 }
452 json := string(body)
453 imgURL := gjson.Get(json, "data.wbi_img.img_url").String()
454 subURL := gjson.Get(json, "data.wbi_img.sub_url").String()
455 imgKey := strings.Split(strings.Split(imgURL, "/")[len(strings.Split(imgURL, "/"))-1], ".")[0]
456 subKey := strings.Split(strings.Split(subURL, "/")[len(strings.Split(subURL, "/"))-1], ".")[0]
457 return imgKey, subKey
443 458 }
444 459 ```
445 460
@@ -495,23 +510,28 @@ class Program
495 510 }
496 511
497 512 // 获取最新的 img_key 和 sub_key
498 private static async Task<(string, string)> GetWbiKeys()
499 {
500 HttpResponseMessage responseMessage = await _httpClient.SendAsync(new HttpRequestMessage
501 {
502 Method = HttpMethod.Get,
503 RequestUri = new Uri("https://api.bilibili.com/x/web-interface/nav"),
504 });
513 private static async Task<(string, string)> GetWbiKeys()
514 {
515 var httpClient = new HttpClient();
516 httpClient.DefaultRequestHeaders.Add("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");
517 httpClient.DefaultRequestHeaders.Referrer = new Uri("https://www.bilibili.com/");
518
519 HttpResponseMessage responseMessage = await httpClient.SendAsync(new HttpRequestMessage
520 {
521 Method = HttpMethod.Get,
522 RequestUri = new Uri("https://api.bilibili.com/x/web-interface/nav"),
523 });
524
525 JsonNode response = JsonNode.Parse(await responseMessage.Content.ReadAsStringAsync())!;
526
527 string imgUrl = (string)response["data"]!["wbi_img"]!["img_url"]!;
528 imgUrl = imgUrl.Split("/")[^1].Split(".")[0];
529
530 string subUrl = (string)response["data"]!["wbi_img"]!["sub_url"]!;
531 subUrl = subUrl.Split("/")[^1].Split(".")[0];
532 return (imgUrl, subUrl);
533 }
505 534
506 JsonNode response = JsonNode.Parse(await responseMessage.Content.ReadAsStringAsync())!;
507
508 string imgUrl = (string)response["data"]!["wbi_img"]!["img_url"]!;
509 imgUrl = imgUrl.Split("/")[^1].Split(".")[0];
510
511 string subUrl = (string)response["data"]!["wbi_img"]!["sub_url"]!;
512 subUrl = subUrl.Split("/")[^1].Split(".")[0];
513 return (imgUrl, subUrl);
514 }
515 535
516 536 public static async Task Main()
517 537 {
@@ -584,6 +604,8 @@ public class WbiTest {
584 604 map.put("bar", "五一四");
585 605 map.put("baz", 1919810);
586 606 map.put("wts", System.currentTimeMillis() / 1000);
607 map.put("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");
608 map.put("Referer", "https://www.bilibili.com/");
587 609 StringJoiner param = new StringJoiner("&");
588 610 //排序 + 拼接字符串
589 611 map.entrySet().stream()
@@ -679,6 +701,7 @@ class Bilibili {
679 701 $header[] = "Accept: */*";
680 702 $header[] = "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7";
681 703 $header[] = "Connection: close";
704 $header[]="Referer:https://www.bilibili.com/";
682 705 $header[] = "Cache-Control: max-age=0";
683 706 curl_setopt_array($ch, [
684 707 CURLOPT_HTTPGET => 1,
@@ -796,6 +819,7 @@ async fn get_wbi_keys() -> Result<(String, String), reqwest::Error> {
796 819 let ResWbi { data:Data{wbi_img} } = client
797 820 .get("https://api.bilibili.com/x/web-interface/nav")
798 821 .header(USER_AGENT,"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36")
822 .header("Referer","https://www.bilibili.com/")
799 823 // SESSDATA=xxxxx
800 824 .header("Cookie", "SESSDATA=xxxxx")
801 825 .send()
@@ -849,21 +873,27 @@ func biliWbiSign(param: String, completion: @escaping (String?) -> Void) {
849 873 return params
850 874 }
851 875
852 func getWbiKeys(completion: @escaping (Result<(imgKey: String, subKey: String), Error>) -> Void) {
853 AF.request("https://api.bilibili.com/x/web-interface/nav").responseJSON { response in
854 switch response.result {
855 case .success(let value):
856 let json = JSON(value)
857 let imgURL = json["data"]["wbi_img"]["img_url"].string ?? ""
858 let subURL = json["data"]["wbi_img"]["sub_url"].string ?? ""
859 let imgKey = imgURL.components(separatedBy: "/").last?.components(separatedBy: ".").first ?? ""
860 let subKey = subURL.components(separatedBy: "/").last?.components(separatedBy: ".").first ?? ""
861 completion(.success((imgKey, subKey)))
862 case .failure(let error):
863 completion(.failure(error))
864 }
865 }
866 }
876 func getWbiKeys(completion: @escaping (Result<(imgKey: String, subKey: String), Error>) -> Void) {
877 let headers: HTTPHeaders = [
878 "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",
879 "Referer": "https://www.bilibili.com/"
880 ]
881
882 AF.request("https://api.bilibili.com/x/web-interface/nav", headers: headers).responseJSON { response in
883 switch response.result {
884 case .success(let value):
885 let json = JSON(value)
886 let imgURL = json["data"]["wbi_img"]["img_url"].string ?? ""
887 let subURL = json["data"]["wbi_img"]["sub_url"].string ?? ""
888 let imgKey = imgURL.components(separatedBy: "/").last?.components(separatedBy: ".").first ?? ""
889 let subKey = subURL.components(separatedBy: "/").last?.components(separatedBy: ".").first ?? ""
890 completion(.success((imgKey, subKey)))
891 case .failure(let error):
892 completion(.failure(error))
893 }
894 }
895 }
896
867 897
868 898 func calculateMD5(string: String) -> String {
869 899 let data = Data(string.utf8)