avatar

mdo

Hello

  • 首页
  • 知识库
  • 归档
  • 标签
  • 关于
主页 将监控程序直接跑在云端
文章

将监控程序直接跑在云端

发表于 15天前 更新于 15天前
作者 mdo
15~19 分钟 阅读

将监控程序直接跑在云端(服务器),最大的好处是不需要保持个人电脑开机,能够 24 小时稳定运行。

由于在云端无法像浏览器插件那样直接复用你的日常登录状态,我们需要使用 headless(无头)浏览器技术(如 Node.js 的 Puppeteer 或 Python 的 Playwright),并在服务器上模拟人工登录和过验证。

以下是完整的云端架构、防封号核心配置以及完整的 Node.js 开发方案。


🧱 云端架构设计

  1. 宿主环境:建议选择 Linux 服务器(如 Ubuntu),内存建议 2GB 或以上(因为 Chrome 浏览器在云端比较吃内存)。

  2. 核心工具:Playwright(比 Puppeteer 更推荐,它的防检测反爬能力更强,API 更现代)。

  3. 状态持久化:在本地登录一次,将 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();

请谨慎使用此类代码。


⚠️ 云端运行的“降维打击”与避坑指南

在云端跑此类脚本,有两点需要特别注意:

  1. IP 干净度(最重要):
    阿里云、腾讯云、AWS 等公共云厂商的机房 IP 早就被 Facebook 列入了高风险名单。如果你的小号刚在机房 IP 上登录,极易触发“账户异常锁定”。

    • 解决方案:强烈建议在服务器上配置 住宅代理 IP(Residential Proxy)。让 Playwright 通过住宅 IP 去访问 Facebook,伪装成普通的家用宽带用户。

  2. 云端后台持续运行:
    在 Linux 服务器上,不能直接
    node monitor.js,因为终端断开程序就死了。

    • 解决方案:使用 pm2 管理进程。在服务器上安装:npm install pm2 -g,然后运行 pm2 start monitor.js --name "fb-monitor"。它会自动在后台运行,崩溃了还会自动重启。

技术
许可协议:  CC BY 4.0
分享

相关文章

7月 26, 2026

完美地解决 TP3 老系统数据的平滑读取

为了彻底、完美地解决 TP3 老系统数据的平滑读取,必须解决两个核心痛点: TP3 的盲猜反序列化机制(标量存原样,数组/对象存原生 serialize,同时兼容 json)。 TP3 与 TP6 的缓存前缀(Prefix)不一致。 以下是为你量身定制的终极落地解决方案,通

7月 26, 2026

thinkphp3 redis序列化和反序列化

在老系统重构迁移至 ThinkPHP 6 (TP6) 的过程中,ThinkPHP 3 (TP3) 的 Redis 序列化历史遗留问题是最核心的连环坑之一。 TP3 的 S('key', $value) 缓存方法和底层 Redis 驱动,在存储非字符串(如数组、对象)时,有一套独特的序列化行为。如果不

7月 24, 2026

Table 空间极易发生哈希冲突并溢出

既然你没有在业务中主动调用 Room,只使用了全局广播,那么这个问题就非常明确了:即使你不用房间功能,think-swoole 只要开启了 WebSocket,底层就会强行初始化并注入一个名为 Room 的驱动组件。 [1] 框架底层默认使用 table 类型来作为 Room 的存储介质。当进行全局

下一篇

AI 驱动型 Facebook 群组关键词监控 Chrome 浏览器插件

上一篇

Table 空间极易发生哈希冲突并溢出

最近更新

  • 完美地解决 TP3 老系统数据的平滑读取
  • thinkphp3 redis序列化和反序列化
  • Table 空间极易发生哈希冲突并溢出
  • 将监控程序直接跑在云端
  • AI 驱动型 Facebook 群组关键词监控 Chrome 浏览器插件

热门标签

API CodeGeex Gitkraken Management Manticore Premiere Sublime Swoole ThinkPHP ThinkPHP5

目录

©2026 mdo. 保留部分权利。