MediaCrawler 常见问题排查手册:Node 环境、滑块风控、CDP 连接与配置速查
本文基于 MediaCrawler 仓库的《常见程序运行出错问题》文档整理扩展,覆盖抖音/知乎签名报错、小红书滑块验证失效、关键词与指定帖子爬取、账号切换、Playwright 超时、词云图配置以及 CDP 浏览器连接失败等高频运行问题。读完后你可以对照报错信息快速定位原因,并掌握每一项配置在源码中的真实作用位置,独立完成排障。
缺少 Node.js 环境导致的签名报错
典型报错
execjs._exceptions.ProgramError: SyntaxError: 缺少 ';'
或:
execjs._exceptions.ProgramError: TypeError: Cannot read property 'JS_MD5_NO_COMMON_JS' of null
原因与解决
这两类报错都指向同一个根因:运行环境缺少 Node.js。MediaCrawler 爬取抖音和知乎时,需要通过 Node 引擎在本地执行签名算法脚本,缺少 Node 环境时 execjs 编译 JS 文件就会抛出上述 ProgramError。
从源码可以确认这一依赖关系:
- media_platform/douyin/help.py 第 37 行通过
execjs.compile(open('libs/douyin.js', encoding='utf-8-sig').read())加载 libs/douyin.js 完成抖音请求签名; - media_platform/zhihu/help.py 第 50-51 行以同样方式编译 libs/zhihu.js;
- 小红书平台的 media_platform/xhs/xhs_sign.py 同样依赖 execjs 执行 JS 签名代码。
因此解决方案是安装 Node.js,版本要求大于等于 v16。Windows 用户可从 Node.js 官网下载 Windows 64-bit Installer 安装,一路下一步即可。README 中的安装说明也明确指出:如果是爬取抖音和知乎,需要提前安装 nodejs 环境,版本大于等于 16。
注意:该问题仅影响需要本地 JS 签名的平台(抖音、知乎、小红书等),如果报错信息中出现
execjs._exceptions.ProgramError字样,基本可以确定是 Node 环境问题,而不是 Cookie 或网络问题。
小红书登录滑块验证一直不通过
现象
小红书扫码登录成功后,浏览器持续弹出滑块验证、无法通过,导致登录卡死。
处理建议
小红书平台的风控较为严格,官方文档给出的核心建议是:优先使用 CDP 模式连接自己的真实浏览器(这也是当前版本的默认配置),不要使用无痕浏览器或标准 Playwright 模式。原理在于:连接真实浏览器可以复用已有的 Cookie、登录状态和浏览历史,浏览器指纹更真实,平台难以将其与真实用户行为区分开,从而显著降低触发滑块的概率。
当前 config/base_config.py 的默认配置即为该推荐方案:
# 是否启用 CDP 模式 - 使用用户本地的 Chrome/Edge 浏览器进行爬取,具有更好的反检测能力
ENABLE_CDP_MODE = True
# 是否连接用户已打开的浏览器,而不是启动新的浏览器
CDP_CONNECT_EXISTING = True
如果已经使用 CDP 模式仍出现滑块问题,可以尝试删除项目目录下的 browser_data 文件夹,重新走一遍登录流程,让浏览器数据目录以全新状态重建。
从源码结构看,各平台爬虫在启动浏览器上下文时都会把用户数据目录落在 browser_data 下的平台子目录中,例如 media_platform/xhs/core.py 第 426-428 行:
user_data_dir = os.path.join(os.getcwd(), "browser_data", config.USER_DATA_DIR % config.PLATFORM)
其中 USER_DATA_DIR 的默认值为 "%s_user_data_dir"(config/base_config.py 第 96 行),%s 会被替换为平台名,如 xhs_user_data_dir。也就是说,删除 browser_data/ 目录后,登录态缓存会被一并清除,下次登录相当于全新账号会话——这既适用于"滑块修不好"的场景,也适用于"想换账号"的场景(见下文)。
扫码登录后如何手动通过滑块验证
如果扫码后仍需人工介入通过验证码,官方文档给出的做法是:打开 config/base_config.py 文件,找到 HEADLESS 配置项,将其设置为 False,然后重启项目,在弹出的浏览器窗口中手动完成滑块验证即可。
# 当前仓库默认值即为 False(第 50 行)
HEADLESS = False
该配置的源码注释也说明了适用场景:如果小红书一直扫码登录失败,就打开浏览器手动通过滑块验证码;如果抖音扫码后提示失败,打开浏览器查看是否出现手机号验证环节,手动走完即可。当前版本默认就是 False,一般无需额外修改,只需确认没有被改成 True 即可。
如何指定关键词爬取
可以指定关键词。config/base_config.py 中的 KEYWORDS 参数用于控制需要爬取的关键词,多个关键词之间用英文逗号分隔:
KEYWORDS = "编程副业,编程兼职" # Keyword search configuration, separated by English commas
同时需配合 CRAWLER_TYPE = "search"(关键词搜索模式)使用,搜索到的帖子数量由 CRAWLER_MAX_NOTES_COUNT(默认 15 条)控制。
如何指定帖子(或作者)爬取
可以指定具体帖子。官方文档提到 XHS_SPECIFIED_ID_LIST 参数用于控制需要爬取的帖子 ID 列表;结合当前仓库源码可以看到各平台在 config/ 目录下都有对应的"指定列表"配置:
- 小红书:config/xhs_config.py 中为
XHS_SPECIFIED_NOTE_URL_LIST(笔记 URL 列表,必须携带xsec_token参数)与XHS_CREATOR_ID_LIST(作者主页 URL 列表,需携带xsec_token和xsec_source参数); - 其他平台:
BILI_SPECIFIED_ID_LIST(config/bilibili_config.py)、DY_SPECIFIED_ID_LIST(config/dy_config.py)、WEIBO_SPECIFIED_ID_LIST、KS_SPECIFIED_ID_LIST、TIEBA_SPECIFIED_ID_LIST、ZHIHU_SPECIFIED_ID_LIST等。
这些配置也可以在运行时通过命令行参数 --id 覆盖。从 cmd_arg/arg.py 第 372-386 行可以看到,解析器会把 --id 传入的值按平台赋给对应的 *_SPECIFIED_ID_LIST 配置项,例如:
config.XHS_SPECIFIED_NOTE_URL_LIST = specified_id_list # xhs
config.BILI_SPECIFIED_ID_LIST = specified_id_list # bili
config.DY_SPECIFIED_ID_LIST = specified_id_list # dy
同时配合 CRAWLER_TYPE = "detail"(指定帖子模式)或 "creator"(创作者主页模式)使用。
爬取过一段时间后失效(疑似风控)
如果一开始能正常爬取数据、过一段时间就失效(接口返回异常、要求重新登录等),多半是账号触发了平台风控机制。
官方文档对此有明确警示:请勿大规模对平台进行爬虫,避免影响平台运营。可以从以下角度降低风控概率:
- 保持默认的 CDP 模式 + 连接真实浏览器配置(
ENABLE_CDP_MODE = True、CDP_CONNECT_EXISTING = True); - 合理控制请求频率,
CRAWLER_MAX_SLEEP_SEC(默认 2 秒)控制爬取间隔,MAX_CONCURRENCY_NUM(默认 1)控制并发数,不要盲目调高; - 控制单次爬取规模,
CRAWLER_MAX_NOTES_COUNT控制帖子数量; - 出现风控后先停一段时间再试,或按上文方法清理
browser_data目录后重新登录。
如何更换登录账号
直接删除项目根目录下的 browser_data/ 文件夹即可。该目录保存了 Playwright 的浏览器用户数据(Cookie、登录态等,各平台分别存放在 browser_data/{平台}_user_data_dir 子目录中),删除后重新运行登录流程即可用新账号扫码登录。
官方 FAQ 原文写作
brower_data,但源码中实际使用的目录名是browser_data(见 media_platform/xhs/core.py 第 426 行等各处os.path.join(os.getcwd(), "browser_data", ...)),删除时以实际存在的目录名为准。
Playwright 超时问题
典型报错:
playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
官方文档给出的排查方向:出现这种情况先检查网络环境——如果目标平台(如小红书、知乎的接口)在当前网络下无法正常访问,Playwright 页面加载就会一直等待直至 30 秒超时。确保浏览器可以正常访问目标站点后重试;使用代理的用户还需确认代理对浏览器流量同样生效(MediaCrawler 的代理配置见 config/base_config.py 中 ENABLE_IP_PROXY、IP_PROXY_PROVIDER_NAME 等参数,相关说明见 docs/代理使用.md)。
词云图生成与自定义词
开启词云图
打开 config/base_config.py,将以下两个配置项都设为 True:
# 是否启用生成评论词云
ENABLE_GET_WORDCLOUD = False # 改为 True
# 是否启用评论爬取模式(词云数据来源于评论,需一并开启)
ENABLE_GET_COMMENTS = True
相关配套参数(当前仓库默认值):
# 禁用词文件路径
STOP_WORDS_FILE = "./docs/hit_stopwords.txt"
# 中文字体文件路径(词云渲染用)
FONT_PATH = "./docs/STZHONGS.TTF"
更完整的说明可参考 docs/词云图使用配置.md。
添加禁用词与自定义词组
- 禁用词:编辑 docs/hit_stopwords.txt,每行输入一个词语即可;
- 自定义词组:在 config/base_config.py 中找到
CUSTOM_WORDS字典,按"短语": "分组名"的格式添加,例如:
CUSTOM_WORDS = {
"零几": "年份", # 将"零几"识别为一个整体
"高频词": "专业术语", # 示例自定义词
}
CDP 连接已有浏览器相关问题
报错 Cannot connect to existing browser on port 9222
从 tools/cdp_browser.py 第 178-185 行可以看到,该报错由 _connect_existing_browser 在等待超时后抛出。源码中等待循环的超时时长取自 BROWSER_LAUNCH_TIMEOUT(默认 60 秒),期间每秒探测一次 CDP 端口。请逐项检查:
- 确保 Chrome 浏览器已经打开并正在运行;
- 在 Chrome 地址栏输入
chrome://inspect/#remote-debugging,确保已勾选 "Allow remote debugging for this browser instance"; - 页面上应显示
Server running at: 127.0.0.1:9222,如果没有显示说明远程调试未成功开启; - 确保 Chrome 版本 ≥ 144,低版本不支持此功能,可在地址栏输入
chrome://version查看版本号; - 确认 config/base_config.py 中
CDP_DEBUG_PORT = 9222与浏览器实际调试端口一致,端口冲突时可改为其他值。
连接时浏览器弹出确认对话框怎么办
这是正常行为。Chrome 连接已有浏览器时会弹出确认对话框,点击"接受"即可。程序会等待用户确认,默认超时时间为 60 秒(即 BROWSER_LAUNCH_TIMEOUT),在此期间完成确认即可建立连接。从 tools/cdp_browser.py 第 324 行的日志提示也可以印证:Please check your browser for a confirmation dialog and accept it。
不想连接已有浏览器,让程序自动启动新浏览器
在 config/base_config.py 中设置:
CDP_CONNECT_EXISTING = False
程序会自动检测系统安装的 Chrome/Edge 并启动一个新的浏览器实例(检测失败时可通过 CUSTOM_BROWSER_PATH 手动指定路径)。
为什么推荐连接已有浏览器
连接已有浏览器可以直接复用浏览器中真实的 Cookie、登录状态、扩展插件和浏览历史,平台很难区分这是自动化操作还是真实用户行为,大幅降低被平台风控检测的风险;而启动新浏览器是一个"干净"环境,更容易被平台识别为爬虫。这一结论与 docs/CDP模式使用指南.md 中的配置说明一致:ENABLE_CDP_MODE、CDP_CONNECT_EXISTING、CDP_DEBUG_PORT、CDP_HEADLESS、AUTO_CLOSE_BROWSER、CUSTOM_BROWSER_PATH、BROWSER_LAUNCH_TIMEOUT 是 CDP 模式的全部核心配置项,完整用法可参考该指南文档。
小结
| 问题 | 关键配置 / 操作 | 依据位置 |
|---|---|---|
| 抖音/知乎 execjs 签名报错 | 安装 Node.js ≥ v16 | media_platform/douyin/help.py、media_platform/zhihu/help.py |
| 小红书滑块验证卡死 | 使用 CDP 模式连接真实浏览器;必要时删除 browser_data/ 重登 |
config/base_config.py、media_platform/xhs/core.py |
| 需手动过验证码 | HEADLESS = False 后重启项目 |
config/base_config.py |
| 指定关键词 | KEYWORDS(英文逗号分隔) |
config/base_config.py |
| 指定帖子/作者 | 各平台 *_SPECIFIED_ID_LIST / XHS_SPECIFIED_NOTE_URL_LIST,或 --id 参数 |
config/xhs_config.py、cmd_arg/arg.py |
| 爬取中途失效 | 控制频率与规模,优先 CDP 模式 | config/base_config.py |
| 更换账号 | 删除根目录 browser_data/ 文件夹 |
各平台 core.py 中 user_data_dir 拼接逻辑 |
| Playwright 30s 超时 | 检查网络/代理是否可访问目标站点 | — |
| 词云图 | ENABLE_GET_WORDCLOUD + ENABLE_GET_COMMENTS 均设为 True |
config/base_config.py |
| CDP 无法连接 9222 端口 | 开启远程调试、Chrome ≥ 144、确认弹窗 | tools/cdp_browser.py、docs/CDP模式使用指南.md |
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00