Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[漏洞] get_videos()获得-352返回值 #691

Closed
lb-chc opened this issue Feb 23, 2024 · 27 comments
Closed

[漏洞] get_videos()获得-352返回值 #691

lb-chc opened this issue Feb 23, 2024 · 27 comments
Labels
anti-spider 反爬相关 bug 漏洞

Comments

@lb-chc
Copy link

lb-chc commented Feb 23, 2024

import asyncio
from bilibili_api import user

async def main() -> None:
    # 实例化 User 类
    v = user.User(uid="69496358")
    # 获取信息
    info = await v.get_videos()
    # 打印信息
    print(info)

if __name__ == "__main__":
    asyncio.run(main())

运行如上代码出现了如下错误

 File "C:\Users\Win10\Nextcloud\PC3\My\BiliBili_WebSpider\Project\BiliBili_WebSpider_Processing 3\例子和试验\bilibili-api 库测试.py", line 3, in <module>
    from bilibili_api import proxy
ImportError: cannot import name 'proxy' from 'bilibili_api' (C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\site-packages\bilibili_api\__init__.py)

C:\Windows\System32>python "C:\Users\bilibili-api 库测试.py"
Traceback (most recent call last):
  File "C:\Users\bilibili-api 库测试.py", line 13, in <module>
    asyncio.run(main())
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 646, in run_until_complete
    return future.result()
  File "C:\Users\bilibili-api 库测试.py", line 8, in main
    info = await v.get_videos()
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\site-packages\bilibili_api\user.py", line 483, in get_videos
    await Api(**api, credential=self.credential).update_params(**params).result
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\site-packages\bilibili_api\utils\network.py", line 273, in result
    self.__result = await self.request()
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\site-packages\bilibili_api\utils\network.py", line 173, in inner
    return await func(*args, **kwargs)
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\site-packages\bilibili_api\utils\network.py", line 558, in request
    real_data = self._process_response(
  File "C:\Users\Win10\AppData\Local\Programs\Python\Python310\lib\site-packages\bilibili_api\utils\network.py", line 603, in _process_response
    raise ResponseCodeException(code, msg, resp_data)
bilibili_api.exceptions.ResponseCodeException.ResponseCodeException: 接口返回错误代码:-352,信息:风控校验失败。
{'code': -352, 'message': '风控校验失败', 'ttl': 1, 'data': {'v_voucher': 'voucher_508f6n1e-2p8d-4a3f-b14f-b181cse52dad'}}
@lb-chc lb-chc added the bug 漏洞 label Feb 23, 2024
@lb-chc lb-chc changed the title [漏洞] {这里填写标题} [漏洞] {get_videos获得-352返回值} Feb 23, 2024
@lb-chc lb-chc changed the title [漏洞] {get_videos获得-352返回值} [漏洞] get_videos()获得-352返回值 Feb 23, 2024
@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 23, 2024

#680

@lb-chc
Copy link
Author

lb-chc commented Feb 25, 2024

#680

使用最新的dev分支后,buvid确实可以成功激活,但get_videos()依然获得-352返回值,要不要把buvid4、b_nut、b_lsid、_uuid、buvid_fp作为cookie也传进去?在你的框架里我不知道怎么改出这个来......

PS:你有在api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi遇到过{"code":130212,"message":"130212","ttl":1,"data":null} 返回值吗

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 25, 2024

#680

使用最新的dev分支后,buvid确实可以成功激活,但get_videos()依然获得-352返回值,要不要把buvid4、b_nut、b_lsid、_uuid、buvid_fp作为cookie也传进去?在你的框架里我不知道怎么改出这个来......

PS:你有在api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi遇到过{"code":130212,"message":"130212","ttl":1,"data":null} 返回值吗

并没有遇到过,不过我也没激活过几次,最近就测试下而已...

dev 分支 credential 已经支持自定义 Cookie 了 #692 ,直接 Credential(buvid4="")

@lb-chc
Copy link
Author

lb-chc commented Feb 25, 2024

dev 分支 credential 已经支持自定义 Cookie 了 #692 ,直接 Credential(buvid4="")

辛苦

虽然不是在这个项目测试的,但由你代码激活的cookie可以成功用于动态请求

PS:看到你激活buvid时发的指纹连uuid和ua都写固定值,网址都不改就能通过还能请求动态的时候我都惊了

@Nemo2011
Copy link
Owner

#680

使用最新的dev分支后,buvid确实可以成功激活,但get_videos()依然获得-352返回值,要不要把buvid4、b_nut、b_lsid、_uuid、buvid_fp作为cookie也传进去?在你的框架里我不知道怎么改出这个来......

PS:你有在api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi遇到过{"code":130212,"message":"130212","ttl":1,"data":null} 返回值吗

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 26, 2024

#680

使用最新的dev分支后,buvid确实可以成功激活,但get_videos()依然获得-352返回值,要不要把buvid4、b_nut、b_lsid、_uuid、buvid_fp作为cookie也传进去?在你的框架里我不知道怎么改出这个来......
PS:你有在api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi遇到过{"code":130212,"message":"130212","ttl":1,"data":null} 返回值吗

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

那个给 dm 参数的 pr 我不知道过不过...随机能用?你看看改改?BAC 那边看不懂说法

@lb-chc
Copy link
Author

lb-chc commented Feb 27, 2024

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

如果我想让get_videos()的请求携带自定义cookie,你觉得我应该从哪里入手?我想试试自己攒一下

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 27, 2024

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

如果我想让get_videos()的请求携带自定义cookie,你觉得我应该从哪里入手?我想试试自己攒一下

dev 分支 credential 已经支持自定义 Cookie 了 #692 ,直接 Credential(buvid4="")

@lb-chc
Copy link
Author

lb-chc commented Feb 27, 2024

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

如果我想让get_videos()的请求携带自定义cookie,你觉得我应该从哪里入手?我想试试自己攒一下

dev 分支 credential 已经支持自定义 Cookie 了 #692 ,直接 Credential(buvid4="")

不是,我想问这个项目中自定义cookie涉及哪些关键部分......

@lb-chc
Copy link
Author

lb-chc commented Feb 27, 2024

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

如果我想让get_videos()的请求携带自定义cookie,你觉得我应该从哪里入手?我想试试自己攒一下

dev 分支 credential 已经支持自定义 Cookie 了 #692 ,直接 Credential(buvid4="")

哦天那,成了!join(random.sample(dm_rand, 2))是可运行的,现有固定值会遭遇-352。我认为你应该合并这个请求

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 27, 2024

get_videos 只靠激活的 buvid3 是不行的,buvid3 激活仅能直接解决用户动态获取问题,获取视频看 https://github.com/Nemo2011/bilibili-api/issues/595#issuecomment-1859074892,那些 dm_xxx 参数目前没加。

如果我想让get_videos()的请求携带自定义cookie,你觉得我应该从哪里入手?我想试试自己攒一下

dev 分支 credential 已经支持自定义 Cookie 了 #692 ,直接 Credential(buvid4="")

哦天那,成了!join(random.sample(dm_rand, 2))是可运行的,现有固定值会遭遇-352。我认为你应该合并这个请求

现在 -352 是有新参数 dm_img_inter

@lb-chc
Copy link
Author

lb-chc commented Feb 27, 2024

现在 -352 是有新参数 dm_img_inter

简而言之就是这个提交的每个修改都是有必要的,不做这些修改这个接口就不起作用,所以我觉得应该合并这个提交

还有个问题,是不是所有json返回值被我拿到后都会删减了这一段:

{
    "code": 0,
    "message": "0",
    "ttl": 1,
    "data": {
    }
}

仅保留了data内的结构

有办法让我拿到的返回值包括这一段,成为原始的返回值吗?

@lb-chc lb-chc closed this as completed Feb 27, 2024
@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 28, 2024

现在 -352 是有新参数 dm_img_inter

简而言之就是这个提交的每个修改都是有必要的,不做这些修改这个接口就不起作用,所以我觉得应该合并这个提交

还有个问题,是不是所有json返回值被我拿到后都会删减了这一段:

{
    "code": 0,
    "message": "0",
    "ttl": 1,
    "data": {
    }
}

仅保留了data内的结构

有办法让我拿到的返回值包括这一段,成为原始的返回值吗?

有,你给每个 Api 的调用都加上 raw=True,或者把 network 里面的 raw 默认值改成 False,下次我看看整个 dev 模式...?

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Feb 28, 2024

那个pr我不会合并的...迟早随机数会报风控,但我没空去扒拉最新的,可以来个人提个新的

@lb-chc
Copy link
Author

lb-chc commented Feb 29, 2024

有,你给每个 Api 的调用都加上 raw=True,或者把 network 里面的 raw 默认值改成 False,下次我看看整个 dev 模式...?

如果要做 dev 模式的话,或许需要让程序不再因为服务器响应和json返回值失败而报错崩溃,直接返回服务器的http响应或json/编码的二进制数据(弹幕)(不过弹幕解码还是py方便,解码成json再返回吧......)

@lb-chc
Copy link
Author

lb-chc commented Feb 29, 2024

那个pr我不会合并的...迟早随机数会报风控,但我没空去扒拉最新的,可以来个人提个新的

dm_img_list是用户操作事件特征,dm_img_inter 是浏览器渲染元素间的关系特征,两者的高度模拟可能只能在浏览器环境中完成,dm_img_inter 可以说必须在当时更新的b站对应页面完成,未来或许需要在使用前弹出浏览器窗口让用户进行真实操作来填充库的指纹池?但要小心真实b站页面把指纹上传过,以至于产生的指纹失效?

dm_img_listdm_img_inter 可以通过网页本身进行模拟,如下代码可以生成base32编码前的明文内容,从控制台便利的查看

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>dm_img_list dm_img_inter</title>
</head>
<body>
  <script>
    console.log("----------------------1");
    

    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` 的值。
     */
    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` 的值。
     */
    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),
    });
    }

    //-----------------------------------------------
    //运行测试
    function updateOnResize() {//窗口更新时调用
      // 为了演示目的,假设有一些模拟的事件和元素数据
      const mockEvents = [
        { x: 10, y: 20, timeStamp: 12345, type: "mousemove" },
        { x: 30, y: 40, timeStamp: 67890, type: "click" }
      ];

      const mockWindowBounds = { width: 800, height: 600, x: 100, y: 50 };

      const mockElements = [
        { tagName: "div", className: "example-class", getBoundingClientRect: () => ({ x: 50, y: 60, width: 200, height: 150 }) },
        { tagName: "span", className: "another-class", getBoundingClientRect: () => ({ x: 80, y: 120, width: 100, height: 80 }) }
      ];

      // 调用函数并打印最终输出
      const dmImgList = getDmImgList(mockEvents);
      console.log("dm_img_list:", dmImgList);

      const dmImgInter = getDmImgInter(mockWindowBounds, mockElements);
      console.log("dm_img_inter:", dmImgInter);
    }

    // 在窗口大小改变时调用
    window.addEventListener('resize', updateOnResize);

      // 初始化调用一次
      updateOnResize();
    
  </script>
