将监控程序直接跑在云端
将监控程序直接跑在云端(服务器),最大的好处是不需要保持个人电脑开机,能够 24 小时稳定运行。
由于在云端无法像浏览器插件那样直接复用你的日常登录状态,我们需要使用 headless(无头)浏览器技术(如 Node.js 的 Puppeteer 或 Python 的 Playwright),并在服务器上模拟人工登录和过验证。
以下是完整的云端架构、防封号核心配置以及完整的 Node.js 开发方案。
🧱 云端架构设计
宿主环境:建议选择 Linux 服务器(如 Ubuntu),内存建议 2GB 或以上(因为 Chrome 浏览器在云端比较吃内存)。
核心工具:Playwright(比 Puppeteer 更推荐,它的防检测反爬能力更强,API 更现代)。
状态持久化:在本地登录一次,将
Cookie和LocalStorage(登录状态)保存为 JSON 文件上传到服务器。这样云端程序启动时直接就是登录状态,完美绕过账号密码登录时的滑块或设备验证。
🚀 核心代码实现 (Node.js + Playwright)
第一步:初始化项目与安装依赖
在你的开发目录下执行:
bash
npm init -y
npm install playwright dotenv
请谨慎使用此类代码。
第二步:保存登录状态(在本地电脑执行一次)
新建 save_auth.js。运行该脚本后,会弹出一个真实的浏览器。你在里面手动登录你的 Facebook 账号,完成所有验证码或手机验证。登录成功进入首页后,关闭浏览器,它会自动将登录状态保存到 auth.json 中。
javascript
const { chromium } = require('playwright');
const fs = require('fs');
(async () => {
// 启动有界面的浏览器
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://facebook.com');
console.log('请在弹出的浏览器中手动登录 Facebook,确认登录成功后,在终端按回车键...');
// 等待用户在终端敲回车
await new Promise(resolve => process.stdin.once('data', resolve));
// 保存登录状态(包含 Cookie 等)
await context.storageState({ path: 'auth.json' });
console.log('登录状态已成功保存到 auth.json!');
await browser.close();
process.exit();
})();
请谨慎使用此类代码。
第三步:云端循环监控主程序 (monitor.js)
将生成的 auth.json 和以下 monitor.js 代码一起上传到你的云服务器。
javascript
const { chromium } = require('playwright');
const fs = require('fs');
// 配置项
const TARGET_GROUP = 'https://facebook.com'; // 目标群组,按最新帖子排序
const KEYWORDS = ['需要推荐', '求介绍', '预算', '寻找']; // 监控关键词
const NOTIFY_WEBHOOK = 'https://your-webhook-server.com'; // 你的接收通知地址(如飞书、钉钉、Telegram)
// 拟人化随机延迟函数
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const randomDelay = (min, max) => delay(Math.floor(Math.random() * (max - min + 1) + min));
async function checkGroup() {
console.log(`[${new Date().toLocaleString()}] 开始新一轮群组扫描...`);
// 启动无头浏览器,并加入极其重要的“防检测”参数
const browser = await chromium.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-blink-features=AutomationControlled', // 隐藏自动化特征,防封核心
]
});
// 加载之前保存的登录状态
const context = await browser.newContext({
storageState: 'auth.json',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
viewport: { width: 1280, height: 800 }
});
const page = await context.newPage();
try {
// 访问目标群组
await page.goto(TARGET_GROUP, { waitUntil: 'networkidle', timeout: 60000 });
await randomDelay(3000, 5000); // 模拟人类停顿看网页
// 模拟人类向下滑动 1~2 次屏幕,加载更多最新帖子
for (let i = 0; i < 2; i++) {
await page.evaluate(() => window.scrollBy(0, window.innerHeight * 0.8));
await randomDelay(2000, 4000);
}
// 抓取帖子内容(根据 FB 目前的 DOM 结构,文字通常在 data-ad-preview="message" 的 div 中)
// 注意:Facebook 经常微调前端类名,如果失效需要重新审查元素修改选择器
const posts = await page.$$eval('div[data-ad-preview="message"]', (elements) => {
return elements.map(el => {
// 尝试获取该帖子的链接,通常在祖先节点的 article 元素里找
const article = el.closest('div[role="article"]');
const linkEl = article ? article.querySelector('a[href*="/permalink/"]') : null;
return {
text: el.innerText || "",
url: linkEl ? linkEl.href : window.location.href
};
});
});
console.log(`成功抓取到 ${posts.length} 个帖子,开始匹配关键词...`);
// 匹配关键词并发送通知
for (const post of posts) {
const matched = KEYWORDS.some(kw => post.text.includes(kw));
if (matched) {
console.log(`🔥 匹配到关键词!内容:${post.text.substring(0, 30)}`);
// 触发你的 Webhook 通知
await fetch(NOTIFY_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: "📢 FB群组发现目标线索",
content: post.text,
link: post.url
})
}).catch(err => console.error("通知发送失败:", err));
}
}
} catch (error) {
console.error('扫描过程中发生错误:', error);
} finally {
// 必须关闭上下文和浏览器,释放内存
await context.close();
await browser.close();
}
}
// 调度主循环:使用随机间隔防止被 FB 算法识别为机器人
async function main() {
if (!fs.existsSync('auth.json')) {
console.error('错误:未找到 auth.json,请先在本地运行 save_auth.js 生成!');
return;
}
while (true) {
try {
await checkGroup();
} catch (e) {
console.error(e);
}
// 随机等待 20 到 35 分钟再进行下一次检查
const nextWaitMin = Math.floor(Math.random() * (35 - 20 + 1) + 20);
console.log(`💤 等待 ${nextWaitMin} 分钟后进行下一次扫描...\n`);
await delay(nextWaitMin * 60 * 1000);
}
}
main();
请谨慎使用此类代码。
⚠️ 云端运行的“降维打击”与避坑指南
在云端跑此类脚本,有两点需要特别注意:
IP 干净度(最重要):
阿里云、腾讯云、AWS 等公共云厂商的机房 IP 早就被 Facebook 列入了高风险名单。如果你的小号刚在机房 IP 上登录,极易触发“账户异常锁定”。解决方案:强烈建议在服务器上配置 住宅代理 IP(Residential Proxy)。让 Playwright 通过住宅 IP 去访问 Facebook,伪装成普通的家用宽带用户。
云端后台持续运行:
在 Linux 服务器上,不能直接node monitor.js,因为终端断开程序就死了。解决方案:使用
pm2管理进程。在服务器上安装:npm install pm2 -g,然后运行pm2 start monitor.js --name "fb-monitor"。它会自动在后台运行,崩溃了还会自动重启。