使用 Playwright 和沙箱模式实现安全的浏览器自动化

打印 上一主题 下一主题

主题 989|帖子 989|积分 2967

我的需求,做一个流式测试环境,一个结点测试用例跑完,进入下一个结点运行。

必要具备下面特性:
1、使用沙箱模式隔离执行环境
2、使用 Playwright 进行浏览器自动化
3. 实现了安全的变量共享机制
4、包含了错误处理和资源清理
5、支持动态代码执行
实现代码片段
  1. const { chromium } = require('playwright')
  2. class Sandbox {
  3.   constructor() {
  4.     this.sharedVariables = {
  5.       browser: null,
  6.       page: null,
  7.       pageScreenshot: null,
  8.     }
  9.     // 创建代理对象来自动处理变量存取
  10.     this.context = new Proxy(this.sharedVariables, {
  11.       get: (target, prop) => target[prop],
  12.       set: (target, prop, value) => {
  13.         target[prop] = value
  14.         return true
  15.       },
  16.     })
  17.   }
  18.   // 获取代理对象
  19.   getContext() {
  20.     return this.context
  21.   }
  22.   // 保留cleanup方法
  23.   async cleanup() {
  24.     if (this.context.browser) {
  25.       await this.context.browser.close()
  26.       this.context.browser = null
  27.       this.context.page = null
  28.     }
  29.   }
  30. }
  31. // 修改 createSandboxExecutor 使用新的 context
  32. const createSandboxExecutor = (code, sandbox) => {
  33.   return new Function(
  34.     'sandbox',
  35.     'chromium',
  36.     `
  37.     return (async () => {
  38.       try {
  39.         const context = sandbox.getContext();
  40.         
  41.         // 添加全局对象到上下文
  42.         Object.assign(context, {
  43.           console,
  44.           setTimeout,
  45.           setInterval,
  46.           clearTimeout,
  47.           clearInterval,
  48.           chromium,
  49.         });
  50.         with (context) {
  51.           ${code}
  52.         }
  53.         return context;
  54.       } catch (error) {
  55.         throw new Error('Sandbox execution error: ' + error.message);
  56.       }
  57.     })()
  58.   `
  59.   )
  60. }
  61. // 执行代码片段
  62. async function executeCodeSnippet(sandbox, code) {
  63.   try {
  64.     const executor = createSandboxExecutor(code, sandbox)
  65.     return await executor(sandbox, chromium)
  66.   } catch (error) {
  67.     await sandbox.cleanup()
  68.     throw error
  69.   }
  70. }
  71. // 优化后的代码片段 1
  72. const code1 = `
  73.   browser = await chromium.launch({
  74.     headless: false,
  75.     args: ['--no-sandbox', '--disable-setuid-sandbox'],
  76.     timeout: 10000
  77.   });
  78.   page = await browser.newPage();
  79.   await page.setViewportSize({ width: 1280, height: 800 });
  80.   console.log('Browser and page launched');
  81. `
  82. // 优化后的代码片段 2
  83. const code2 = `
  84.   try {
  85.     await page.goto('https://music.163.com/', { waitUntil: 'networkidle' });
  86.     pageScreenshot = Buffer.from(await page.screenshot({
  87.       fullPage: true,
  88.       quality: 80,
  89.       type: 'jpeg'
  90.     })).toString('base64');
  91.     console.log('Page screenshot captured');
  92.   } catch (error) {
  93.     console.error('Failed to capture screenshot:', error);
  94.     throw error;
  95.   }
  96. `
  97. async function run() {
  98.   const sandbox = new Sandbox()
  99.   try {
  100.     await executeCodeSnippet(sandbox, code1)
  101.     await executeCodeSnippet(sandbox, code2)
  102.     const context = sandbox.getContext()
  103.     console.log('截图成功:', !!context.pageScreenshot)
  104.   } catch (error) {
  105.     console.error('执行错误:', error)
  106.   } finally {
  107.     await sandbox.cleanup()
  108.   }
  109. }
  110. run()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表