</body>
</html>

但还好,需要完全合法指纹的一天还没有到来

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Mar 1, 2024

有,你给每个 Api 的调用都加上 raw=True,或者把 network 里面的 raw 默认值改成 False,下次我看看整个 dev 模式...?

如果要做 dev 模式的话,或许需要让程序不再因为服务器响应和json返回值失败而报错崩溃,直接返回服务器的http响应或json/编码的二进制数据(弹幕)(不过弹幕解码还是py方便,解码成json再返回吧......)

有这种需求自己打断点就好了,说真的不打算深入,凑合

@lb-chc
Copy link
Author

lb-chc commented Mar 4, 2024

那个pr我不会合并的...迟早随机数会报风控,但我没空去扒拉最新的,可以来个人提个新的

"迟早随机数会报风控"......
但保留固定值也迟早,其实是已经报风控了啊

如果喜欢原理正确可以在注释写好正当的实现思路以供后人参考,但爬虫不就是短时间反复对抗的过程吗?在已知短时间内无法完成原理正确的代码的同时,顶着功能不能用的现状将已经无法使用的优雅代码保留在为实用目标编写的代码库里到底有什么好处呢?

@lb-chc lb-chc reopened this Mar 4, 2024
@z0z0r4
Copy link
Collaborator

z0z0r4 commented Mar 5, 2024

