修复 sec_user_id 抓取:同时解析请求 URL 与 body,修正关注按钮选择器
This commit is contained in:
+48
-17
@@ -1,4 +1,4 @@
|
|||||||
// 获取抖音 Cookie 和 sec_user_id 的 Playwright 脚本
|
// 获取抖音 Cookie 和 sec_user_id 的 Playwright 脚本
|
||||||
// 用法: node get-cookie.js 或通过 cli.js cookies 调用
|
// 用法: node get-cookie.js 或通过 cli.js cookies 调用
|
||||||
// 首次运行扫码登录,后续运行浏览器会记住登录状态,无需重复扫码
|
// 首次运行扫码登录,后续运行浏览器会记住登录状态,无需重复扫码
|
||||||
|
|
||||||
@@ -128,24 +128,43 @@ async function openAndLogin(context) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
// 提取 sec_user_id
|
// 提取 sec_user_id
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
// 从任意文本/URL 中提取 sec_user_id
|
||||||
|
// 兼容:URL query ?sec_user_id=xxx / JSON body "sec_user_id":"xxx"
|
||||||
|
function pickSecUserId(text) {
|
||||||
|
if (!text) return null;
|
||||||
|
// 匹配 sec_user_id=xxx 或 "sec_user_id":"xxx"
|
||||||
|
const m = text.match(/sec_user_id(?:=|%3D|":"|%22:%22|\":\")([^&"'\s]+)/i);
|
||||||
|
if (m && m[1] && m[1] !== "self") return decodeURIComponent(m[1]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
async function extractSecUserId(page) {
|
async function extractSecUserId(page) {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
let found = null;
|
let found = null;
|
||||||
|
|
||||||
page.on("request", (request) => {
|
// 监听所有请求:既看 URL 查询串,也看 POST body
|
||||||
|
const onRequest = (request) => {
|
||||||
|
if (found) return;
|
||||||
try {
|
try {
|
||||||
const data = request.postData();
|
// 1) 优先看 URL(following/list 等 GET 请求的 sec_user_id 在这里)
|
||||||
if (data && data.includes("sec_user_id")) {
|
const fromUrl = pickSecUserId(request.url());
|
||||||
const parsed = JSON.parse(data);
|
if (fromUrl) {
|
||||||
if (parsed.sec_user_id && !found) {
|
found = fromUrl;
|
||||||
found = parsed.sec_user_id;
|
console.log("✅ 从请求 URL 捕获到 sec_user_id:", found);
|
||||||
console.log("✅ 从请求中捕获到 sec_user_id:", found);
|
return;
|
||||||
}
|
}
|
||||||
|
// 2) 再看 POST body
|
||||||
|
const data = request.postData();
|
||||||
|
const fromBody = pickSecUserId(data);
|
||||||
|
if (fromBody) {
|
||||||
|
found = fromBody;
|
||||||
|
console.log("✅ 从请求 Body 捕获到 sec_user_id:", found);
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
});
|
};
|
||||||
|
page.on("request", onRequest);
|
||||||
|
|
||||||
// 尝试从页面获取
|
// 从页面本身尝试
|
||||||
await page.waitForTimeout(TIMEOUTS.pageWait);
|
await page.waitForTimeout(TIMEOUTS.pageWait);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
try {
|
try {
|
||||||
@@ -167,20 +186,32 @@ async function extractSecUserId(page) {
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试点击关注按钮触发请求
|
// 兜底:主动点击头像旁边的「关注 / 关注列表」按钮,触发 following/list 请求
|
||||||
|
// 抖音此按钮有多种 data-e2e,逐个尝试
|
||||||
if (!found) {
|
if (!found) {
|
||||||
console.log("🖱️ 尝试点击关注按钮...");
|
const selectors = [
|
||||||
|
'[data-e2e="following-count"]', // 关注数(点它弹关注列表)
|
||||||
|
'[data-e2e="user-info-follow"]', // 关注按钮
|
||||||
|
'span:has-text("关注")',
|
||||||
|
];
|
||||||
|
for (const sel of selectors) {
|
||||||
|
if (found) break;
|
||||||
|
console.log(`🖱️ 尝试点击关注入口: ${sel}`);
|
||||||
try {
|
try {
|
||||||
const btn = page.locator('[data-e2e="follow-count"]').first();
|
const btn = page.locator(sel).first();
|
||||||
if (await btn.isVisible({ timeout: TIMEOUTS.elementVisible })) {
|
if (await btn.isVisible({ timeout: TIMEOUTS.elementVisible }).catch(() => false)) {
|
||||||
await btn.click();
|
await btn.click().catch(() => {});
|
||||||
|
// 触发后再多等一会儿收集请求
|
||||||
await page.waitForTimeout(TIMEOUTS.pageWait);
|
await page.waitForTimeout(TIMEOUTS.pageWait);
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 等最后 3 秒收集网络请求
|
// 再等一会儿收集网络请求
|
||||||
await page.waitForTimeout(TIMEOUTS.pageWait);
|
if (!found) await page.waitForTimeout(TIMEOUTS.pageWait);
|
||||||
|
|
||||||
|
page.off("request", onRequest);
|
||||||
resolve(found);
|
resolve(found);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user