saermart / DouyinLiveWebFetcher

抖音直播间网页版的弹幕数据抓取(2024最新版本)
GNU Affero General Public License v3.0
526 stars 158 forks source link

gbk编码问题如何修改 #53

Closed isZonghao closed 2 weeks ago

isZonghao commented 1 month ago

QQ图片20240718175841

看注释中有提示说这么改 python模块subprocess的Popen类的init函数参数encoding值为 "utf-8"

但我对subprocess模块并不熟悉,具体要怎么改呢,大佬请赐教

saermart commented 1 month ago

就是修改它的源码,你可以找到 Python 的 subprocess.py 文件进行修改

saermart commented 1 month ago

点击报错信息里面那个文件链接,就可以直接找到(狗头)

SXCSSYLJ commented 1 month ago

}NJTWXK4 (PWONAECAXTN 修改了之后,我这个现在报utf未定义,怎么解决啊,请教一下

isZonghao commented 1 month ago

}NJTWXK4 (PWONAECAXTN 修改了之后,我这个现在报utf未定义,怎么解决啊,请教一下

看报错明显是你把utf-8写错成了utf了吧

isZonghao commented 1 month ago

}NJTWXK4 (PWONAECAXTN 修改了之后,我这个现在报utf未定义,怎么解决啊,请教一下

看报错明显是你把utf-8写错成了utf了吧

SXCSSYLJ commented 1 month ago

E(ZPU12YFL 3V(@R 01P@C 那不至于,现在不知道怎么解决

isZonghao commented 1 month ago

E(ZPU12YFL 3V(@R 01P@C 那不至于,现在不知道怎么解决

你没加双引号啊

isZonghao commented 1 month ago

点击报错信息里面那个文件链接,就可以直接找到(狗头)

大佬 我现在启动不报错了,但是运行起来报WebSocket的错,报完错链接就断了 QQ图片20240718175841

SXCSSYLJ commented 1 month ago

E(ZPU12YFL 3V(@R 01P@C 那不至于,现在不知道怎么解决

你没加双引号啊

好的好的我的解决了,自学的,基础比较弱,感谢感谢【抱拳】

saermart commented 1 month ago

点击报错信息里面那个文件链接,就可以直接找到(狗头)

大佬 我现在启动不报错了,但是运行起来报WebSocket的错,报完错链接就断了 QQ图片20240718175841

nodejs 版本不对吧,应该是 v18.x 的

isZonghao commented 1 month ago

点击报错信息里面那个文件链接,就可以直接找到(狗头)

大佬 我现在启动不报错了,但是运行起来报WebSocket的错,报完错链接就断了 QQ图片20240718175841

nodejs 版本不对吧,应该是 v18.x 的

哇 大佬 一眼就看出问题所在了,换成了18版本 确实可以了

xyl123124 commented 1 month ago

改subprocess.py的源码,可能导致别的东西因为源码问题不能运行,例如pip install

ERROR: Exception:
Traceback (most recent call last):
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\base_command.py", line 179, in exc_logging_wrapper
status = run_func(*args)
^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\req_command.py", line 67, in wrapper
return func(self, options, args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\commands\install.py", line 324, in run
session = self.get_default_session(options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\index_command.py", line 71, in get_default_session
self._session = self.enter_context(self._build_session(options))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\index_command.py", line 100, in _build_session
session = PipSession(
^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\network\session.py", line 344, in init
self.headers["User-Agent"] = user_agent()
^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\network\session.py", line 190, in user_agent
if rustc_output.startswith(b"rustc "):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: startswith first arg must be str or a tuple of str, not bytes
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in run_code
File "D:\soft\python3.11.4\Scripts\pip.exe_main.py", line 7, in <module>
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\main.py", line 80, in main
return command.main(cmd_args)
^^^^^^^^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\base_command.py", line 100, in main
return self._main(args)
^^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\base_command.py", line 234, in _main
self.handle_pip_version_check(options)
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\index_command.py", line 161, in handle_pip_version_check
session = self._build_session(
^^^^^^^^^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\cli\index_command.py", line 100, in _build_session
session = PipSession(
^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\network\session.py", line 344, in init
self.headers["User-Agent"] = user_agent()
^^^^^^^^^^^^
File "D:\soft\python3.11.4\Lib\site-packages\pip_internal\network\session.py", line 190, in user_agent
if rustc_output.startswith(b"rustc "):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: startswith first arg must be str or a tuple of str, not bytes

你的情况是需要在一个特定的函数中设置 encoding='utf-8' 来解决编码问题,但修改全局的 subprocess 模块会导致其他问题。可以尝试通过局部解决方案来避免修改全局模块。

一个推荐的办法是利用 contextlibpatch 方法来临时修改 subprocess.Popen 的行为。这样可以在你需要的地方修改编码,而不影响全局环境。

下面是一个解决方案:

  1. 创建一个上下文管理器,临时修改 subprocess.Popen 的行为:
import subprocess
from contextlib import contextmanager
from unittest.mock import patch

@contextmanager
def patched_popen_encoding(encoding='utf-8'):
    original_popen_init = subprocess.Popen.__init__

    def new_popen_init(self, *args, **kwargs):
        kwargs['encoding'] = encoding
        original_popen_init(self, *args, **kwargs)

    with patch.object(subprocess.Popen, '__init__', new_popen_init):
        yield

# Example usage within the context manager
def generateSignature(wss, script_file='sign.js'):
    params = ("live_id,aid,version_code,webcast_sdk_version,"
              "room_id,sub_room_id,sub_channel_id,did_rule,"
              "user_unique_id,device_platform,device_type,ac,"
              "identity").split(',')
    wss_params = urlparse(wss).query.split('&')
    wss_maps = {i.split('=')[0]: i.split("=")[-1] for i in wss_params}
    tpl_params = [f"{i}={wss_maps.get(i, '')}" for i in params]
    param = ','.join(tpl_params)
    md5 = hashlib.md5()
    md5.update(param.encode())
    md5_param = md5.hexdigest()

    with codecs.open(script_file, 'r', encoding='utf-8') as f:
        script = f.read()

    context = execjs.compile(script)
    with patched_popen_encoding(encoding='utf-8'):
        ret = context.call('getSign', {'X-MS-STUB': md5_param})
    return ret.get('X-Bogus')

在这个例子中,patched_popen_encoding 是一个上下文管理器,它临时修改了 subprocess.Popen__init__ 方法,使其默认使用 utf-8 编码。这样,你可以在需要的地方使用这个上下文管理器,而不需要修改全局的 subprocess 模块。

  1. 使用上下文管理器 运行你的函数:
# 调用generateSignature函数
wss = 'your_wss_string_here'
result = generateSignature(wss)
print(result)

通过这种方法,你可以在特定的地方临时修改 subprocess 的行为,避免全局修改带来的副作用。这样既能解决你的编码问题,又不会影响 pip 等其他工具的正常运行。