SocialSisterYi / bilibili-API-collect

哔哩哔哩-API收集整理【不断更新中....】
https://socialsisteryi.github.io/bilibili-API-collect/
Other
15.3k stars 1.73k forks source link

请问为什么这2个up的全部投稿里,有的在视频里能看到包含"充电专属"标记的投稿,另一个up有需要充电的视频却不展示在视频里 #974

Open kiddkyd2 opened 9 months ago

kiddkyd2 commented 9 months ago

这个up的视频投稿,能看到全部的视频,包含”充电专属”的,也包含普通的视频 https://space.bilibili.com/1492237636/video

这个up的视频投稿,不会展示”充电专属”的视频,必须要去”充电专属”的合集里,才能看到 https://space.bilibili.com/385805493/video

我用的是这个接口查询 https://api.bilibili.com/x/space/wbi/arc/search,可以通过 is_charging_arc 这个属性判断是否是充电专属视频。

如果换成这个接口,https://api.bilibili.com/x/space/arc/list 就会全部展示,但是无法判断哪些视频是”充电专属”。

我也看到了,有贴子讨论了,部分视频只会出现在合集里这个问题。但是我这个问题的情况,也是这样子的原因吗?

My-Responsitories commented 9 months ago

385805493甚至连app端都不能看到充电视频 api.bilibili.com/x/space/arc/list或许可以通过 !($.data.archives[].rights.hd5 && $.data.archives[].rights.autoplay) 判断是不是充电视频?

cxw620 commented 9 months ago

385805493甚至连app端都不能看到充电视频 api.bilibili.com/x/space/arc/list或许可以通过 !($.data.archives[].rights.hd5 && $.data.archives[].rights.autoplay) 判断是不是充电视频?

APP 端可以啊, 7.67.0, 可能是 dev 的状态, 各种 API 还不稳定.

而且似乎 typeid 不一样, 充电专属视频应该也有许多种, 只能去合集里面找的是 228 / 201, 另一个是 241, 这是他们唯一区别了, 不过我不清楚实际含义...

P.S., 从现网 F12 看看官方正在用的 API 会好点, 老接口可能确实顾不上

My-Responsitories commented 9 months ago

APP 端可以啊, 7.67.0, 可能是 dev 的状态, 各种 API 还不稳定.

我这边必须要点击充电专属才能看到, 所有视频里面是没有的

cxw620 commented 9 months ago

APP 端可以啊, 7.67.0, 可能是 dev 的状态, 各种 API 还不稳定.

我这边必须要点击充电专属才能看到, 所有视频里面是没有的

我又看了看, 现在也这样了, 奇怪()

xfangfang commented 9 months ago

应该是 up 主给合集设置了 空间防刷屏, 这样同一个合集就只会在个人主页显示一次,后面上传的充电专属视频因此不显示在主页上。

fanza1 commented 2 weeks ago

用https://api.bilibili.com/x/space/wbi/arc/search 出来的视频很多缺失充电专属,而且不包含动态视频,不知道怎么修复

目前看来可能只能用https://api.bilibili.com/x/space/arc/list 搜出来直接一个个扫是否是充电视频

edit: 找到一个方法获取用户所有充电视频,但不知道怎么获取动态视频,如果有人知道的话请告诉我

需要设置SESSDATA,用uid调用getBvidList_is_charging()

from functools import reduce
from hashlib import md5
import urllib.parse
import time
import requests
import sys
import cfscrape

# Headers with session information for authorization
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0',
    'Cookie': 'SESSDATA=' + SESSDATA,
    'Referer': 'https://message.bilibili.com/',
}

mixinKeyEncTab = [
    46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
    33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
    61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
    36, 20, 34, 44, 52
]

def getjson(url, headers=None):
    """Fetch JSON data with cfscrape to handle Cloudflare protection."""
    scraper = cfscrape.create_scraper()
    response = scraper.get(url, headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Request failed with status: {response.status_code}")
        return None

def getMixinKey(orig: str):
    """Encode imgKey and subKey based on specific mixinKeyEncTab."""
    return reduce(lambda s, i: s + orig[i], mixinKeyEncTab, '')[:32]

def encWbi(params: dict, img_key: str, sub_key: str):
    """Generate WBI signature for the parameters."""
    mixin_key = getMixinKey(img_key + sub_key)
    curr_time = round(time.time())
    params['wts'] = curr_time
    # special_type=charging
    params['special_type'] = 'charging'
    params = dict(sorted(params.items()))
    params = {
        k: ''.join(filter(lambda chr: chr not in "!'()*", str(v)))
        for k, v in params.items()
    }
    query = urllib.parse.urlencode(params)
    wbi_sign = md5((query + mixin_key).encode()).hexdigest()
    params['w_rid'] = wbi_sign
    return params

def getWbiKeys():
    """Get the latest img_key and sub_key from Bilibili API."""
    resp = getjson('https://api.bilibili.com/x/web-interface/nav', headers=headers)
    if resp and 'data' in resp:
        img_url = resp['data']['wbi_img']['img_url']
        sub_url = resp['data']['wbi_img']['sub_url']
        img_key = img_url.rsplit('/', 1)[1].split('.')[0]
        sub_key = sub_url.rsplit('/', 1)[1].split('.')[0]
        return img_key, sub_key
    else:
        raise ValueError("Failed to retrieve WBI keys from Bilibili API")

def get_query(**parameters):
    """Get signed query parameters for the API request."""
    img_key, sub_key = getWbiKeys()
    signed_params = encWbi(params=parameters, img_key=img_key, sub_key=sub_key)
    return urllib.parse.urlencode(signed_params)

def getpageinfo(uid, page=1):
    """Retrieve information of videos on a specific page for a user."""
    query = get_query(mid=uid, ps=50, pn=page)
    url_getvideo = f'https://api.bilibili.com/x/space/wbi/arc/search?{query}'
    print(url_getvideo)
    try:
        response = requests.get(url_getvideo, headers=headers)
        response.raise_for_status()
        # print(response.json())
        videoinfo = response.json()['data']['list']['vlist']
    except Exception as e:
        print(f"Error fetching video info: {e}")
        videoinfo = None
    return videoinfo

def dic2bvid_is_charging(data):
    """Return BVID list of videos with 'is_charging_arc' flag set."""
    for item in data:
        if item.get('is_charging_arc', False):
            print(">> Charging video:", item['title'], item['bvid'])
        else:
            print(item['title'], item['bvid'])
    return [item['bvid'] for item in data if item.get('is_charging_arc', False)]

def getBvidList_is_charging(uid):
    """Retrieve a list of BVIDs with 'is_charging_arc' flag set for all pages."""
    page = 1
    BvidList = []
    while True:
        data = getpageinfo(uid, page)
        if not data:  # Stop if there's no more data
            break
        BvidList.extend(dic2bvid_is_charging(data))
        page += 1
    return BvidList