那个pr我不会合并的...迟早随机数会报风控,但我没空去扒拉最新的,可以来个人提个新的

"迟早随机数会报风控"...... 但保留固定值也迟早,其实是已经报风控了啊

如果喜欢原理正确可以在注释写好正当的实现思路以供后人参考,但爬虫不就是短时间反复对抗的过程吗?在已知短时间内无法完成原理正确的代码的同时,顶着功能不能用的现状将已经无法使用的优雅代码保留在为实用目标编写的代码库里到底有什么好处呢?

不置评价,除非你打算持续更进这个风控继续修,那我非常认同

至少 bac 那边整理一份稳定可用的之前我不会动,我这边开学了,没空继续更进

@lb-chc
Copy link
Author

lb-chc commented Apr 1, 2024

不置评价,除非你打算持续更进这个风控继续修,那我非常认同

至少 bac 那边整理一份稳定可用的之前我不会动,我这边开学了,没空继续更进

目前我的项目依赖于本项目的buvid激活实现,也依赖本项目的get_videos,所以get_videos再出问题的话我会先尝试修复get_videos,直到难度让我考虑其他方法或者放弃使用这个API。因此只要我还使用本项目,我可以保证我的能跑这里也能跑,这样行吗

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Apr 2, 2024

不置评价,除非你打算持续更进这个风控继续修,那我非常认同
至少 bac 那边整理一份稳定可用的之前我不会动,我这边开学了,没空继续更进

