修复搜索和用户主页的笔记 ID 提取及风控绕过问题

- 搜索页笔记 href 格式为 /search_result/<id>,修正正则以兼容 /explore/ 和 /search_result/
- 用户主页笔记 href 格式为 /user/profile/<userId>/<noteId>,扩展正则并取正确捕获组
- 用户主页访问前先 warm-up 到 /explore,绕过 XHS headless IP 风控(code 300012)
- xsec_source 改为 pc_feed 以匹配用户从 feed 页获取的 token 类型
- 新增 debug-search.ts / debug-qrcode.ts / debug-profile.ts 诊断脚本
This commit is contained in:
2026-03-01 22:44:45 +08:00
parent 8b39520ec7
commit 56d5a6de96
5 changed files with 265 additions and 4 deletions
+39
View File
@@ -0,0 +1,39 @@
import { chromium } from 'rebrowser-playwright';
import { readFileSync } from 'node:fs';
const COOKIE_FILE = `${process.env.HOME}/.social-mcp/xiaohongshu/cookies.json`;
const userId = '5b29b622e8ac2b5a12ae97fc';
const xsecToken = 'ABrhIpSL55O66wuekMtlJUxsX4EpaNTlfCYwDo6UfKrrM=';
async function main() {
const raw = JSON.parse(readFileSync(COOKIE_FILE, 'utf-8'));
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage','--disable-gpu'] });
const ctx = await browser.newContext({ storageState: raw });
const page = await ctx.newPage();
// Warm up: visit explore first
console.log('Warming up: visiting explore...');
await page.goto('https://www.xiaohongshu.com/explore', { waitUntil: 'domcontentloaded' });
await page.waitForTimeout(2000);
console.log('Explore title:', await page.title());
// Now try profile with pc_feed source (matching the token's source)
const url = `https://www.xiaohongshu.com/user/profile/${userId}?xsec_token=${encodeURIComponent(xsecToken)}&xsec_source=pc_feed`;
console.log('\nNavigating to profile (xsec_source=pc_feed)...');
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForTimeout(2000);
console.log('title:', await page.title());
console.log('url:', page.url().slice(0, 80));
const nickname = await page.$eval('.user-info .user-name', el => el.textContent?.trim() ?? '').catch(() => 'NOT FOUND');
console.log('nickname:', nickname);
const feeds = await page.$$('.feeds-container .note-item');
console.log('note items:', feeds.length);
if (feeds.length > 0) {
const href = await feeds[0]!.$eval('a.cover', el => el.getAttribute('href') ?? '').catch(() => '');
console.log('first note href:', href);
}
await browser.close();
}
main().catch(e => { console.error(e); process.exit(1); });