SocialSisterYi / bilibili-API-collect

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

用户主页获取投稿列表 -352 新增校验 #868

Open o0HalfLife0o opened 11 months ago

o0HalfLife0o commented 11 months ago

https://api.bilibili.com/x/space/wbi/arc/search?mid=2&ps=30&tid=0&pn=1&keyword=&order=pubdate&platform=web&web_location=1550101&order_avoided=true&dm_img_list=[]&dm_img_str=V2ViR0wgMS&dm_cover_img_str=QU5HTEUgKEludGVsLCBJbnRlbChSKSBIRCBHcmFwaGljcyBEaXJlY3QzRDExIHZzXzVfMCBwc181XzApR29vZ2xlIEluYy4gKEludGVsKQ&w_rid=e8319e347dca849eadcdd27f1a8a5a79&wts=1700567648

用户投稿多了dm_img_listdm_img_strdm_cover_img_str这3个值,缺少这3个值会报352错误,加上这3个值,wbi接口不添加wbi校验值都可以正常获取数据

{
    'code': -352,
    'message': '风控校验失败',
    'ttl': 1,
    'data': {
        'v_voucher': 'voucher_605d9ef3-9ca5-4498-ace1-8613ecf7a24f'
    }
}
HashLiver commented 10 months ago

近几天感觉风控没有那么严格了。如果是一个星期前,连Chrome无痕模式正常浏览用户投稿页面都有概率出现-352

那是因为 dm_img_list 缺失吧

我删了刚才的评论,目前Chrome无痕模式正常浏览用户投稿页面仍有概率出现-352,下图是刚刚测试的:

bili-352

z0z0r4 commented 10 months ago

我这边无痕模式是完全没法访问用户投稿的捏...

而且并不是新参数的问题,只是没登录 cookie 缺失

My-Responsitories commented 10 months ago

我这边无痕模式是完全没法访问用户投稿的捏...

而且并不是新参数的问题,只是没登录 cookie 缺失

如果无痕模式关闭了webgl除了Mozilla/5.0外其他ua必定出-352 有些ua好像天然就会-352, 有些只是连续请求后会出现-352

z0z0r4 commented 10 months ago

@xiaoyv404 将标题改直观点如何?比如

用户主页获取投稿列表 -352 新增校验

z0z0r4 commented 10 months ago

我这边无痕模式是完全没法访问用户投稿的捏... 而且并不是新参数的问题,只是没登录 cookie 缺失

如果无痕模式关闭了webgl除了Mozilla/5.0外其他ua必定出-352 有些ua好像天然就会-352, 有些只是连续请求后会出现-352

我可以认为这两个参数都是 WebGL 的固定字段可以直接不变吗?

My-Responsitories commented 10 months ago

我可以认为这两个参数都是 WebGL 的固定字段可以直接不变吗?

这两个应该和浏览器和操作系统相关, 这边测试将它固定不影响-352出现频率, 但不确定再多个ip的情况还有没有影响

z0z0r4 commented 10 months ago

Mozilla/5.0 免校验适用于其他接口吗?

yaobiao131 commented 10 months ago

Mozilla/5.0 免校验适用于其他接口吗?

好像是适用的。目前获取视频流也遇到了

z0z0r4 commented 10 months ago

起名困难症...有大佬给这个垃圾反爬起个名称吗

ncdn commented 10 months ago

all the args in https://browserleaks.com/webrtc , WebGL, GPU

z0z0r4 commented 10 months ago

all the args in browserleaks.com/webrtc , WebGL, GPUbrowserleaks.com/webrtc 、WebGL、GPU 中的所有参数

https://browserleaks.com/webgl

https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859078300

power721 commented 9 months ago

现在返回-403,有人遇到吗?

okashi-ya commented 9 months ago

今天Mozilla/5.0这种UA会不定时出现-352,试了一下,直接用Chrome浏览器完整的UA的话是正常的

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36

z0z0r4 commented 9 months ago

今天Mozilla/5.0这种UA会不定时出现-352,试了一下,直接用Chrome浏览器完整的UA的话是正常的

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36

看来正则修了.jpg

okashi-ya commented 9 months ago

今天Mozilla/5.0这种UA会不定时出现-352,试了一下,直接用Chrome浏览器完整的UA的话是正常的 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36

看来正则修了.jpg

