You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何保持Windows Server会话活跃以全屏运行Puppeteer?

解决Windows Server断开RDS后Puppeteer/Chrome冻结的问题

问题根源

断开RDS连接后,Windows Server默认会冻结或注销用户会话,Chrome非无头模式依赖用户会话的桌面环境运行,一旦会话被冻结,Chrome的GUI进程会停止响应,导致Puppeteer的CDP连接中断,触发Execution context was destroyed错误。

解决方案

1. 配置Windows Server保持RDS会话不冻结

修改系统策略和会话设置,确保断开RDS后用户会话仍保持活跃:

  • 打开本地组策略编辑器(gpedit.msc):
    • 导航到计算机配置 > 管理模板 > Windows组件 > 远程桌面服务 > 远程桌面会话主机 > 会话时间限制
    • 设置设置断开连接的会话的时间限制为已禁用
    • 设置设置活动但空闲的远程桌面服务会话的时间限制为已禁用
  • 打开远程桌面会话主机配置(tsconfig.msc):
    • 右键选中目标会话,点击属性
    • 在会话选项卡中,设置结束已断开的会话为从不,空闲会话限制为从不
  • 检查用户账户设置:
    • 打开计算机管理,导航到本地用户和组 > 用户
    • 右键目标用户,点击属性,在会话选项卡中确保结束已断开的会话为从不

2. 以Windows服务运行Chrome和Node.js应用

将Chrome和你的Express应用注册为系统服务,脱离用户会话运行(系统会话0不受RDS断开影响):

  • 使用NSSM工具将Node.js应用包装为服务:
    • 运行nssm install [服务名],在配置窗口中指定Node.exe路径、脚本路径和项目工作目录
  • 配置Chrome在服务中启动:
    • 启动Chrome时添加参数:chrome.exe --no-sandbox --disable-gpu --remote-debugging-port=9222
    • 同样用NSSM将Chrome注册为服务,设置启动类型为自动
    • 注意:部分Windows版本需给服务开启允许服务与桌面交互权限,或搭配虚拟显示驱动使用

3. 安装虚拟显示驱动

非无头Chrome需要显示输出,安装虚拟显示驱动模拟桌面环境,即使没有真实显示器或用户会话,Chrome也能正常运行:

  • 安装虚拟显示驱动(如Virtual Display Adapter),系统会生成虚拟显示器
  • 启动Chrome时可指定分辨率参数:--window-size=1920,1080

脚本优化建议

全局复用browser和page实例会导致会话失效后无法恢复,建议每次请求创建新实例并及时清理:

const express = require('express');
const puppeteer = require('puppeteer');

const app = express();

app.get('/scrape', async (req, res) => {
  let result = {};
  const { url } = req.query;
  
  if (!url) {
    return res.status(400).send('请提供要爬取的URL');
  }

  console.log(`Scraping URL: ${url}`);
  let browser = null;
  let page = null;

  // 连接浏览器
  console.log(`Launch browser..`);
  try {
    browser = await puppeteer.connect({
      browserURL: 'http://localhost:9222',
      defaultViewport: null,
    });
  } catch (error) {
    console.error('An error occurred:', error);
    result.error=`无法连接到浏览器: ${error}`;
    return res.send(result);
  }
  
  // 创建新页面
  console.log(`Get page..`);
  try {
    page = await browser.newPage();
  } catch (error) {
    console.error('An error occurred:', error);
    await browser?.close();
    result.error=`无法创建页面: ${error}`;
    return res.send(result);
  }
  
  // 导航到目标URL
  console.log(`Navigate..`);
  try {
    const response = await page.goto(url, { waitUntil: 'domcontentloaded' });
    const statusCode = response.status();
    result.statusCode = statusCode;
    
    if (statusCode !== 200) {
      result.error = "无效状态码";
      return res.send(result);
    }
  } catch (error) {
    console.error('An error occurred:', error);
    result.error=`无法导航到URL: ${error}`;
    return res.send(result);
  }

  // 后续爬取逻辑(获取标题、检查侧边栏、点击电话链接等)...

  // 清理资源
  try {
    await page?.close();
    await browser?.disconnect();
  } catch (cleanupErr) {
    console.error('清理资源时出错:', cleanupErr);
  }

  res.send(result);
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

内容的提问来源于stack exchange,提问作者Alexandru Trandafir Catalin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:44:58