目前我的项目依赖于本项目的buvid激活实现,也依赖本项目的get_videos,所以get_videos再出问题的话我会先尝试修复get_videos,直到难度让我考虑其他方法或者放弃使用这个API。因此只要我还使用本项目,我可以保证我的能跑这里也能跑,这样行吗

当前该 pr 能成功运行吗?以及 #699 (comment)

#680

@lb-chc
Copy link
Author

lb-chc commented Apr 4, 2024

当前该 pr 能成功运行吗?以及 #699 (comment)

#680

我做了测试,截至当前DEV分支合并 #680 后运行get_videos即可顺利得到数据返回,无需考虑#699 (comment)

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Apr 4, 2024

当前该 pr 能成功运行吗?以及 #699 (comment)
#680

我做了测试,截至当前DEV分支合并 #680 后运行get_videos即可顺利得到数据返回,无需考虑#699 (comment)

那这是啥 #699 (comment) 前言不搭后语?

还真是,只要一直填写true就行

@lb-chc
Copy link
Author

lb-chc commented Apr 5, 2024

那这是啥 #699 (comment) 前言不搭后语?

还真是,只要一直填写true就行

那时我查了我自己项目的等效函数实现和web端的API实现,确实有order_avoided=true一项,并且取值恒为true,因此这是值得加入API请求使之更接近真实请求的提议,但这不是风控指标,因为首先我项目的等效函数实现在buvid激活上线后再没跑通过,直接取本项目激活的buvid也不行

其次我在昨晚下载了当前最新DEV分支ZIP包,手工合并 #680 中的有效代码,并测试了get_videos,得到了预期的数据返回,因此才得出了截至当前DEV分支合并 #680 后运行get_videos即可顺利得到数据返回这个观点

我使用本项目DEV分支几个月前的版本以同样方法手工合并 #680 中的有效代码后,一直顺利使用get_videos至今,日间每两秒一次请求的海外IP封禁发生在500-1000次附近

@z0z0r4
Copy link
Collaborator

z0z0r4 commented Apr 5, 2024

那这是啥 #699 (comment) 前言不搭后语?

还真是,只要一直填写true就行

那时我查了我自己项目的等效函数实现和web端的API实现,确实有order_avoided=true一项,并且取值恒为true,因此这是值得加入API请求使之更接近真实请求的提议,但这不是风控指标,因为首先我项目的等效函数实现在buvid激活上线后再没跑通过,直接取本项目激活的buvid也不行

其次我在昨晚下载了当前最新DEV分支ZIP包,手工合并 #680 中的有效代码,并测试了get_videos,得到了预期的数据返回,因此才得出了截至当前DEV分支合并 #680 后运行get_videos即可顺利得到数据返回这个观点

我使用本项目DEV分支几个月前的版本以同样方法手工合并 #680 中的有效代码后,一直顺利使用get_videos至今,日间每两秒一次请求的海外IP封禁发生在500-1000次附近

4fb2ef3 不予置评...加油

@lb-chc lb-chc closed this as completed Apr 5, 2024
@GaoAO1e
Copy link

GaoAO1e commented Sep 20, 2024

那么现在这个问题解决了吗

@Fmajor
Copy link

Fmajor commented Oct 25, 2024

此问题从20号左右又重新出现了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
anti-spider 反爬相关 bug 漏洞
Projects
None yet
Development

No branches or pull requests

5 participants