早上过来看了一眼,拉取速度2秒3次左右的情况下,一晚上大概还会出现七八次的-352错误。不清楚具体原因。。 我尝试在无痕模式下疯狂强制无缓存刷新页面也没遇到过-352错误

okashi-ya commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

TDK1969 commented 9 months ago

动态相关的接口也会报-352错误了

lovetingyuan commented 9 months ago

报错+1

z0z0r4 commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

动态相关的 -352 有详细信息吗?

okashi-ya commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

动态相关的 -352 有详细信息吗?

无,只有一个-352错误码。 而且我发现哪怕我创建了十几个正常的buvid3,但是如果我轮训的时候没有加时间间隔(也就是跑完一次立刻跑下一次),这样会在几分钟后所有buvid3立刻全部-352 感觉B站也按照IP来风控了

z0z0r4 commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

动态相关的 -352 有详细信息吗?

无,只有一个-352错误码。 而且我发现哪怕我创建了十几个正常的buvid3,但是如果我轮训的时候没有加时间间隔(也就是跑完一次立刻跑下一次),这样会在几分钟后所有buvid3立刻全部-352 感觉B站也按照IP来风控了

指的是 https://github.com/SocialSisterYi/bilibili-API-collect/issues/686 这个吗?

z0z0r4 commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

并没有这么回事吧...我这边轮询了几百次都没事

import requests

headers = {
    "referer": "https://space.bilibili.com/2/dynamic",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0",
}

buvid3 = requests.get(
    "https://api.bilibili.com/x/frontend/finger/spi", headers=headers
).json()["data"]["b_3"]
print(buvid3)
cookies = {
    "buvid3": buvid3,
}

i = 0
while True:
    response = requests.get(
        "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=186492380550777365&host_mid=2&timezone_offset=-480&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote&web_location=333.999",
        cookies=cookies,
        headers=headers,
    )
    if response.status_code == 200:
        print(f"{response.status_code} {i} times")
        i += 1
    else:
        print(f"{response.status_code}")
        break

image

kaosaa commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

并没有这么回事吧...我这边轮询了几百次都没事

import requests

headers = {
    "referer": "https://space.bilibili.com/2/dynamic",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0",
}

buvid3 = requests.get(
    "https://api.bilibili.com/x/frontend/finger/spi", headers=headers
).json()["data"]["b_3"]
print(buvid3)
cookies = {
    "buvid3": buvid3,
}

i = 0
while True:
    response = requests.get(
        "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=186492380550777365&host_mid=2&timezone_offset=-480&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote&web_location=333.999",
        cookies=cookies,
        headers=headers,
    )
    if response.status_code == 200:
        print(f"{response.status_code} {i} times")
        i += 1
    else:
        print(f"{response.status_code}")
        break

image

你这个思路上有问题。。无论如何B站返回的状态码都是200,这只是网页访问成功了。要看他json里的code这个参数

TDK1969 commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

并没有这么回事吧...我这边轮询了几百次都没事

import requests

headers = {
    "referer": "https://space.bilibili.com/2/dynamic",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0",
}

buvid3 = requests.get(
    "https://api.bilibili.com/x/frontend/finger/spi", headers=headers
).json()["data"]["b_3"]
print(buvid3)
cookies = {
    "buvid3": buvid3,
}

i = 0
while True:
    response = requests.get(
        "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=186492380550777365&host_mid=2&timezone_offset=-480&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote&web_location=333.999",
        cookies=cookies,
        headers=headers,
    )
    if response.status_code == 200:
        print(f"{response.status_code} {i} times")
        i += 1
    else:
        print(f"{response.status_code}")
        break

image

不是http响应码,是json格式的报文里面code字段为-352 格式为 {"code":-352,"message":"-352","ttl":1}

z0z0r4 commented 9 months ago

今天所有都-352了,经过尝试,发现一个规律: 正常浏览器的buvid3是可以拉取动态的,但是直接https://api.bilibili.com/x/frontend/finger/spi拿到的buvid3拉取动态会直接失败。 怀疑是需要做一些基本的初始化后这个buvid3才可以使用

并没有这么回事吧...我这边轮询了几百次都没事

import requests

headers = {
    "referer": "https://space.bilibili.com/2/dynamic",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0",
}

buvid3 = requests.get(
    "https://api.bilibili.com/x/frontend/finger/spi", headers=headers
).json()["data"]["b_3"]
print(buvid3)
cookies = {
    "buvid3": buvid3,
}

