)
项目位置edfhh/xhs_job_crawler一个本地运行的轻量工具从「主页推荐」流里采集博主昵称与简介 并用规则引擎推测其职业。只保留「风控绕过 抓取 职业推断」这条链路其余平台、代理池、 数据库、评论/搜索等功能全部移除。支持两种采集模式默认游客模式免登录模式是否需要登录能拿到的字段主要风险guest默认否昵称 / 小红书号 / 简介 / IP属地实测均可拿到IP 级风控匿名流量更易被拦成「安全限制」页login需要扫码同上走签名接口更稳账号级风控限流、异常登录实测详情见下文「免登录游客模式实测结论」。来源与改造组件来源改造点签名绕过MediaCrawler 的playwright_sign.py/xhs_sign.py只保留对xhshow的封装core/sign.py反指纹 / 登录MediaCrawler 的ENABLE_CDP_MODElibs/stealth.min.jslogin.py精简为持久化上下文 stealth 注入 扫码登录core/browser.py主页抓取MediaCrawler 的client.py/extractor.py只保留GET /user/profile/{uid}__INITIAL_STATE__解析core/xhs_client.py职业预测twitter_profile_predictor原项目面向法语 Twitter 简介这里换成中文词典并对「昵称简介」打分predictor/风控要点为什么这样设计接口签名所有对edith.xiaohongshu.com的请求都由xhshow生成x-s / x-t / x-s-common / x-b3-traceid绕过签名校验。浏览器指纹Playwright 持久化上下文user_data_dir复用登录态注入stealth.min.js启动参数带--disable-blink-featuresAutomationControlled规避navigator.webdriver等检测。行为风控请求间隔在 MediaCrawler 原有基准2s上慢一倍4~8s 随机每 5 个博主长休息 20s。无 IP 池全程本机单 IP靠「慢 复用登录态」降低风险。默认抓 10 人页面输入框可调。目录结构xhs_job_crawler/ ├── app_config.py # 全局配置速率×2、抓取上限、浏览器、Web 端口 ├── run.py # 一键启动起 Web 服务并自动打开页面 ├── core/ │ ├── sign.py # xhshow 签名封装 │ ├── xhs_client.py # 签名请求 主页解析昵称/小红书号/简介 │ ├── browser.py # 反检测浏览器 扫码登录 推荐流作者采集 │ ├── crawler.py # 抓取编排登录→采集→逐个抓主页→预测→限流 │ └── stealth.min.js # 反指纹脚本 ├── predictor/ │ ├── occupation.py # 中文职业预测引擎 │ └── professions_zh.json# 中文职业词典职业/类别/关键词124 个职业 ├── tools/ │ ├── predict_cli.py # 离线测试入口不联网、不用浏览器 │ ├── test_user_cases.py # 真实样例回归无需登录 │ └── web_selftest.sh # Web 接口自测起服务→打四个接口→关服务 ├── data/ │ ├── sample_creators.tsv# 样例数据 │ ├── edge_cases.tsv # 边界/易错样例回归用 │ └── user_cases.tsv # 用户真实样例回归用 └── web/ ├── server.py # FastAPI/api/start /api/stop /api/status /api/demo /api/export └── index.html # 极简页面先离线验证职业预测无需登录 / 无需浏览器只想先验证「职业推断」效果时直接用命令行测试不需要网络、也不需要 Playwright# 1) 内置样例演示 python tools/predict_cli.py # 2) 用你自己的数据每行「昵称|简介」或「昵称TAB简介」 python tools/predict_cli.py 咖啡师小鹿|手冲咖啡 拉花 老周说法|执业12年律师 # 3) 从文件读取 python tools/predict_cli.py -f data/sample_creators.tsv # 4) 从剪贴板/标准输入逐行粘贴Ctrl-D 结束 python tools/predict_cli.py -输出示例昵称 推测职业 类别 置信度 命中依据 阿沁的日常 程序员 IT/互联网 高 开发工程师、前端开发、程序员 [score12.0] Amy在湾区 全职妈妈 家庭/生活 高 全职妈妈、亲子、妈妈 [score8.0] 小甜乖乖 未识别 未知 无 - [score0]命中依据 触发的关键词score 加权得分越长/越具体的词权重越高。 若某条判错直接往predictor/professions_zh.json的对应职业keywords里增删词即可无需改代码。无简介 / 无意义内容怎么处理重要引擎只依据「昵称 简介」里出现的证据词判断没有证据就不猜并给出置信度场景结果置信度简介为空昵称也无关键词如「小甜乖乖」未识别无简介全是套话感谢关注 每天更新且昵称无信息未识别无纯乱码 / 无意义文本如「了改_sleep baccano」未识别无简介为空但昵称含职业词如「小琪影视」按昵称给出如 摄像/剪辑低仅昵称弱信号简介含明确职业词如「分享母婴好物育儿知识」母婴/育儿博主高/中判定规则仅昵称命中 → 一律「低」有简介命中时按 score 分档2 低、5 中、≥5 高。 导出结果里「置信度」「命中依据」两列可让你快速筛掉低可信项、并复核是否误判。免登录游客模式实测结论2024 版 Web结论不登录也能拿到和登录基本一样的资料字段并不少。实测链路与证据用真实浏览器Playwright 持久化上下文打开推荐页并滚动几下让服务端下发acw_tc/websectiga/sec_poison_id/a1/web_session等匿名 Cookie把这套 Cookie 交给requestsGEThttps://www.xiaohongshu.com/user/profile/uid返回174 KB 的完整 SSR HTML不是登录墙里面直接有div classuser-name昵称/divspan classuser-redId小红书号123456789/spanspan classuser-IP IP属地示例省/spandiv classuser-desc简介/div以及window.__INITIAL_STATE__ → userPageData.basicInfo{nickname,redId,desc,ipLocation}实测输出游客、未登录nickname示例博主, red_id123456789, desc还没有简介, ip_location示例省。⚠️关键前提必须先用真实浏览器逛一遍页面再取数。 只用requests裸请求或浏览器只开 4 秒不滚动时同一 URL 只返回36 KB 的剥离页 里面没有「小红书号」——这正是「免登录拿不到小红书号」这种错觉的来源。⚠️风险从「账号」转移到「IP」匿名流量更容易被拦。 实测出现过推荐流采集到昵称安全限制的拦截页。脚本已内置若 HTTP 200 但页面里没有「小红书号」→ 判定疑似风控 →退避 8~15 秒自动重试一次导出的「备注」列会写「疑似被 IP 级风控拦成精简页…」便于识别。因此免登录模式的使用建议单次 ≤ 20界面默认 10跑完隔几分钟再跑不要并发。 若连续多次都是风控页说明当前 IP 已被临时限制停手等半小时或改用登录模式。登录模式扫码排查窗口起来了却跳不过去 / 点不开登录模式用 Playwright 的有头浏览器打开https://www.xiaohongshu.com/explore二维码弹窗是自动出现的扫码即登录等待上限 180 秒二维码过期会自动点「刷新」最多 3 次。若遇到「浏览器窗口起来了但停在空白页 / 无法跳转 / 点不动」按顺序排查不要混用浏览器渠道最常见原因Chrome 与 chromium 的user_data_dir互不兼容。用 chromium 建好的登录态目录再交给 Chrome 打开 Chrome 会拒绝接管症状正是「窗口出来但空白、地址栏不跳转」。 本工具默认只用 Playwright 自带 chromium并按渠道分开存登录态默认data/browser_user_data指定 ChromeXHS_CHANNELchrome→data/browser_user_data_chrome两套登录态互不影响先关掉旧的浏览器窗口若data/browser_user_data*/SingletonLock还在上一个实例没退干净新窗口会空白。 程序启动时会检测并把这条写进界面上的「启动提示」。窗口被压在后台启动时已加--start-maximized且调用bring_to_front()但若被其它窗口完全遮住 看起来仍像「没打开」。切一下窗口即可——程序不依赖你点击二维码弹窗自动出现。网络到不了小红书程序会校验落点是否真的是xiaohongshu.com否则直接报错并提示先用普通浏览器确认网络/代理。看失败原因不要干等失败时界面会显示一行登录失败原因 | 浏览器渠道 | 页面当前URL | 二维码可见True/False | 启动提示...一次性自检约 30 秒不进等待循环DISPLAY:0.0 .venv/bin/python tools/diag_login3.py正常应输出渠道chromium(自带)、页面https://www.xiaohongshu.com/explore、登录弹窗可见: True、二维码已渲染: True。运行本地—— 打开可视化页面实测第 1 步装依赖务必用虚拟环境cd xhs_job_crawler python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt playwright install chromium # 首次需下载浏览器内核直接pip install -r requirements.txt在 Kali/新版 Debian 上会报error: externally-managed-environmentPEP 668这是系统保护机制不是缺包。 建虚拟环境后再装即可也可临时用pip install --break-system-packages但不推荐。第 2 步起服务.venv/bin/python run.py # 或先 source .venv/bin/activate 再 python run.py常见报错python run.py报ModuleNotFoundError: No module named xhshow 原因几乎都是用了系统 Python 而不是项目的.venv依赖装在 venv 里。 换成本节命令即可无需重装依赖。看到* 控制台: http://127.0.0.1:8777/即启动成功浏览器会自动弹出该页面没弹出就手动访问。无图形界面 / 服务器上可加虚拟显示xvfb-run -a python run.py。第 3 步页面操作打开http://127.0.0.1:8777/后先点「演示数据」—— 不需要登录、不联网表格立刻填上 5 条示例 用来确认列顺序昵称 / 小红书号 / 推测职业 / 置信度 / 备注和导出效果是否符合预期选采集模式默认游客模式免登录推荐并设定抓取数量 默认 10游客模式单次上限 20登录模式上限 300点开始游客模式不会让你扫码脚本自己开浏览器逛推荐流种 Cookie后直接采集登录模式自动弹出浏览器跳转小红书用手机 App扫码登录页面会显示剩余秒数采集过程中表格实时刷新列含义列含义昵称博主昵称小红书号博主 ID紧挨昵称空值显示-IP属地如「上海」取自主页 SSR 页未见则显示-推测职业规则引擎结论无法判断时显示「未识别」置信度高/中/低/无颜色区分仅昵称命中一律「低」备注小红书号的来源或为空时的原因见下节点停止可随时中止点一键导出 (CSV)或导出 Excel保存结果。 导出文件列昵称 / 小红书号 / 推测职业 / 职业大类 / 置信度 / 命中依据 / 简介 /备注/ 用户ID。行业筛选可选推荐先选行业命中率更高默认「不选行业」老行为随机推荐流。在页面上点选行业卡片可多选旅游 / 美食 / 摄影 / 健身 … 或填一个自定义关键词脚本就会带着关键词去找人而不是随机撞人。关键词分两条路走关键词类型走哪条路游客态可用说明命中内置行业频道旅游/美食/健身/美妆/穿搭/宠物/职场/家居/游戏/影视/情感 等行业频道流explore?channel_id…✅ 可用内容就是该行业的笔记取作者命中率最高实测4 秒取到 10 位作者其余行业与自定义关键词摄影/母婴/教育/数码/汽车/音乐/舞蹈/手工/读书…关键词搜索/api/sns/web/v1/search/notes❌ 需登录游客态接口恒返回-104 您当前登录的账号没有权限访问此时会直接跳过并在「阶段」里说明不再白等搜索页兜底顺序行业频道 → 关键词搜索 → 随机推荐流。每一步失败都会在页面「阶段」里写明原因不静默失败。内置「行业 → 频道」映射表见app_config.py: INDUSTRY_CHANNELS行业频道 ID行业频道 ID旅游 / 旅行homefeed.travel_v3职场homefeed.career_v3美食homefeed.food_v3健身homefeed.fitness_v3穿搭 / 时尚homefeed.fashion_v3家居 / 装修homefeed.household_product_v3美妆 / 彩妆homefeed.cosmetics_v3游戏homefeed.gaming_v3影视homefeed.movie_and_tv_v3宠物homefeed.pet情感homefeed.love_v3推荐随机homefeed_recommend⚠️ 这些 ID 是从小红书前端 JS 里提取后逐个实测确认的不是猜的。写错的 ID 不会报错 而是静默回退到推荐流——猜 ID 会让「行业筛选」悄悄失效所以包里内置的是实测表。 想加行业/换频道只改INDUSTRY_CHANNELS即可采集逻辑不用动。同一个行业的多个搜索词如 旅游 → 旅游攻略/旅行vlog/citywalk/自由行指向同一个频道 只会逛一次不会重复采集。结果表里「来源行业·关键词」列会标明每条数据来自哪个行业/关键词频道来源标记为channel 方便你判断筛选是否真的生效。推荐用法游客模式下优先「点选行业」走频道当前最有效自定义关键词搜索建议先扫码登录再跑。实测记录游客态、industries[旅游]、数量2展开关键词 → 旅游攻略 / 旅行vlog / citywalk / 自由行INDUSTRY_MAX_KEYWORDS6内自动展开首词命中频道homefeed.travel_v34 秒取到 10 位候选作者其余同频道的词自动跳过不再重复逛全程54 秒、正好 2 条结果来源列旅游攻略(channel)推测职业为摄影师 / 海钓船长 / 户外探险等旅游强相关仅当真的没有频道可用时才走搜索且游客态-104会立即跳过而不去等搜索页避免每条关键词白等 ~22 秒。小红书号为空怎么办小红书号有三层兜底且会在「备注」列说明原因不会静默丢字段主页接口 JSON 多路径解析redId/red_id/redID…字段被包在深层也能取到主页 HTML 文本正则小红书号xxx兼容半角/全角冒号浏览器打开主页真实登录态读__INITIAL_STATE__ 页面文本 / 标题。对应「备注」含义备注含义处理小红书号来源主页HTML(SSR)免登录 SSR 页解析得到游客模式常态正常小红书号来源主页接口 / 主页HTML / 页面文本 / 浏览器登录态取到了正常该账号未设置小红书号该博主确实没设 ID正常非 bug疑似被 IP 级风控拦成精简页页面无「小红书号」HTTP 200 但拿到的是 36KB 剥离/「安全限制」页降低频率稍后重试必要时等半小时或改用登录模式未取到主页资料可能未登录/被风控…抓取被拦稍后重试或重新扫码登录或调大RATE_MULTIPLIER登录判定已改为接口判定以GET /api/sns/web/v2/user/me的data.guest为准。 实测小红书会给未登录游客也下发web_sessionCookie长度 38 所以「Cookie 里有 web_session」不能当登录判据——早期版本据此判断会把游客误判成 已登录、跳过扫码随后主页资料抓不全出现「昵称有、小红书号空」的现象现已修复。 接口不可用网络抖动时降级为 Cookie 判据并把login_check标记为cookie_fallback。第 4 步可选自动自测不打开浏览器也能把四个接口跑一遍sh tools/web_selftest.sh # 结果写入 data/_web_test.txt另外还有两组完全离线、无需网络/浏览器的单元自检改完代码建议先跑python tools/test_industry.py # 行业筛选 / 频道解析 / 关键词展开 共 27 项 python tools/test_parse.py # 主页字段解析 / 小红书号多路径 共 16 项说明与限制运行环境为本地、无 IP 池若频繁触发风控请调大app_config.py里的RATE_MULTIPLIER。职业推断基于关键词规则命中的关键词会记录在导出文件的「命中依据」列便于人工核对。小红书接口字段可能随版本变化若推荐流接口不可用会自动回退到浏览器 DOM 采集作者。未装 Playwright 时python run.py仍能正常起服务、页面可打开但点「开始」会提示未安装 playwright。请先执行pip install playwright playwright install chromium。 此时可用「演示数据」先验证界面与导出。换机器独立运行本包可整体搬走本项目不依赖任何外部服务或原会话环境所有路径都由app_config.py的PROJECT_DIR即文件自身位置推导 所以整个目录复制到任意机器/任意路径都能跑。# 1) 拷到新机器解压后 tar xzf xhs_job_crawler_pkg.tar.gz cd xhs_job_crawler # 2) 装依赖自动建 .venv 下 chromium 内核只需一次 ./install.sh # 3) 启动 ./start.sh # → http://127.0.0.1:8777/环境要求项要求说明Python3.10推荐 3.11 / 3.12开发环境用的是 3.14较老的发行版请装 3.11系统库Linux 需libnss3等缺了就跑playwright install-deps chromium图形界面登录扫码模式需要纯游客模式可XHS_HEADLESS1无头跑网络能访问xiaohongshu.com需要出网有代理请在系统层面配好可调环境变量XHS_PORT8899 ./start.sh # 换端口默认 8777 XHS_HOST0.0.0.0 ./start.sh # 允许局域网访问默认仅本机 XHS_HEADLESS1 ./start.sh # 强制无头仅游客模式 XHS_CHANNELchrome ./start.sh # 用本机 Google Chrome