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

Playwright无头模式下DevOps流水线Captcha绕过方案咨询

问题描述

当将headless mode设置为false时,以下登录代码可正常执行,但在DevOps流水线的headless模式下运行时,会遇到Captcha验证界面,导致流程中断执行失败。需要解决在headless模式下绕过Captcha的问题。

复现代码
import { expect, chromium } from "playwright/test";

module.exports = async () => {
    const browser = await chromium.launch();
    await browser.newContext();

    const page = await browser.newPage();
    await page.goto(process.env.VITE_BASE_URL ?? "https://photondev.sgsco.com/");
    const origin = await page.evaluate(() => window.location.origin);
    await page.goto(`${origin}/dashboard`);
    await page.getByRole("button", { name: "Login As A Client" }).click();
    await page.getByRole("link", { name: "Google" }).click();
    await page
        .getByLabel("Email or phone")
        .fill(process.env.VITE_PLAYWRIGHT_GMAIL_USERNAME ?? "test");
    await page.getByRole("button", { name: "Next" }).click();
    await page
        .getByLabel("Enter your password")
        .fill(process.env.VITE_PLAYWRIGHT_GMAIL_PASSWORD ?? "test@123");
    await page
        .locator("#passwordNext")
        .getByRole("button", { name: "Next" })
        .click();
    await page.waitForURL(
        `${origin}/dashboard?period=last+3+months&status=4&toggle=true`,
    );
    expect(page).toHaveURL(
        `${origin}/dashboard?period=last+3+months&status=4&toggle=true`,
    );
    await page.goto(
        `my page`,
    );
    await page.goto(`${origin}/dashboard`);
    await page.goto(
        `${origin}/dashboard?period=last+3+months&status=4&toggle=true`,
    );
    await page.context().storageState({ path: "state.json" });
    await browser.close();
};
解决方案

1. 优化Headless模式配置,模拟真实浏览器环境

Playwright旧无头模式易被检测,改用新无头模式并添加真实浏览器参数,降低被识别为自动化工具的概率:

const browser = await chromium.launch({
  headless: "new", // 使用Playwright新无头模式,更接近真实浏览器
  args: [
    "--disable-blink-features=AutomationControlled", // 禁用自动化检测标志
    "--start-maximized"
  ],
  slowMo: 100, // 模拟人类操作速度,避免触发反爬规则
});

const context = await browser.newContext({
  userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
  viewport: { width: 1920, height: 1080 },
  locale: "en-US",
});

2. 复用已登录存储状态,跳过登录流程

先在本地非无头模式下运行代码生成state.json,流水线中直接加载该状态,从根本上避开Captcha:

// 流水线执行代码,直接加载预先生成的登录状态
const context = await browser.newContext({
  storageState: "state.json", // 跳过登录,直接使用已验证的会话
});
const page = await context.newPage();
// 直接访问目标页面,无需重复登录
await page.goto(`${origin}/dashboard?period=last+3+months&status=4&toggle=true`);

3. 添加随机延迟,模拟人类操作节奏

在表单填写、按钮点击之间加入随机延迟,避免操作过于机械化:

// 填写邮箱后随机延迟500-1000ms
await page.getByLabel("Email or phone").fill(process.env.VITE_PLAYWRIGHT_GMAIL_USERNAME ?? "test");
await page.waitForTimeout(Math.floor(Math.random() * 500) + 500);

await page.getByRole("button", { name: "Next" }).click();
await page.waitForTimeout(Math.floor(Math.random() * 800) + 300);

4. 请求网站管理员添加测试白名单

如果是内部系统,直接联系管理员将DevOps流水线IP或测试账号加入反爬白名单,这是最稳定可靠的解决方案,无需额外修改代码。

5. 补充必要请求头与权限

部分网站会检查特定请求头或权限,可在context中补充相关配置:

const context = await browser.newContext({
  extraHTTPHeaders: {
    "Accept-Language": "en-US,en;q=0.9",
    "Referer": `${origin}/`,
  },
  permissions: ["geolocation"], // 若网站需要地理位置权限可添加
});

内容的提问来源于stack exchange,提问作者Ahila .B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:33:10