i = 0
while True:
    response = requests.get(
        "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=186492380550777365&host_mid=2&timezone_offset=-480&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote&web_location=333.999",
        cookies=cookies,
        headers=headers,
    )
    if response.status_code == 200:
        print(f"{response.status_code} {i} times")
        i += 1
    else:
        print(f"{response.status_code}")
        break

image

你这个思路上有问题。。无论如何B站返回的状态码都是200,这只是网页访问成功了。要看他json里的code这个参数

草我的锅,大早上冲傻了

我回去试试看…

renmu123 commented 9 months ago

动态接口去隔壁#686讨论吧,这两个接口的风控参数是完全不一样的,一样的只有神奇不受风控的Mozilla/5.0的ua头失效了。

投稿接口

  1. cookie需要加上buvid3参数,具体的值可以随便填
  2. query参数需要加上dm_img_list, dm_img_str,dm_cover_img_str,只有dm_cover_img_str参数是必填的,具体算法见吾爱破解你也可以填固定值dm_img_list可以填写"[]", dm_img_str可以填写“”。这三个参数也加入Wbi签名。

动态接口

动态接口代码可以参考 https://github.com/SocialSisterYi/bilibili-API-collect/issues/686#issuecomment-1619755760 ,简单测试可用

z0z0r4 commented 9 months ago

动态接口去隔壁#686讨论吧,这两个接口的风控参数是完全不一样的,一样的只有神奇不受风控的Mozilla/5.0的ua头失效了。

投稿接口

  1. cookie需要加上buvid3参数,具体的值可以随便填
  2. query参数需要加上dm_img_list, dm_img_str,dm_cover_img_str,只有dm_cover_img_str参数是必填的,具体算法见吾爱破解,~你也可以填固定值~,dm_img_list可以填写"[]", dm_img_str可以填写“”。这三个参数也加入Wbi签名。

动态接口

动态接口代码可以参考 #686 (comment) ,简单测试可用

那边issue又把我☞这边来了...

Kataick commented 9 months ago

现在返回-403,有人遇到吗?

我遇到了 wbi计算错误 我通过排查wbi的算法解决了

gq20110204 commented 9 months ago

动态接口去隔壁#686讨论吧,这两个接口的风控参数是完全不一样的,一样的只有神奇不受风控的Mozilla/5.0的ua头失效了。

投稿接口

  1. cookie需要加上buvid3参数,具体的值可以随便填
  2. query参数需要加上dm_img_list, dm_img_str,dm_cover_img_str,只有dm_cover_img_str参数是必填的,具体算法见吾爱破解,~你也可以填固定值~,dm_img_list可以填写"[]", dm_img_str可以填写“”。这三个参数也加入Wbi签名。

动态接口

动态接口代码可以参考 #686 (comment) ,简单测试可用

按照这个跑了几天 观察到一些情况 这两个接口 跑多了依旧会风控 投稿接口风控比动态接口更严格

针对投稿接口进行了一些测试(每次测试间隔10分钟 dm参数用的固定值 同一轮测试用的同一个cookie 生成cookie 只传必要参数并wbi签名 100次请求左右就会跳-352 尝试每次请求更换一个cookie 没用 甚至跳-352更快 尝试补全除了pn和ps外的全部请求参数 没用 依旧100次请求左右跳-352 尝试加大间隔到15分钟 没用 次数到了就-352 尝试每次请求sleep2秒 没用 次数到了就-352 尝试使用真实账号cookie去请求 即使不加三个dm开头的参数 只进行wbi签名 依旧不会风控(但这么做对账号有什么影响未知 而且风控限制阈值似乎是动态的 昨天这个时候 生成cookie请求200次也能正常 今晚再看就不行了 暂时先用小号跑着继续观察

power721 commented 9 months ago

现在返回-403,有人遇到吗?

我遇到了 wbi计算错误 我通过排查wbi的算法解决了

wbi没有问题,生成的链接浏览器能正常访问

My-Responsitories commented 9 months ago

我这边测试下来, 和-352相关的有cookie, ip, ua. cookie里只需要任意合法的buvid3(uuid+"%05d"+"infoc")即可.

无特殊说明, cookie与buvid3均指cookie中只包含合法的buvid3

未携带cookie时有少部分ua可以大量请求, 但效果不如携带cookie, 大部分ua在第一次请求时就出现了-352, 携带cookie时几乎所有合法的ua在第一次请求时均不会出现-352

相同的buvid3最多处理异步发起的200个请求, 超过部分将出现-352(如果并发过大, 可能会有少量请求突破200上限(800个出现216个成功), 也许是服务器忘了加锁?), 同时该buvid3将无效, 需要再次随机一个

同个ip有上限(在达到上限前会间歇出现, 且频率逐渐增加的-352), 达到上限时只能使用完成了geetest的buvid3进行请求, 即便使用浏览器隐身模式打开也需要geetest

完成了geetest的buvid3也会再次被风控, 并且上限比ip上限低, 再次被风控后, 该buvid3每次请求都需要完成geetest. 但再次生成buvid3后并完成一次geetest, 该buvid3可不完成geetest直接使用

用携带SESSDATA的cookie也可以解除ip的限制, 但不清楚是否会对账号造成影响

测试:

async def req(client:httpx.AsyncClient, headers:dict, cookies:dict, mid:int=0):
    params = {
        'mid': mid,
        'pn': '1',
        'ps': '25',
        'order': 'pubdate',
        'dm_img_list': '[]',
        'dm_img_str': base64.b64encode(bytes(random.choices(range(0x20, 0x7f), k=random.randint(16, 64))))[:-2].decode(),
        'dm_cover_img_str': base64.b64encode(bytes(random.choices(range(0x20, 0x7f), k=random.randint(32, 128))))[:-2].decode(),
        'wts': int(time.time())
    }
    params = sign(params) # w_rid签名
    errs = []
    for _ in range(3):
        try:
            response = await client.get(
                'https://api.bilibili.com/x/space/wbi/arc/search',
                params=params,
                headers=headers,
                cookies=cookies
            )
        except httpx.TransportError as e:
            errs.append(e)
        else:
            break
    else:
        raise ExceptionGroup('TransportError', errs)
    code = ujson.loads(response.content)['code']
    return code

async def loop(client:httpx.AsyncClient):
    headers = {
        'user-agent': f'Mozilla/5.0 (X11; Linux x86_64; rv:{random.randint(60, 120)}.0) Gecko/20100101 Firefox/{random.randint(60, 120)}.0',
    }
    cookies = {
        'buvid3': f'{str(uuid.uuid4()).upper()}{random.randint(0, 99999):05d}infoc',
    }
    codes = await asyncio.gather(*(
        req(client, headers, cookies, mid)
        for mid in range(1, 201) # 最多处理异步发起的200个请求
    ))
    print(collections.Counter(codes))

async def main():
    async with httpx.AsyncClient(http2=True, http1=False, timeout=10) as client:
        await asyncio.gather(*(
            loop(client)
            for _ in range(5) # 根据CPU和网络调节, 不宜太大
        ))

asyncio.run(main())
cxw620 commented 9 months ago

接楼上的, 反正单个 IP / BUVID 都有并发上限和单位时间内请求数上限, 大概率这个阈值是按正常未登录用户的请求频次的大数据来定, 登陆后按登陆用户的请求频次, 应该也有时间相关性.

更多地: buvid4 后面那串 base64 应该是和 IP 相关的可逆的(?)加密, 所以 buvid4 不能乱编, 或者也可以试试设置为 "buvid4-failed-1". 加密算法就得密码学佬来看看了.

z0z0r4 commented 9 months ago

接楼上的, 反正单个 IP / BUVID 都有并发上限和单位时间内请求数上限, 大概率这个阈值是按正常未登录用户的请求频次的大数据来定, 登陆后按登陆用户的请求频次, 应该也有时间相关性.

更多地: buvid4 后面那串 base64 应该是和 IP 相关的可逆的(?)加密, 所以 buvid4 不能乱编, 或者也可以试试设置为 "buvid4-failed-1". 加密算法就得密码学佬来看看了.

buvid4-failed-1 是什么?

cxw620 commented 9 months ago

接楼上的, 反正单个 IP / BUVID 都有并发上限和单位时间内请求数上限, 大概率这个阈值是按正常未登录用户的请求频次的大数据来定, 登陆后按登陆用户的请求频次, 应该也有时间相关性. 更多地: buvid4 后面那串 base64 应该是和 IP 相关的可逆的(?)加密, 所以 buvid4 不能乱编, 或者也可以试试设置为 "buvid4-failed-1". 加密算法就得密码学佬来看看了.

buvid4-failed-1 是什么?

获取 buvid4 失败的时候用的默认值

yajuhua commented 8 months ago

https://api.bilibili.com/x/space/wbi/arc/search?mid=xxxxx&pn=1&ps=25&index=1&order=pubdate&order_avoided=true&platform=web&web_location=1550101&dm_img_list=[]&dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ&dm_cover_img_str=QU5HTEUgKEludGVsLCBJbnRlbChSKSBJcmlzKFRNKSBHcmFwaGljcyA2MTAwIERpcmVjdDNEMTEgdnNfNV8wIHBzXzVfMCwgRDNEMTEtMjAuMTkuMTUuNDUzMSlHb29nbGUgSW5jLiAoSW50ZW&dm_img_inter=%7B%22ds%22:[%7B%22t%22:2,%22c%22:%22Y2xlYXJmaXggZy1zZWFyY2ggc2VhcmNoLWNvbnRhaW5lcg%22,%22p%22:[2311,97,412],%22s%22:[348,810,1112]%7D,%7B%22t%22:2,%22c%22:%22c2VjdGlvbiB2aWRlbyBsb2FkaW5nIGZ1bGwtcm93cw%22,%22p%22:[1219,87,1308],%22s%22:[281,3563,2798]%7D],%22wh%22:[135,45,45],%22of%22:[201,402,201]%7D&w_rid=cfe23e0233c997ced2e8811850d431f6&wts=1706088851

我发现少了dm_img_inter就不行了,转义后如下

{"ds":[{"t":2,"c":"Y2xlYXJmaXggZy1zZWFyY2ggc2VhcmNoLWNvbnRhaW5lcg","p":[2311,97,412],"s":[348,810,1112]},{"t":2,"c":"c2VjdGlvbiB2aWRlbyBsb2FkaW5nIGZ1bGwtcm93cw","p":[1219,87,1308],"s":[281,3563,2798]}],"wh":[135,45,45],"of":[201,401,202]}

其中c进行base64解码后

{"ds":[{"t":2,"c":"clearfix g-search search-container","p":[2311,97,412],"s":[348,810,1112]},{"t":2,"c":"section video loading full-rows","p":[1219,87,1308],"s":[281,3563,2798]}],"wh":[135,45,45],"of":[201,401,202]}

而且dm_img_inter每次都不一样,就数字发生了变化,并不知道是如何生成的。

iiicebearrr commented 8 months ago

看来是的,刚测试了下自己的仓库也不行了,又调整策略了多了个dm_img_inter参数:(@yajuhua

cxw620 commented 8 months ago

https://api.bilibili.com/x/space/wbi/arc/search?mid=xxxxx&pn=1&ps=25&index=1&order=pubdate&order_avoided=true&platform=web&web_location=1550101&dm_img_list=[]&dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ&dm_cover_img_str=QU5HTEUgKEludGVsLCBJbnRlbChSKSBJcmlzKFRNKSBHcmFwaGljcyA2MTAwIERpcmVjdDNEMTEgdnNfNV8wIHBzXzVfMCwgRDNEMTEtMjAuMTkuMTUuNDUzMSlHb29nbGUgSW5jLiAoSW50ZW&dm_img_inter=%7B%22ds%22:[%7B%22t%22:2,%22c%22:%22Y2xlYXJmaXggZy1zZWFyY2ggc2VhcmNoLWNvbnRhaW5lcg%22,%22p%22:[2311,97,412],%22s%22:[348,810,1112]%7D,%7B%22t%22:2,%22c%22:%22c2VjdGlvbiB2aWRlbyBsb2FkaW5nIGZ1bGwtcm93cw%22,%22p%22:[1219,87,1308],%22s%22:[281,3563,2798]%7D],%22wh%22:[135,45,45],%22of%22:[201,402,201]%7D&w_rid=cfe23e0233c997ced2e8811850d431f6&wts=1706088851

我发现少了dm_img_inter就不行了,转义后如下

{"ds":[{"t":2,"c":"Y2xlYXJmaXggZy1zZWFyY2ggc2VhcmNoLWNvbnRhaW5lcg","p":[2311,97,412],"s":[348,810,1112]},{"t":2,"c":"c2VjdGlvbiB2aWRlbyBsb2FkaW5nIGZ1bGwtcm93cw","p":[1219,87,1308],"s":[281,3563,2798]}],"wh":[135,45,45],"of":[201,401,202]}

其中c进行base64解码后

{"ds":[{"t":2,"c":"clearfix g-search search-container","p":[2311,97,412],"s":[348,810,1112]},{"t":2,"c":"section video loading full-rows","p":[1219,87,1308],"s":[281,3563,2798]}],"wh":[135,45,45],"of":[201,401,202]}

而且dm_img_inter每次都不一样,就数字发生了变化,并不知道是如何生成的。

这是鼠标操作的记录吧, 具体实现逆向一下 js 就好.

0f-0b commented 8 months ago

目前 dm_img_listdm_img_inter 的算法大致如下。

const { floor, random } = Math;

function f114i(a, b, i) {
  const t = floor(random() * (114 * i));
  return [3 * a + 2 * b + t, 4 * a - 5 * b + t, t];
}

function f114(a, b) {
  const t = floor(random() * 114);
  return [2 * a + 2 * b + 3 * t, 4 * a - b + t, t];
}

function f514(a, b) {
  const t = floor(random() * 514);
  return [3 * a + 2 * b + t, 4 * a - 4 * b + 2 * t, t];
}

const eventTypes = ["mousemove", "click"];

/**
 * @param {Iterable<MouseEvent>} events 最近 50 次 `mousemove` 和 `click` 事件。
 * @returns {string} `dm_img_list` 的值。
 */
export function getDmImgList(events) {
  return JSON.stringify(Array.from(events, (event, index) => {
    const [x, y, z] = f114i(event.x, event.y, index);
    return {
      x,
      y,
      z,
      timestamp: floor(event.timeStamp),
      k: floor(random() * 67) + 60,
      type: eventTypes.indexOf(event.type),
    };
  }));
}

const tagNames = [
  "span", "div", "p", "a", "img", "input", "button", "ul", "ol", "li",
  "h1", "h2", "h3", "h4", "h5", "h6", "form", "textarea", "select", "option",
  "table", "tr", "td", "th", "label", "strong", "em", "section", "article",
];

/**
 * @param {DOMRectReadOnly} windowBounds
 *   初始全零,窗口大小和滚动位置都没变则保持全零;
 *   窗口大小改变时 `width` 和 `height` 属性分别更新为 `innerWidth` 和 `innerHeight`;
 *   滚动位置改变时 `x` 和 `y` 属性分别更新为 `scrollX` 和 `scrollY`。
 * @param {Iterable<Element>} elements
 *   初值是 `document.querySelectorAll("div[data-v-risk=fingerprint]")` 返回的两个元素;
 *   `mousemove` 或 `click` 时更新为只含事件的 `target` 一个元素。
 * @returns {string} `dm_img_inter` 的值。
 */
export function getDmImgInter(windowBounds, elements) {
  return JSON.stringify({
    ds: Array.from(elements, (element) => {
      const bounds = element.getBoundingClientRect();
      const [x1, y1, z1] = f114(bounds.y | 0, bounds.x | 0);
      const [x2, y2, z2] = f514(bounds.width | 0, bounds.height | 0);
      return {
        t: tagNames.indexOf(element.tagName.toLowerCase()) + 1,
        c: btoa(element.className).slice(0, -2),
        p: [x1, z1, y1],
        s: [z2, x2, y2],
      };
    }),
    wh: f114(windowBounds.width, windowBounds.height),
    of: f514(windowBounds.y, windowBounds.x),
  });
}
iiicebearrr commented 8 months ago

问一嘴有没有python版的dm_img_inter参数实现,js不是很熟悉┭┮﹏┭┮

std-microblock commented 8 months ago

经测试,随机生成的dm_img_inter参数似乎不能过风控..

o0HalfLife0o commented 8 months ago
    dm_rand = 'ABCDEFGHIJK'
    dm_img_list = '[]'
    dm_img_str = ''.join(random.sample(dm_rand, 2))
    dm_cover_img_str = ''.join(random.sample(dm_rand, 2))
    dm_img_inter = '{"ds":[],"wh":[0,0,0],"of":[0,0,0]}'

我这样测试3天了都正常

std-microblock commented 8 months ago

啊..那难道是inter随机反而不行

GannicusLiu commented 8 months ago
    dm_rand = 'ABCDEFGHIJK'
    dm_img_list = '[]'
    dm_img_str = ''.join(random.sample(dm_rand, 2))
    dm_cover_img_str = ''.join(random.sample(dm_rand, 2))
    dm_img_inter = '{"ds":[],"wh":[0,0,0],"of":[0,0,0]}'

我这样测试3天了都正常

带cookie了吗

iiicebearrr commented 8 months ago

dm_rand = 'ABCDEFGHIJK' dm_img_list = '[]' dm_img_str = ''.join(random.sample(dm_rand, 2)) dm_cover_img_str = ''.join(random.sample(dm_rand, 2)) dm_img_inter = '{"ds":[],"wh":[0,0,0],"of":[0,0,0]}'

2024-01-31 09:56:40 DEBUG bilibili ==> [GET] https://api.bilibili.com/x/space/wbi/arc/search with kwargs: {'params': 'mid=496504596&ps=30&tid=0&pn=1&keyword=&order=pubdate&platform=web&web_location=1550101&order_avoided=true&dm_img_list=[]&dm_img_str=FK&dm_cover_img_str=FH&dm_img_inter={"ds":[],"wh":[0,0,0],"of":[0,0,0]}&w_rid=ea2753131954dd89af69a6295b4de657&wts=1706666201', 'cookies': {}, 'proxies': {}, 'headers': {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://space.bilibili.com/496504596/video'}}

尝试了下貌似不行,cookies空的

My-Responsitories commented 8 months ago

2024-01-31 09:56:40 DEBUG bilibili ==> [GET] api.bilibili.com/x/space/wbi/arc/search with kwargs: {'params': 'mid=496504596&ps=30&tid=0&pn=1&keyword=&order=pubdate&platform=web&web_location=1550101&order_avoided=true&dm_img_list=[]&dm_img_str=FK&dm_cover_img_str=FH&dm_img_inter={"ds":[],"wh":[0,0,0],"of":[0,0,0]}&w_rid=ea2753131954dd89af69a6295b4de657&wts=1706666201', 'cookies': {}, 'proxies': {}, 'headers': {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://space.bilibili.com/496504596/video'}}

尝试了下貌似不行,cookies空的

你的w_rid不正确, 应为e42ec0cb127e7497b8e8232ab4290a1c

iiicebearrr commented 8 months ago

2024-01-31 09:56:40 DEBUG bilibili ==> [GET] api.bilibili.com/x/space/wbi/arc/search with kwargs: {'params': 'mid=496504596&ps=30&tid=0&pn=1&keyword=&order=pubdate&platform=web&web_location=1550101&order_avoided=true&dm_img_list=[]&dm_img_str=FK&dm_cover_img_str=FH&dm_img_inter={"ds":[],"wh":[0,0,0],"of":[0,0,0]}&w_rid=ea2753131954dd89af69a6295b4de657&wts=1706666201', 'cookies': {}, 'proxies': {}, 'headers': {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'referer': 'https://space.bilibili.com/496504596/video'}} 尝试了下貌似不行,cookies空的

你的w_rid不正确, 应为e42ec0cb127e7497b8e8232ab4290a1c

emm, 按道理不应该呀,wrid是我debugger里面扣出来的,按照里面的传参拼接的字符串,我再扣一次看看

My-Responsitories commented 8 months ago

cc1bc5f1a148ad792cbdda79338e6400 吧

你多了("new", "1".into()), 加上这个后确实是cc1bc5f1a148ad792cbdda79338e6400

lovegaoshi commented 8 months ago
    dm_rand = 'ABCDEFGHIJK'
    dm_img_list = '[]'
    dm_img_str = ''.join(random.sample(dm_rand, 2))
    dm_cover_img_str = ''.join(random.sample(dm_rand, 2))
    dm_img_inter = '{"ds":[],"wh":[0,0,0],"of":[0,0,0]}'

我这样测试3天了都正常

感谢兄弟 好使 js: https://github.com/lovegaoshi/azusa-player-mobile/pull/286/files#diff-66515e66b3c8491b5602fea100701a381a25afdb185fe51acc630b18f7fcf1b6R119

cxw620 commented 8 months ago

我已经搞定了,可测试,需要+扣2722204630 一个红包就行

Here's BAC, an open-source project and your behavior is really dishonorable...

This comment should be hide and mark as abuse.

z0z0r4 commented 8 months ago

我已经搞定了,可测试,需要+扣2722204630 一个红包就行

拒绝利益相关内容,一律视为诈骗