{
  "canonical_name": "puppeteer/puppeteer",
  "compilation_id": "pack_b456d8ae8a1a40fe8c174637984b3a19",
  "created_at": "2026-05-16T05:02:37.775498+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=skill, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=skill, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npm i puppeteer` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npm i puppeteer",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_625faaf7f5c646308f213780b0cd0dff"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_3c1d56b2b886ac2b018813fa8a8a6f63",
    "canonical_name": "puppeteer/puppeteer",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/puppeteer/puppeteer",
    "slug": "puppeteer",
    "source_packet_id": "phit_32eb41d0731945eebf9159709047c71b",
    "source_validation_id": "dval_25fd9b42e7524484a309f55c8d5afd29"
  },
  "merchandising": {
    "best_for": "需要软件开发与交付能力，并使用 local_cli的用户",
    "github_forks": 9416,
    "github_stars": 94330,
    "one_liner_en": "JavaScript API for Chrome and Firefox",
    "one_liner_zh": "JavaScript API for Chrome and Firefox",
    "primary_category": {
      "category_id": "software-development",
      "confidence": "medium",
      "name_en": "Software Development",
      "name_zh": "软件开发与交付",
      "reason": "matched_keywords:git, cli"
    },
    "target_user": "使用 local_cli 等宿主 AI 的用户",
    "title_en": "puppeteer",
    "title_zh": "puppeteer 能力包",
    "visible_tags": [
      {
        "label_en": "Browser Agents",
        "label_zh": "浏览器 Agent",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-browser-agents",
        "type": "product_domain"
      },
      {
        "label_en": "Web Task Automation",
        "label_zh": "网页任务自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-web-task-automation",
        "type": "user_job"
      },
      {
        "label_en": "Browser Automation",
        "label_zh": "浏览器自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-browser-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Node-based Workflow",
        "label_zh": "节点式流程编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-node-based-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_32eb41d0731945eebf9159709047c71b",
  "page_model": {
    "artifacts": {
      "artifact_slug": "puppeteer",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npm i puppeteer",
          "label": "Node.js / npm · 官方安装入口",
          "source": "https://github.com/puppeteer/puppeteer#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "浏览器自动化",
        "节点式流程编排",
        "评测体系"
      ],
      "eyebrow": "软件开发与交付",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要软件开发与交付能力，并使用 local_cli的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "JavaScript API for Chrome and Firefox"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "local_cli",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "skill, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Chrome Canary/Firefox Nightly test results",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_1aabe120a9df47a2adbd293381b50a64 | https://github.com/puppeteer/puppeteer/issues/12379 | 来源类型 github_issue 暴露的待验证使用条件。"
            ],
            "severity": "high",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Chrome Canary/Firefox Nightly test results",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Puppeteer v25",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_050f65ceff2a455da4a3538895a7538b | https://github.com/puppeteer/puppeteer/issues/14342 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "high",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Puppeteer v25",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: GHSA issued a false malicious package alert for puppeteer",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_55588dfbd41442fdb8a2f4f1be57e4c9 | https://github.com/puppeteer/puppeteer/issues/14986 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。"
            ],
            "severity": "high",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：[Bug]: GHSA issued a false malicious package alert for puppeteer",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_9b1ef7c38ed14c41b3e4ce786adcdf26 | https://github.com/puppeteer/puppeteer/issues/14774 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。"
            ],
            "severity": "high",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_5d1f448d8768460a806ab32e8d4f6997 | https://github.com/puppeteer/puppeteer/issues/14957 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: `setViewport` crashes on Firefox if uncaught",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_75bddb8a74194cf7a8978853f19db23a | https://github.com/puppeteer/puppeteer/issues/14989 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：[Bug]: `setViewport` crashes on Firefox if uncaught",
            "user_impact": "可能阻塞安装或首次运行。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: chrome binary is not present when installing latest chrome",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_1e85cdab2b684dda8e5c83f55b8ff7b6 | https://github.com/puppeteer/puppeteer/issues/14988 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：[Bug]: chrome binary is not present when installing latest chrome",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Feature]: Make proxy-agent dependency optional",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_195c51e4a5e84edda14a2a79b456821c | https://github.com/puppeteer/puppeteer/issues/13775 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：[Feature]: Make proxy-agent dependency optional",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安装相关的待验证问题：browsers: v3.0.0",
            "category": "安装坑",
            "evidence": [
              "community_evidence:github | cevd_bf2d83568c54447fbfd3047d24be0c48 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：browsers: v3.0.0",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：browsers: v3.0.2",
            "category": "能力坑",
            "evidence": [
              "community_evidence:github | cevd_c9f08632e7ee4e9485d27b864a21e462 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2 | 来源类型 github_release 暴露的待验证使用条件。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：browsers: v3.0.2",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：puppeteer-core: v25.0.2",
            "category": "能力坑",
            "evidence": [
              "community_evidence:github | cevd_3a8b10a5263e4d6488e16972c8249a38 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2 | 来源类型 github_release 暴露的待验证使用条件。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：puppeteer-core: v25.0.2",
            "user_impact": "可能增加新用户试用和生产接入成本。"
          },
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:90796663 | https://github.com/puppeteer/puppeteer | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：ng-schematics: v0.8.0",
            "category": "维护坑",
            "evidence": [
              "community_evidence:github | cevd_4e7ee6a70b1d4fb6879ab4670099d205 | https://github.com/puppeteer/puppeteer/releases/tag/ng-schematics-v0.8.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：ng-schematics: v0.8.0",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer-core: v25.0.0",
            "category": "维护坑",
            "evidence": [
              "community_evidence:github | cevd_3e6a5770b15146ddab5249f1aa687cae | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：puppeteer-core: v25.0.0",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer: v25.0.0",
            "category": "维护坑",
            "evidence": [
              "community_evidence:github | cevd_9294fdbab95d446887bdb54a11df66d2 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。",
            "title": "来源证据：puppeteer: v25.0.0",
            "user_impact": "可能影响升级、迁移或版本选择。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 21 个潜在踩坑项，其中 4 个为 high/blocking；最高优先级：安装坑 - 来源证据：Chrome Canary/Firefox Nightly test results。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 553,
        "forks": 9416,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 94330
      },
      "source_url": "https://github.com/puppeteer/puppeteer",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "JavaScript API for Chrome and Firefox",
      "title": "puppeteer 能力包",
      "trial_prompt": "# puppeteer - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 puppeteer 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: JavaScript API for Chrome and Firefox 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-overview：Puppeteer项目概览。围绕“Puppeteer项目概览”模拟一次用户任务，不展示安装或运行结果。\n2. page-installation：安装与入门指南。围绕“安装与入门指南”模拟一次用户任务，不展示安装或运行结果。\n3. page-architecture：Puppeteer系统架构。围绕“Puppeteer系统架构”模拟一次用户任务，不展示安装或运行结果。\n4. page-protocols：协议实现：CDP与WebDriver BiDi。围绕“协议实现：CDP与WebDriver BiDi”模拟一次用户任务，不展示安装或运行结果。\n5. page-browser-management：浏览器启动与管理。围绕“浏览器启动与管理”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-overview\n输入：用户提供的“Puppeteer项目概览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-installation\n输入：用户提供的“安装与入门指南”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-architecture\n输入：用户提供的“Puppeteer系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-protocols\n输入：用户提供的“协议实现：CDP与WebDriver BiDi”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-browser-management\n输入：用户提供的“浏览器启动与管理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-overview：Step 1 必须围绕“Puppeteer项目概览”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-installation：Step 2 必须围绕“安装与入门指南”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-architecture：Step 3 必须围绕“Puppeteer系统架构”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-protocols：Step 4 必须围绕“协议实现：CDP与WebDriver BiDi”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-browser-management：Step 5 必须围绕“浏览器启动与管理”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/puppeteer/puppeteer\n- https://github.com/puppeteer/puppeteer#readme\n- README.md\n- package.json\n- packages/puppeteer-core/package.json\n- docs/guides/what-is-puppeteer.md\n- packages/puppeteer-core/src/puppeteer-core.ts\n- packages/puppeteer/install.mjs\n- packages/puppeteer/src/install.ts\n- docs/guides/installation.md\n- docs/guides/getting-started.md\n- examples/README.md\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 puppeteer 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: [Bug]: GHSA issued a false malicious package alert for puppeteer（https://github.com/puppeteer/puppeteer/issues/14986）；github/github_issue: Chrome Canary/Firefox Nightly test results（https://github.com/puppeteer/puppeteer/issues/12379）；github/github_issue: [Bug]: `setViewport` crashes on Firefox if uncaught（https://github.com/puppeteer/puppeteer/issues/14989）；github/github_issue: [Bug]: chrome binary is not present when installing latest chrome（https://github.com/puppeteer/puppeteer/issues/14988）；github/github_issue: [Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 （https://github.com/puppeteer/puppeteer/issues/14957）；github/github_issue: [Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stde（https://github.com/puppeteer/puppeteer/issues/14774）；github/github_issue: [Feature]: Reducing dependencies（https://github.com/puppeteer/puppeteer/issues/13552）；github/github_issue: [Feature]: Make proxy-agent dependency optional（https://github.com/puppeteer/puppeteer/issues/13775）；github/github_issue: Puppeteer v25（https://github.com/puppeteer/puppeteer/issues/14342）；github/github_release: puppeteer-core: v25.0.2（https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2）；github/github_release: browsers: v3.0.2（https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2）；github/github_release: puppeteer-core: v25.0.1（https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.1）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Bug]: GHSA issued a false malicious package alert for puppeteer",
              "url": "https://github.com/puppeteer/puppeteer/issues/14986"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Chrome Canary/Firefox Nightly test results",
              "url": "https://github.com/puppeteer/puppeteer/issues/12379"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Bug]: `setViewport` crashes on Firefox if uncaught",
              "url": "https://github.com/puppeteer/puppeteer/issues/14989"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Bug]: chrome binary is not present when installing latest chrome",
              "url": "https://github.com/puppeteer/puppeteer/issues/14988"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 ",
              "url": "https://github.com/puppeteer/puppeteer/issues/14957"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stde",
              "url": "https://github.com/puppeteer/puppeteer/issues/14774"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Feature]: Reducing dependencies",
              "url": "https://github.com/puppeteer/puppeteer/issues/13552"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "[Feature]: Make proxy-agent dependency optional",
              "url": "https://github.com/puppeteer/puppeteer/issues/13775"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Puppeteer v25",
              "url": "https://github.com/puppeteer/puppeteer/issues/14342"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "puppeteer-core: v25.0.2",
              "url": "https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "browsers: v3.0.2",
              "url": "https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "puppeteer-core: v25.0.1",
              "url": "https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.1"
            }
          ],
          "status": "已收录 12 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "软件开发与交付",
      "desc": "JavaScript API for Chrome and Firefox",
      "effort": "安装已验证",
      "forks": 9416,
      "icon": "code",
      "name": "puppeteer 能力包",
      "risk": "可发布",
      "slug": "puppeteer",
      "stars": 94330,
      "tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "浏览器自动化",
        "节点式流程编排",
        "评测体系"
      ],
      "thumb": "gray",
      "type": "Skill Pack"
    },
    "manual": {
      "markdown": "# https://github.com/puppeteer/puppeteer 项目说明书\n\n生成时间：2026-05-16 04:41:15 UTC\n\n## 目录\n\n- [Puppeteer项目概览](#page-overview)\n- [安装与入门指南](#page-installation)\n- [Puppeteer系统架构](#page-architecture)\n- [协议实现：CDP与WebDriver BiDi](#page-protocols)\n- [浏览器启动与管理](#page-browser-management)\n- [Page页面操作API](#page-page-api)\n- [元素定位器与操作](#page-element-locator)\n- [网络请求拦截与管理](#page-network)\n- [浏览器上下文与扩展支持](#page-contexts-extensions)\n- [覆盖率检测与调试功能](#page-coverage-debugging)\n\n<a id='page-overview'></a>\n\n## Puppeteer项目概览\n\n### 相关页面\n\n相关主题：[Puppeteer系统架构](#page-architecture), [安装与入门指南](#page-installation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/puppeteer/puppeteer/blob/main/README.md)\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n- [packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n- [packages/browsers/README.md](https://github.com/puppeteer/puppeteer/blob/main/packages/browsers/README.md)\n- [examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n</details>\n\n# Puppeteer项目概览\n\n## 1. 项目简介\n\nPuppeteer是一个由Google维护的Node.js库，它提供了高级API来通过[Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/)控制无头Chrome或Chromium浏览器。Puppeteer本质上是Chrome浏览器的自动化工具，允许开发者以编程方式执行通常需要手动操作的任务。\n\n### 1.1 核心功能\n\n| 功能类别 | 说明 |\n|---------|------|\n| 页面导航 | 加载网页、访问URL、处理导航事件 |\n| 内容抓取 | 提取页面DOM、获取元素内容、截图 |\n| 用户交互 | 模拟键盘输入、鼠标点击、表单提交 |\n| 性能监控 | 跟踪网络请求、测量页面性能 |\n| 设备模拟 | 模拟移动设备、iPhone、Android等 |\n| 浏览器扩展 | 支持加载Chrome扩展程序 |\n\n资料来源：[README.md:1-15]()\n\n## 2. 项目架构\n\nPuppeteer采用monorepo架构，主要由核心包和配套工具组成。\n\n### 2.1 核心包结构\n\n```mermaid\ngraph TD\n    A[Puppeteer] --> B[puppeteer-core]\n    A --> C[@puppeteer/browsers]\n    A --> D[@puppeteer/ng-schematics]\n    \n    B --> E[API层]\n    B --> F[CDP通信层]\n    B --> G[公共组件]\n    \n    E --> H[Page]\n    E --> I[Browser]\n    E --> J[BrowserContext]\n    \n    G --> K[Configuration]\n    G --> L[Device]\n    G --> M[LazyArg]\n    G --> N[Debug]\n```\n\n### 2.2 主要包说明\n\n| 包名 | 用途 |\n|------|------|\n| `puppeteer` | 完整包，包含浏览器下载功能 |\n| `puppeteer-core` | 轻量级核心库，不自动下载浏览器 |\n| `@puppeteer/browsers` | 浏览器管理和下载CLI工具 |\n| `@puppeteer/ng-schematics` | Angular集成工具 |\n\n资料来源：[README.md:1-10]()\n\n## 3. 安装与配置\n\n### 3.1 安装方式\n\n```bash\n# 完整安装（自动下载Chrome）\nnpm i puppeteer\n\n# 仅安装核心库（不下载浏览器）\nnpm i puppeteer-core\n```\n\n### 3.2 启动选项配置\n\nPuppeteer支持丰富的浏览器启动配置选项：\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `executablePath` | `string` | - | 指定浏览器可执行文件路径 |\n| `ignoreDefaultArgs` | `boolean \\| string[]` | `false` | 是否忽略默认启动参数 |\n| `enableExtensions` | `boolean \\| string[]` | - | 启用Chrome扩展 |\n| `handleSIGINT` | `boolean` | `true` | Ctrl+C时关闭浏览器 |\n| `handleSIGTERM` | `boolean` | `true` | SIGTERM时关闭浏览器 |\n| `handleSIGHUP` | `boolean` | `true` | SIGHUP时关闭浏览器 |\n| `timeout` | `number` | `30000` | 启动超时时间(毫秒) |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:1-50]()\n\n### 3.3 全局配置\n\nConfiguration接口定义了全局配置选项：\n\n```typescript\ninterface Configuration {\n  defaultBrowser?: SupportedBrowser;\n  temporaryDirectory?: string;\n  skipDownload?: boolean;\n  logLevel?: 'silent' | 'error' | 'warn';\n  experiments?: ExperimentsConfiguration;\n  chrome?: ChromeSettings;\n  firefox?: FirefoxSettings;\n}\n```\n\n| 配置项 | 说明 |\n|--------|------|\n| `defaultBrowser` | 默认浏览器类型，默认`chrome` |\n| `temporaryDirectory` | 临时文件目录，默认为`os.tmpdir()` |\n| `skipDownload` | 安装时跳过浏览器下载 |\n| `logLevel` | 日志级别，默认`warn` |\n| `chrome` | Chrome特定配置 |\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:1-40]()\n\n## 4. 核心API\n\n### 4.1 Page类\n\nPage类是Puppeteer最核心的类，继承自EventEmitter，负责页面操作和交互。\n\n```mermaid\ngraph LR\n    A[Page] --> B[事件监听]\n    A --> C[页面导航]\n    A --> D[元素查询]\n    A --> E[函数暴露]\n```\n\n#### 4.1.1 常用方法\n\n| 方法 | 说明 |\n|------|------|\n| `goto(url)` | 导航到指定URL |\n| `waitForSelector(selector)` | 等待元素出现 |\n| `click(selector)` | 点击元素 |\n| `type(selector, text)` | 输入文本 |\n| `evaluate(fn)` | 在页面上下文执行JavaScript |\n| `screenshot()` | 页面截图 |\n| `setViewport()` | 设置视口大小 |\n\n#### 4.1.2 事件系统\n\nPage类继承EventEmitter模式，支持以下典型事件：\n\n```typescript\npage.once('load', () => console.log('Page loaded!'));\n\nfunction logRequest(interceptedRequest) {\n  console.log('A request was made:', interceptedRequest.url());\n}\npage.on('request', logRequest);\npage.off('request', logRequest);\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:1-80]()\n\n### 4.2 exposeFunction方法\n\nexposeFunction允许将Node.js函数暴露给浏览器页面调用：\n\n```typescript\npage.exposeFunction('readfile', async filePath => {\n  return fs.readFile(filePath, 'utf8');\n});\n\nawait page.evaluate(async () => {\n  const content = await window.readfile('/etc/hosts');\n  console.log(content);\n});\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:100-140]()\n\n### 4.3 Locators API\n\nLocators是实验性的定位器API，提供更可靠的元素定位方式：\n\n```typescript\n// 使用ARIA文本定位\nawait page.locator('::-p-aria(Search)').fill('automate beyond recorder');\n\n// 使用文本内容定位\nawait page.locator('::-p-text(Customize and automate)').waitHandle();\n\n// 使用组合选择器\nawait page.locator('.devsite-result-item-link').click();\n```\n\n## 5. 设备模拟\n\nPuppeteer内置了丰富的设备模拟功能，通过KnownDevices对象提供：\n\n```typescript\nimport {KnownDevices} from 'puppeteer';\n\nconst iPhone = KnownDevices['iPhone 15 Pro'];\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\nawait page.emulate(iPhone);\n```\n\n| 设备类别 | 示例设备 |\n|---------|---------|\n| iPhone系列 | iPhone 12, iPhone 15 Pro |\n| iPad系列 | iPad Mini, iPad Pro |\n| Android | Android Phone, Android Tablet |\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts:1-30]()\n\n## 6. @puppeteer/browsers CLI\n\n@puppeteer/browsers包提供浏览器管理的命令行工具：\n\n### 6.1 常用命令\n\n```bash\n# 安装Chrome稳定版\nnpx @puppeteer/browsers install chrome@stable\n\n# 安装指定版本\nnpx @puppeteer/browsers install chrome@116.0.5793.0\n\n# 安装ChromeDriver\nnpx @puppeteer/browsers install chromedriver@canary\n\n# 列出已安装浏览器\nnpx @puppeteer/browsers list\n\n# 清除所有已安装浏览器\nnpx @puppeteer/browsers clear\n```\n\n### 6.2 系统要求\n\n| 平台 | 依赖 |\n|------|------|\n| Linux/MacOS | `unzip` |\n| Windows | `tar.exe` |\n| Firefox下载(Linux) | `xz`, `bzip2` |\n| Firefox下载(MacOS) | `hdiutil` |\n\n资料来源：[packages/browsers/README.md:1-60]()\n\n## 7. 工作流程示例\n\n### 7.1 基础使用流程\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[创建页面]\n    B --> C[设置视口]\n    C --> D[导航到URL]\n    D --> E[执行操作]\n    E --> F[提取数据]\n    F --> G[关闭浏览器]\n    \n    D -.->|网络请求| H[request事件]\n    E -.->|控制台| I[console事件]\n    F -.->|截图| J[screenshot]\n```\n\n### 7.2 完整示例代码\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\nawait page.setViewport({width: 1080, height: 1024});\nawait page.goto('https://developer.chrome.com/');\n\nawait page.keyboard.press('/');\nawait page.locator('::-p-aria(Search)').fill('automate beyond recorder');\nawait page.locator('.devsite-result-item-link').click();\n\nconst textSelector = await page\n  .locator('::-p-text(Customize and automate)')\n  .waitHandle();\nconst fullTitle = await textSelector?.evaluate(el => el.textContent);\n\nconsole.log('The title of this blog post is \"%s\".', fullTitle);\n\nawait browser.close();\n```\n\n资料来源：[README.md:15-40]()\n\n## 8. 调试功能\n\nPuppeteer提供内置调试支持，通过`__PUPPETEER_DEBUG`环境变量控制：\n\n```bash\n# 开启所有日志\nwindow.__PUPPETEER_DEBUG='*';\n\n# 仅记录Page通道\nwindow.__PUPPETEER_DEBUG='Page';\n\n# 记录所有以Page开头的通道\nwindow.__PUPPETEER_DEBUG='Page*';\n```\n\n调试输出示例：\n\n```typescript\nconst log = debug('Page');\nlog('new page created');\n// 输出: \"Page: new page created\"\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:1-30]()\n\n## 9. 项目组织结构\n\n```\npuppeteer/\n├── packages/\n│   ├── puppeteer-core/     # 核心API包\n│   │   └── src/\n│   │       ├── api/        # Page、Browser等API\n│   │       ├── cdp/        # Chrome DevTools Protocol通信\n│   │       └── common/     # 公共组件\n│   ├── browsers/           # 浏览器管理CLI\n│   └── ng-schematics/      # Angular集成\n├── examples/               # 示例代码\n├── docker/                 # Docker配置\n└── tools/                  # 开发工具(ESLint等)\n```\n\n## 10. 相关资源\n\n| 资源 | 链接 |\n|------|------|\n| 官方文档 | [pptr.dev](https://pptr.dev) |\n| 示例集合 | [pptr.dev/examples](https://pptr.dev/examples) |\n| 选择器指南 | [pptr.dev/guides/page-interactions#selectors](https://pptr.dev/guides/page-interactions#selectors) |\n| MCP支持 | [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) |\n| WebMCP | [pptr.dev/guides/webmcp](https://pptr.dev/guides/webmcp) |\n\n资料来源：[README.md:5-15](), [examples/README.md:1-20]()\n\n---\n\n<a id='page-installation'></a>\n\n## 安装与入门指南\n\n### 相关页面\n\n相关主题：[Puppeteer项目概览](#page-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer/install.mjs](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer/install.mjs)\n- [packages/puppeteer/src/install.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer/src/install.ts)\n- [docs/guides/installation.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/installation.md)\n- [docs/guides/getting-started.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/getting-started.md)\n- [examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n</details>\n\n# 安装与入门指南\n\n## 概述\n\nPuppeteer 是一个流行的 Node.js 库，它提供了高级 API 来通过 DevTools 协议控制 Chromium、Chrome 或 Firefox 浏览器。Puppeteer 主要用于网页自动化、网页抓取、生成截图、生成 PDF、测试 Web 应用等场景。\n\n本指南将详细介绍 Puppeteer 的安装方式、系统要求、浏览器配置以及快速入门方法，帮助开发者快速上手使用 Puppeteer。\n\n## 安装方式\n\n### 使用 npm 安装\n\nPuppeteer 提供两个主要的 npm 包，开发者可以根据需求选择合适的版本：\n\n| 包名 | 说明 | 适用场景 |\n|------|------|----------|\n| `puppeteer` | 完整版，包含浏览器下载功能 | 标准使用，需要自动下载 Chrome |\n| `puppeteer-core` | 精简版，不包含浏览器 | 已在环境中安装浏览器，或使用自定义浏览器 |\n\n标准安装命令如下：\n\n```bash\nnpm i puppeteer\n```\n\n此命令会在安装过程中自动下载与 Puppeteer 版本兼容的 Chrome 浏览器。\n\n如果只需要将 Puppeteer 作为库使用，而不包含浏览器：\n\n```bash\nnpm i puppeteer-core\n```\n\n资料来源：[README.md:Installation]()\n\n### 使用 puppeteer-core 的注意事项\n\n使用 `puppeteer-core` 时，需要在 `puppeteer.launch()` 方法中通过 `executablePath` 参数指定浏览器可执行文件路径：\n\n```typescript\nimport puppeteer from 'puppeteer-core';\n\nconst browser = await puppeteer.launch({\n  executablePath: '/path/to/chromium',\n  // 其他配置选项\n});\n```\n\n## 系统要求\n\n### Node.js 版本要求\n\nPuppeteer 对 Node.js 版本有特定要求，具体版本信息请参考 `package.json` 中的 `engines` 字段。建议使用 LTS（长期支持）版本的 Node.js 以确保稳定性。\n\n资料来源：[packages/browsers/README.md:1-10]()\n\n### 浏览器下载的系统依赖\n\n不同的浏览器下载需要不同的系统工具支持：\n\n#### Firefox 下载要求\n\n| 操作系统 | 必需工具 |\n|----------|----------|\n| Linux | `xz` 和 `bzip2` 工具（用于解压 `.tar.gz` 和 `.tar.bz2` 归档文件）|\n| macOS | `hdiutil`（用于解压 `.dmg` 归档文件）|\n\n#### Chrome 下载要求\n\n| 操作系统 | 必需工具 |\n|----------|----------|\n| Linux/macOS | `unzip` |\n| Windows | `tar.exe` |\n\n资料来源：[packages/browsers/README.md:System requirements]()\n\n## 浏览器管理\n\n### @puppeteer/browsers 包\n\n`@puppeteer/browsers` 是官方提供的浏览器管理工具，支持从命令行界面（CLI）或编程方式管理浏览器和驱动。\n\n### 核心命令\n\n#### 安装浏览器\n\n```bash\n# 下载最新的 Stable 频道 Chrome for Testing\nnpx @puppeteer/browsers install chrome@stable\n\n# 下载指定版本的 Chrome for Testing\nnpx @puppeteer/browsers install chrome@116.0.5793.0\n\n# 下载指定里程碑的最新版本\nnpx @puppeteer/browsers install chrome@117\n\n# 下载最新的 ChromeDriver（Canary 频道）\nnpx @puppeteer/browsers install chromedriver@canary\n\n# 下载指定版本的 ChromeDriver\nnpx @puppeteer/browsers install chromedriver@116\n```\n\n#### 列出已安装的浏览器\n\n```bash\nnpx @puppeteer/browsers list\n```\n\n#### 清除所有已安装的浏览器\n\n```bash\nnpx @puppeteer/browsers clear\n```\n\n#### 获取帮助信息\n\n```bash\n# 获取所有命令的帮助\nnpx @puppeteer/browsers --help\n\n# 获取特定命令的帮助\nnpx @puppeteer/browsers install --help\nnpx @puppeteer/browsers launch --help\n```\n\n### 版本指定方式\n\n| 指定方式 | 示例 | 说明 |\n|----------|------|------|\n| `latest` | `chrome@latest` | 下载最新稳定版 |\n| 里程碑版本 | `chrome@117` | 下载该里程碑的最新版本 |\n| 完整版本号 | `chrome@116.0.5793.0` | 下载指定精确版本 |\n| 频道 | `chromedriver@canary` | 下载指定频道的最新版本 |\n\n资料来源：[packages/browsers/README.md:CLI]()\n\n### 浏览器管理 API\n\n除了 CLI，还可以编程方式使用 `@puppeteer/browsers`：\n\n```typescript\nimport {install, launch, clear, list} from '@puppeteer/browsers';\n\n// 列出已安装的浏览器\nconst installed = await list({});\n\n// 安装浏览器\nawait install({\n  browser: 'chrome',\n  channel: 'stable',\n});\n\n// 启动浏览器\nconst process = await launch({\n  browser: 'chrome',\n  channel: 'stable',\n});\n```\n\n## 快速入门\n\n### 基本示例\n\n以下是一个完整的 Puppeteer 使用示例，展示了打开浏览器、导航到网页、模拟用户交互的基本流程：\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nasync function main() {\n  // 启动浏览器并打开新的空白页\n  const browser = await puppeteer.launch();\n  const page = await browser.newPage();\n\n  // 导航到目标 URL\n  await page.goto('https://developer.chrome.com/');\n\n  // 设置视口大小\n  await page.setViewport({width: 1080, height: 1024});\n\n  // 使用键盘按下搜索菜单快捷键\n  await page.keyboard.press('/');\n\n  // 使用可访问的输入框名称填写搜索内容\n  await page.locator('::-p-aria(Search)').fill('automate beyond recorder');\n\n  // 等待并点击第一个搜索结果\n  await page.locator('.devsite-result-item-link').click();\n\n  // 使用文本定位器获取元素句柄\n  const textSelector = await page\n    .locator('::-p-text(Customize and automate)')\n    .waitHandle();\n\n  // 获取元素的文本内容\n  const fullTitle = await textSelector?.evaluate(el => el.textContent);\n\n  // 打印结果\n  console.log('The title of this blog post is \"%s\".', fullTitle);\n\n  // 关闭浏览器\n  await browser.close();\n}\n\nmain();\n```\n\n资料来源：[README.md:Example]()\n\n### 核心概念说明\n\n#### 浏览器实例（Browser）\n\n通过 `puppeteer.launch()` 创建浏览器实例，这是所有浏览器操作的基础。\n\n```typescript\nconst browser = await puppeteer.launch({\n  headless: true,      // 是否使用无头模式\n  args: ['--no-sandbox'],  // 浏览器启动参数\n  timeout: 30000,      // 启动超时时间（毫秒）\n});\n```\n\n#### 页面（Page）\n\n通过 `browser.newPage()` 创建新的页面实例，Page 类继承自 EventEmitter，支持丰富的事件机制：\n\n```typescript\npage.on('console', msg => console.log('PAGE LOG:', msg.text()));\npage.on('request', request => console.log('REQUEST:', request.url()));\npage.on('load', () => console.log('Page loaded!'));\n```\n\n#### 定位器（Locator）\n\nPuppeteer 推荐使用 Locator API 进行元素定位和交互，Locator 提供了更强大的等待和重试机制：\n\n```typescript\n// 使用文本内容定位\nawait page.locator('::-p-text(Submit)').click();\n\n// 使用 ARIA 属性定位\nawait page.locator('::-p-aria(Search)').fill('query');\n\n// 使用 CSS 选择器定位\nawait page.locator('.button.primary').click();\n```\n\n#### 元素操作\n\n| 操作 | 方法 | 说明 |\n|------|------|------|\n| 点击 | `locator.click()` | 单击元素 |\n| 输入 | `locator.fill()` | 填充输入框 |\n| 获取文本 | `evaluate(el => el.textContent)` | 获取元素文本 |\n| 获取属性 | `locator.getAttribute()` | 获取元素属性值 |\n| 截图 | `page.screenshot()` | 截取页面截图 |\n| 生成 PDF | `page.pdf()` | 生成 PDF 文档 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:$$eval]()\n\n## 运行示例项目\n\n### 环境准备\n\n1. **克隆仓库并安装依赖**\n\n```bash\ngit clone https://github.com/puppeteer/puppeteer.git\ncd puppeteer\nnpm install\n```\n\n2. **构建 Puppeteer**\n\n```bash\nnpm run build\n```\n\n### 运行单个示例\n\n构建完成后，使用以下命令运行单个示例脚本：\n\n```bash\nNODE_PATH=../ node examples/search.js\n```\n\n示例脚本位于 `examples/` 目录下，提供了多种使用场景的参考实现，包括网页搜索、截图、PDF 生成等功能。\n\n资料来源：[examples/README.md:Run]()\n\n## 选择器语法参考\n\n### Puppeteer 专用选择器\n\n| 选择器类型 | 语法格式 | 示例 |\n|------------|----------|------|\n| 文本选择器 | `::-p-text(<文本>)` | `page.locator('::-p-text(Submit)')` |\n| ARIA 选择器 | `::-p-aria(<角色>[name=<名称>])` | `page.locator('::-p-aria(Button)')` |\n| XPath 选择器 | `::-p-xpath(<xpath>)` | `page.locator('::-p-xpath(//button)')` |\n| Shadow DOM | `>>> <选择器>` | `page.locator('>>> .custom-element')` |\n\n### Angular Schematics 选择器对照\n\n对于从 Angular/Protractor 迁移的用户，以下是选择器语法对照：\n\n| Protractor | Puppeteer |\n|------------|-----------|\n| `$(by.id('id'))` | `page.$('#id')` |\n| `$(by.cssContainingText('css', 'text'))` | `page.$('css ::-p-text(text)')` |\n| `$(by.deepCss('css'))` | `page.$(':scope >>> css')` |\n| `$(by.xpath('xpath'))` | `page.$('::-p-xpath(xpath)')` |\n\n资料来源：[packages/ng-schematics/README.md:Selectors]()\n\n## MCP 集成\n\nPuppeteer 支持 Model Context Protocol (MCP)，可以用于 AI 驱动的浏览器自动化：\n\n### 安装 chrome-devtools-mcp\n\n```bash\nnpm install chrome-devtools-mcp\n```\n\n### WebMCP 支持\n\nPuppeteer 还支持实验性的 WebMCP API，为基于 Web 的 AI 代理提供浏览器自动化能力。\n\n资料来源：[README.md:MCP]()\n\n## 故障排除\n\n### 常见安装问题\n\n#### 浏览器下载失败\n\n如果浏览器下载失败，可以尝试：\n\n1. 手动下载浏览器并使用 `executablePath` 指定路径\n2. 使用已安装系统的浏览器\n3. 检查网络连接和代理设置\n\n#### 权限错误\n\n在 Linux 或容器环境中，可能需要添加额外参数：\n\n```typescript\nconst browser = await puppeteer.launch({\n  args: ['--no-sandbox', '--disable-setuid-sandbox'],\n});\n```\n\n### 调试模式\n\n启用 Puppeteer 调试日志：\n\n```bash\n# 设置调试环境变量\nwindow.__PUPPETEER_DEBUG='*';  // 记录所有日志\nwindow.__PUPPETEER_DEBUG='Page';  // 只记录 Page 频道\nwindow.__PUPPETEER_DEBUG='foo*';  // 记录所有以 foo 开头的频道\n```\n\n在代码中使用调试日志：\n\n```typescript\nimport {debug} from '@puppeteer/puppeteer-core';\n\nconst log = debug('Page');\nlog('new page created');\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:Debug]()\n\n## 下一步\n\n完成安装和入门后，建议进一步了解以下内容：\n\n- **页面交互**：深入学习页面点击、表单填写、键盘输入等交互操作\n- **网络请求拦截**：掌握请求和响应的监控、修改和模拟\n- **性能分析**：使用 Puppeteer 进行页面性能测试和优化\n- **无头模式与有头模式**：了解不同模式下的使用场景和配置\n- **高级配置**：学习浏览器启动参数、代理设置、用户数据目录等高级特性\n\n如需更多示例和详细文档，请访问 [pptr.dev/examples](https://pptr.dev/examples)。\n\n---\n\n<a id='page-architecture'></a>\n\n## Puppeteer系统架构\n\n### 相关页面\n\n相关主题：[协议实现：CDP与WebDriver BiDi](#page-protocols), [Puppeteer项目概览](#page-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n- [packages/puppeteer-core/src/common/LazyArg.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/LazyArg.ts)\n- [packages/puppeteer-core/src/cdp/ExecutionContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ExecutionContext.ts)\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n- [packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts)\n- [packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n- [README.md](https://github.com/puppeteer/puppeteer/blob/main/README.md)\n</details>\n\n# Puppeteer系统架构\n\n## 概述\n\nPuppeteer是一个由Google维护的Node.js库，它提供了高级API来通过DevTools协议控制Chrome或Firefox浏览器。该项目的核心设计围绕浏览器自动化、网页抓取和性能监控等场景展开，采用分层架构以实现良好的模块化和可扩展性。\n\nPuppeteer的架构主要分为以下几个层次：\n\n| 层次 | 描述 | 主要模块 |\n|------|------|----------|\n| 用户API层 | 面向开发者的TypeScript/JavaScript接口 | Page、Browser、Frame |\n| 协议抽象层 | 封装浏览器通信协议 | CDP (Chrome DevTools Protocol) |\n| 核心引擎层 | 实现核心自动化逻辑 | puppeteer-core |\n| 节点运行时层 | Node.js环境特定功能 | LaunchOptions、PuppeteerNode |\n| 工具层 | 辅助功能 | 设备模拟、调试、配置管理 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:310-320]()\n\n## 核心模块架构\n\n### 1. 包结构\n\nPuppeteer项目采用monorepo结构，主要包含以下npm包：\n\n| 包名 | 用途 |\n|------|------|\n| `puppeteer` | 完整的Puppeteer包，包含浏览器下载 |\n| `puppeteer-core` | 核心库，不包含浏览器二进制文件 |\n| `@puppeteer/browsers` | 浏览器管理和启动CLI工具 |\n| `@puppeteer/ng-schematics` | Angular schematics集成 |\n\n资料来源：[README.md:1-10]()\n\n### 2. Page类架构\n\n`Page`是Puppeteer中最核心的类之一，它继承自`EventEmitter`并提供了丰富的浏览器页面操作能力。\n\n```mermaid\ngraph TD\n    EventEmitter --> Page\n    Page --> |extends| CDPPage\n    Page --> |extends| WebDriverPage\n    \n    Page --> |使用| TimeoutSettings\n    Page --> |管理| RequestHandlers\n    Page --> |发出| PageEvents\n    \n    subgraph \"Page核心功能\"\n        exposeFunction\n        evaluate\n        goto\n        setContent\n        locator\n    end\n```\n\n**Page类的关键内部状态**：\n\n```typescript\nabstract class Page extends EventEmitter<PageEvents> {\n  _isDragging = false;                    // 拖拽状态\n  _timeoutSettings = new TimeoutSettings(); // 超时设置\n  _tabId = '';                            // 标签页标识符\n  #requestHandlers = new WeakMap<>();    // 请求处理器\n  #inflight$ = new ReplaySubject<number>(1); // 进行中的请求\n}\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:290-305]()\n\n### 3. 抽象设计与实现分离\n\nPuppeteer采用了抽象基类的设计模式，定义了清晰的接口契约。这种设计允许不同的协议实现共存：\n\n```mermaid\ngraph LR\n    subgraph \"抽象层\"\n        Page\n        Browser\n        Frame\n    end\n    \n    subgraph \"CDP实现\"\n        CDPPage\n        CDPBrowser\n        CDPFrame\n    end\n    \n    subgraph \"WebDriver实现\"\n        WebDriverPage\n        WebDriverBrowser\n        WebDriverFrame\n    end\n    \n    Page --> CDPPage\n    Page --> WebDriverPage\n```\n\n## 配置系统\n\n### Configuration接口\n\nPuppeteer提供了灵活的配置系统，支持多种自定义选项：\n\n```typescript\ninterface Configuration {\n  defaultBrowser?: SupportedBrowser;     // 默认浏览器\n  temporaryDirectory?: string;           // 临时目录\n  skipDownload?: boolean;               // 跳过下载\n  logLevel?: 'silent' | 'error' | 'warn'; // 日志级别\n  experiments?: ExperimentsConfiguration; // 实验性选项\n  chrome?: ChromeSettings;              // Chrome特定设置\n  firefox?: FirefoxSettings;            // Firefox特定设置\n}\n```\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:30-60]()\n\n### 环境变量覆盖\n\n配置选项可以通过环境变量进行覆盖：\n\n| 配置属性 | 环境变量 | 默认值 |\n|----------|----------|--------|\n| `temporaryDirectory` | `PUPPETEER_TMP_DIR` | `os.tmpdir()` |\n| `skipDownload` | `PUPPETEER_SKIP_DOWNLOAD` | `false` |\n| Chrome `skipDownload` | `PUPPETEER_CHROME_SKIP_DOWNLOAD` | `false` |\n| Chrome `downloadBaseUrl` | `PUPPETEER_CHROME_DOWNLOAD_BASE_URL` | `storage.googleapis.com` |\n\n## 执行上下文与代码注入\n\n### ExecutionContext执行上下文\n\nPuppeteer通过`ExecutionContext`类封装了CDP的`Runtime.evaluate`和`Runtime.callFunctionOn`方法：\n\n```mermaid\nsequenceDiagram\n    用户代码 ->> Page: evaluate(pageFunction)\n    Page ->> ExecutionContext: evaluate(pageFunction)\n    ExecutionContext ->> CDPClient: Runtime.evaluate\n    CDPClient -->> ExecutionContext: remoteObject\n    ExecutionContext ->> ExecutionContext: createCdpHandle\n    ExecutionContext -->> 用户代码: JSHandle\n```\n\n**核心评估逻辑**：\n\n```typescript\n// 处理字符串表达式\nif (isString(pageFunction)) {\n  const expressionWithSourceUrl = `${expression}\\n${sourceUrlComment}\\n`;\n  const {exceptionDetails, result: remoteObject} = await client.send(\n    'Runtime.evaluate', {\n      expression: expressionWithSourceUrl,\n      contextId,\n      returnByValue,\n      awaitPromise: true,\n      userGesture: true,\n    }\n  );\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/ExecutionContext.ts:45-75]()\n\n### LazyArg延迟参数机制\n\n`LazyArg`是Puppeteer用于在页面上下文中延迟解析参数的机制：\n\n```typescript\nclass LazyArg<T, Context = PuppeteerUtilWrapper> {\n  static create = <T>(\n    get: (context: PuppeteerUtilWrapper) => Promise<T> | T\n  ): T => {\n    return new LazyArg(get) as unknown as T;\n  };\n\n  async get(context: Context): Promise<T> {\n    return await this.#get(context);\n  }\n}\n```\n\n这个机制确保了传递给页面函数的参数在被实际使用时才进行求值，避免了闭包捕获问题。\n\n资料来源：[packages/puppeteer-core/src/common/LazyArg.ts:20-35]()\n\n## 设备模拟系统\n\n### KnownDevices预定义设备\n\nPuppeteer内置了丰富的设备模拟配置，通过`KnownDevices`对象提供：\n\n```typescript\nexport const KnownDevices = Object.freeze(knownDevicesByName);\n```\n\n支持的设备包括各种iPhone、Android设备和桌面浏览器的预设配置，涵盖视口尺寸、用户代理字符串和触摸能力等属性。\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts:180-190]()\n\n### 设备模拟使用流程\n\n```mermaid\ngraph LR\n    A[获取设备配置] --> B[创建Browser]\n    B --> C[创建Page]\n    C --> D[page.emulate]\n    D --> E[导航到目标URL]\n```\n\n## 启动选项与浏览器管理\n\n### LaunchOptions启动配置\n\n`LaunchOptions`接口定义了浏览器启动时的各项参数：\n\n| 选项 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `executablePath` | `string` | - | 使用指定的浏览器可执行文件 |\n| `ignoreDefaultArgs` | `boolean \\| string[]` | `false` | 忽略默认启动参数 |\n| `enableExtensions` | `boolean \\| string[]` | - | 启用浏览器扩展 |\n| `handleSIGINT` | `boolean` | `true` | Ctrl+C关闭浏览器 |\n| `handleSIGTERM` | `boolean` | `true` | SIGTERM关闭浏览器 |\n| `handleSIGHUP` | `boolean` | `true` | SIGHUP关闭浏览器 |\n| `timeout` | `number` | `30000` | 启动超时(ms) |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:25-60]()\n\n### 信号处理机制\n\nPuppeteer实现了健壮的进程信号处理：\n\n```mermaid\ngraph TD\n    SIGINT --> handleSIGINT --> browser.close\n    SIGTERM --> handleSIGTERM --> browser.close\n    SIGHUP --> handleSIGHUP --> browser.close\n```\n\n## 调试系统\n\n### Debug模块架构\n\nPuppeteer提供了灵活的调试日志系统，支持Node.js和浏览器环境：\n\n```typescript\nexport const debug = (prefix: string): ((...args: unknown[]) => void) => {\n  if (isNode) {\n    return async (...logArgs: unknown[]) => {\n      if (captureLogs) {\n        capturedLogs.push(prefix + logArgs);\n      }\n      (await importDebug())(prefix)(logArgs);\n    };\n  }\n  \n  return (...logArgs: unknown[]): void => {\n    // 浏览器环境使用console.log\n    console.log(`${prefix}:`, ...logArgs);\n  };\n};\n```\n\n### 调试通道配置\n\n通过`window.__PUPPETEER_DEBUG`环境变量控制调试输出：\n\n| 值 | 行为 |\n|----|------|\n| `'*'` | 记录所有通道 |\n| `'Page'` | 仅记录Page通道 |\n| `'Page*'` | 记录所有以Page开头的通道 |\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:30-60]()\n\n## 事件系统\n\n### PageEvent事件类型\n\nPage类继承自`EventEmitter`，使用标准的事件发布-订阅模式：\n\n```typescript\n// 订阅事件\npage.on('request', logRequest);\n\n// 取消订阅\npage.off('request', logRequest);\n\n// 单次事件监听\npage.once('load', () => console.log('Page loaded!'));\n```\n\n常见的页面事件包括：`load`、`domcontentloaded`、`request`、`response`、`console`等。\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:1-50]()\n\n## 查询选择器系统\n\nPuppeteer支持多种选择器类型，实现灵活的元素定位：\n\n| 选择器类型 | 语法示例 | 描述 |\n|------------|----------|------|\n| CSS选择器 | `page.$('div.class')` | 标准CSS选择器 |\n| ARIA选择器 | `::-p-aria(Search)` | 无障碍角色和名称 |\n| 文本选择器 | `::-p-text(Submit)` | 按文本内容匹配 |\n| XPath选择器 | `::-p-xpath(//button)` | XPath表达式 |\n| Pierce选择器 | `::p-deep(div)` | 穿透Shadow DOM |\n\n资料来源：[packages/ng-schematics/README.md:40-60]()\n\n## 典型工作流程\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[创建新页面]\n    B --> C[设置视口和用户代理]\n    C --> D[导航到URL]\n    D --> E[执行自动化操作]\n    E --> F{是否需要交互}\n    F -->|是| G[执行交互操作]\n    G --> H[等待条件满足]\n    H --> E\n    F -->|否| I[提取数据]\n    I --> J[关闭浏览器]\n```\n\n## 安全考虑\n\n### 沙箱模式\n\nDocker运行Puppeteer时需要特殊权限：\n\n```bash\ndocker run -i --init --rm --cap-add=SYS_ADMIN \\\n  --name puppeteer-chrome puppeteer-chrome-linux \\\n  node -e \"...\"\n```\n\n`--cap-add=SYS_ADMIN`用于启用Chrome沙箱安全机制，或使用`--no-sandbox`标志禁用沙箱。\n\n资料来源：[docker/README.md:15-25]()\n\n## 总结\n\nPuppeteer的系统架构体现了以下设计原则：\n\n1. **抽象与实现分离**：通过抽象基类支持CDP和WebDriver等多种协议实现\n2. **模块化设计**：核心功能与特定运行时环境解耦\n3. **灵活的配置系统**：支持代码配置和环境变量覆盖\n4. **事件驱动架构**：基于EventEmitter的统一事件系统\n5. **跨平台支持**：同时支持Node.js和浏览器环境的调试能力\n\n这种架构使得Puppeteer能够适应各种复杂的浏览器自动化场景，同时保持代码的可维护性和可扩展性。\n\n---\n\n<a id='page-protocols'></a>\n\n## 协议实现：CDP与WebDriver BiDi\n\n### 相关页面\n\n相关主题：[Puppeteer系统架构](#page-architecture), [Page页面操作API](#page-page-api)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/cdp/Browser.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Browser.ts)\n- [packages/puppeteer-core/src/cdp/Connection.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Connection.ts)\n- [packages/puppeteer-core/src/bidi/Browser.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/Browser.ts)\n- [packages/puppeteer-core/src/bidi/Connection.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/Connection.ts)\n- [packages/puppeteer-core/src/bidi/core/core.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/core/core.ts)\n- [docs/webdriver-bidi.md](https://github.com/puppeteer/puppeteer/blob/main/docs/webdriver-bidi.md)\n- [packages/puppeteer-core/src/bidi/core/README.md](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/core/README.md)\n</details>\n\n# 协议实现：CDP与WebDriver BiDi\n\n## 概述\n\nPuppeteer 同时支持两种浏览器自动化协议：**CDP（Chrome DevTools Protocol）** 和 **WebDriver BiDi（WebDriver Bi-Directional）**。这种双协议支持使 Puppeteer 能够提供跨浏览器兼容性和向后兼容性。\n\n| 协议 | 类型 | 支持浏览器 | 用途 |\n|------|------|-----------|------|\n| CDP | Chrome 专有 | Chrome、Chromium | 提供最完整的 Chrome 控制能力 |\n| WebDriver BiDi | W3C 标准 | Chrome、Firefox、Edge | 跨浏览器兼容性 |\n\n资料来源：[packages/puppeteer-core/src/node/PuppeteerNode.ts](packages/puppeteer-core/src/node/PuppeteerNode.ts)\n\n## 架构设计\n\n### 双协议架构\n\nPuppeteer 的协议实现采用分层架构，抽象层将底层协议细节与高级 API 解耦：\n\n```mermaid\ngraph TB\n    subgraph \"高级API层\"\n        P[Page]\n        B[Browser]\n        T[Target]\n    end\n    \n    subgraph \"协议抽象层\"\n        CDPA[CDP Browser]\n        BiDiA[BiDi Browser]\n    end\n    \n    subgraph \"连接层\"\n        CDPC[CDP Connection]\n        BiDiC[BiDi Connection]\n    end\n    \n    P --> CDPA\n    P --> BiDiA\n    B --> CDPA\n    B --> BiDiA\n    T --> CDPA\n    T --> BiDiA\n    \n    CDPA --> CDPC\n    BiDiA --> BiDiC\n```\n\n### CDP over BiDi 混合模式\n\n当使用 CDP 连接时，Puppeteer 可以选择性地将 BiDi 协议叠加在 CDP 连接之上：\n\n```typescript\nconst bidiOnly = process.env['PUPPETEER_WEBDRIVER_BIDI_ONLY'] === 'true';\nconst BiDi = await import('../bidi/bidi.js');\nconst bidiConnection = await BiDi.connectBidiOverCdp(cdpConnection);\n```\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:45-48](packages/puppeteer-core/src/node/BrowserLauncher.ts)\n\n## CDP 实现\n\n### CDP Browser\n\nCDP Browser 类负责管理基于 Chrome DevTools Protocol 的浏览器实例。CDP 协议提供对 Chrome 内部功能的深度控制，包括：\n\n- 完整的 JavaScript 执行环境\n- 网络请求拦截和修改\n- 性能分析\n- 页面截图和 PDF 生成\n- DOM 操作\n\n### CDP Connection\n\nCDP Connection 实现了基于 WebSocket 的 CDP 通信机制：\n\n| 组件 | 职责 |\n|------|------|\n| WebSocket 传输 | 底层双向通信 |\n| 命令分发 | 将 API 调用转换为 CDP 命令 |\n| 事件监听 | 转发浏览器事件到上层 |\n| 会话管理 | 管理多个 CDP 会话 |\n\nCDP 连接支持通过 `puppeteer.connect()` 方法进行远程连接，实现浏览器控制与浏览器进程的分离。\n\n## WebDriver BiDi 实现\n\n### BiDi 协议核心\n\nWebDriver BiDi 是 W3C 标准化的一种双向协议，设计目标是提供跨浏览器统一的自动化接口。Puppeteer 的 BiDi 实现位于 `packages/puppeteer-core/src/bidi/core/` 目录。\n\n#### 设计原则\n\nBiDi 核心实现遵循以下原则：\n\n1. **遵循规范**：`bidi/core` 严格遵循 WebDriver BiDi 规范，而非 Puppeteer 特定需求\n2. **全面性**：按图结构实现所有节点和边，不跳过任何中间步骤\n3. **最小化**：仅实现协议必需的功能，避免过度设计\n\n资料来源：[packages/puppeteer-core/src/bidi/core/README.md](packages/puppeteer-core/src/bidi/core/README.md)\n\n### BiDi Browser\n\nBiDi Browser 类提供基于 WebDriver BiDi 协议的浏览器控制：\n\n```typescript\nreturn await BiDi.BidiBrowser.create({\n  connection: bidiConnection,\n  // 当启用 BiDi-only 模式时不传递 CDP 连接\n  cdpConnection: bidiOnly ? undefined : cdpConnection,\n  closeCallback,\n  process: browserProcess.nodeProcess,\n  defaultViewport: opts.defaultViewport,\n  acceptInsecureCerts: opts.acceptInsecureCerts,\n  networkEnabled: opts.networkEnabled,\n  issuesEnabled: opts.issuesEnabled,\n});\n```\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:50-60](packages/puppeteer-core/src/node/BrowserLauncher.ts)\n\n### BiDi Connection\n\nBiDi Connection 负责 WebSocket 双向通信，处理 BiDi 协议的握手和消息传递。\n\n### BiDi Core 模块\n\n`bidi/core` 模块是 WebDriver BiDi 协议的纯规范实现：\n\n| 模块 | 功能 |\n|------|------|\n| core.ts | 协议核心逻辑、命令处理、事件分发 |\n| EventEmitter | 双向事件传输 |\n| Browsing Context | 浏览器上下文管理 |\n| Script | JavaScript 执行域 |\n\n#### 事件图结构\n\nBiDi 协议中的事件遵循严格的图结构。例如，导航事件必须按以下顺序触发：\n\n```\nfragment navigation → navigation → browsing context\n```\n\n不允许跳过中间节点，也不允许存在组合边（如同时存在上述路径和 `fragment navigation → browsing context`）。\n\n资料来源：[packages/puppeteer-core/src/bidi/core/README.md](packages/puppeteer-core/src/bidi/core/README.md)\n\n## 协议选择与配置\n\n### 环境变量控制\n\n| 环境变量 | 作用 | 值 |\n|----------|------|-----|\n| `PUPPETEER_WEBDRIVER_BIDI_ONLY` | 启用纯 BiDi 模式 | `true` 或 `false` |\n\n当 `PUPPETEER_WEBDRIVER_BIDI_ONLY=true` 时，Browser 对象不会持有 CDP 连接引用，强制使用 BiDi 端点：\n\n```typescript\ncdpConnection: bidiOnly ? undefined : cdpConnection,\n```\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:55](packages/puppeteer-core/src/node/BrowserLauncher.ts)\n\n### 启动配置\n\n通过 LaunchOptions 可自定义浏览器启动行为：\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| executablePath | 浏览器可执行文件路径 | 自动检测 |\n| ignoreDefaultArgs | 跳过默认参数 | false |\n| enableExtensions | 启用扩展支持 | false |\n| timeout | 启动超时(ms) | 30000 |\n| protocolTimeout | 协议超时(ms) | undefined |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts](packages/puppeteer-core/src/node/LaunchOptions.ts)\n\n## Target 抽象\n\nPuppeteer 通过 Target 抽象统一管理不同类型的浏览器目标：\n\n```mermaid\ngraph TD\n    T[Target 抽象]\n    CDPT[CDP Target]\n    BiDiT[BiDi Target]\n    \n    CDPT --> CDPT_Browser[CDP Browser Target]\n    CDPT --> CDPT_Page[CDP Page Target]\n    \n    BiDiT --> BiDiT_Browser[BiDi Browser Target]\n    BiDiT --> BiDiT_Page[BiDi Page Target]\n    \n    T --> CDPT\n    T --> BiDiT\n```\n\n### BiDi Target 实现\n\nBiDi Target 类体系包括：\n\n| 类 | 类型 | 说明 |\n|----|------|------|\n| BidiBrowserTarget | TargetType.BROWSER | 浏览器级别目标 |\n| BidiPageTarget | TargetType.PAGE | 页面级别目标 |\n| BidiFrameTarget | TargetType.FRAME | 帧级别目标 |\n| BidiWorkerTarget | TargetType.WORKER | Web Worker 目标 |\n\n```typescript\nexport class BidiBrowserTarget extends Target {\n  override type(): TargetType {\n    return TargetType.BROWSER;\n  }\n  override browser(): BidiBrowser {\n    return this.#browser;\n  }\n}\n```\n\n资料来源：[packages/puppeteer-core/src/bidi/Target.ts](packages/puppeteer-core/src/bidi/Target.ts)\n\n## 协议特性对比\n\n| 特性 | CDP | WebDriver BiDi |\n|------|-----|----------------|\n| 标准化程度 | Chrome 专有 | W3C 标准 |\n| 浏览器支持 | 仅 Chrome | Chrome、Firefox、Edge |\n| API 完整性 | 完整 | 部分功能 |\n| 跨浏览器兼容 | ✗ | ✓ |\n| 网络拦截 | 完整支持 | 基础支持 |\n| 性能分析 | 深度支持 | 有限支持 |\n| JavaScript 执行 | 完整上下文 | 受限沙箱 |\n\n## 使用场景建议\n\n### 选择 CDP 的场景\n\n- 需要完整的 Chrome 特性支持\n- 进行性能分析和调试\n- 需要精细的网络请求控制\n- 仅针对 Chrome/Chromium 环境\n\n### 选择 WebDriver BiDi 的场景\n\n- 需要跨浏览器兼容性\n- 遵循标准化协议要求\n- 与 Selenium 等工具集成\n- 测试环境包含多种浏览器\n\n## 扩展机制\n\n### 协议扩展\n\nPuppeteer 支持通过自定义 Provider 扩展浏览器下载和安装机制：\n\n```typescript\nimport {install} from '@puppeteer/browsers';\n\nawait install({\n  browser: Browser.CHROMEDRIVER,\n  cacheDir: './cache',\n  providers: [new CustomProvider()],\n});\n```\n\n资料来源：[packages/browsers/src/install.ts](packages/browsers/src/install.ts)\n\n## 总结\n\nPuppeteer 的双协议架构提供了灵活性和兼容性的平衡：\n\n1. **CDP 协议** 提供最深度的 Chrome 控制能力，适合需要高级功能的项目\n2. **WebDriver BiDi** 提供跨浏览器标准化接口，适合需要多浏览器支持的项目\n3. **混合模式** 允许在 CDP 连接上叠加 BiDi 协议，兼顾功能完整性和标准化\n4. **严格规范遵循** 确保 BiDi 实现的可移植性和正确性\n\n---\n\n<a id='page-browser-management'></a>\n\n## 浏览器启动与管理\n\n### 相关页面\n\n相关主题：[Puppeteer系统架构](#page-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/node/ChromeLauncher.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/ChromeLauncher.ts)\n- [packages/puppeteer-core/src/node/FirefoxLauncher.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/FirefoxLauncher.ts)\n- [packages/puppeteer-core/src/node/BrowserLauncher.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/BrowserLauncher.ts)\n- [packages/puppeteer-core/src/api/Browser.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Browser.ts)\n- [packages/puppeteer-core/src/api/BrowserContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/BrowserContext.ts)\n- [packages/browsers/src/launch.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/browsers/src/launch.ts)\n- [docs/guides/browser-management.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/browser-management.md)\n</details>\n\n# 浏览器启动与管理\n\n## 概述\n\nPuppeteer 的浏览器启动与管理模块是整个项目的核心组件之一，负责协调浏览器的生命周期、进程管理和资源分配。该模块通过抽象统一的 API，支持 Chrome、Firefox 等多种浏览器的启动、配置和销毁操作，同时提供细粒度的信号控制、超时管理和多上下文隔离机制。\n\n浏览器启动系统的设计遵循以下核心原则：\n\n- **跨平台兼容性**：统一处理不同操作系统（Linux、macOS、Windows）上的浏览器启动差异\n- **进程生命周期管理**：通过信号处理机制确保浏览器进程能够被正确终止\n- **可扩展性**：支持自定义可执行路径、浏览器参数和实验性功能配置\n- **资源隔离**：通过 BrowserContext 实现多浏览器上下文隔离\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:1-50]()\n\n## 架构设计\n\n### 核心组件关系\n\nPuppeteer 的浏览器启动架构采用分层设计，各层职责分明：\n\n```mermaid\ngraph TD\n    A[用户调用 puppeteer.launch] --> B[BrowserLauncher 抽象基类]\n    B --> C[ChromeLauncher]\n    B --> D[FirefoxLauncher]\n    C --> E[Chrome/Chromium 进程]\n    D --> F[Firefox 进程]\n    G[Configuration 配置] --> B\n    H[LaunchOptions 启动选项] --> B\n```\n\n| 层级 | 组件 | 职责 |\n|------|------|------|\n| 接口层 | `BrowserLauncher` | 定义浏览器启动的统一接口和流程 |\n| 实现层 | `ChromeLauncher` | 处理 Chrome/Chromium 特定启动逻辑 |\n| 实现层 | `FirefoxLauncher` | 处理 Firefox 特定启动逻辑 |\n| 配置层 | `Configuration` | 全局默认配置和浏览器特定设置 |\n| 选项层 | `LaunchOptions` | 用户指定的运行时启动参数 |\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts]()\n\n### 启动流程时序\n\n浏览器启动涉及多个阶段的协调操作：\n\n```mermaid\nsequenceDiagram\n    participant U as 用户代码\n    participant P as Puppeteer\n    participant L as BrowserLauncher\n    participant B as 浏览器进程\n    participant C as CDP/WebDriver\n    \n    U->>P: puppeteer.launch(options)\n    P->>L: 创建 Launcher 实例\n    L->>L: 解析配置和选项\n    L->>B: 启动浏览器进程\n    B-->>L: 进程已启动\n    L->>C: 建立连接\n    C-->>L: 连接就绪\n    L-->>P: 返回 Browser 实例\n    P-->>U: 返回 Browser 实例\n```\n\n资料来源：[packages/browsers/src/launch.ts:1-100]()\n\n## 支持的浏览器类型\n\n### 浏览器枚举\n\nPuppeteer 通过 `SupportedBrowser` 枚举定义支持的浏览器类型：\n\n| 枚举值 | 浏览器 | 说明 |\n|--------|--------|------|\n| `chrome` | Chrome for Testing | 默认浏览器，Puppeteer 主要支持的浏览器 |\n| `chrome-headless-shell` | Chrome Headless Shell | 无头 Chrome 精简版，体积更小 |\n| `firefox` | Firefox | Mozilla Firefox 浏览器 |\n\n配置接口中指定默认浏览器为 `chrome`：\n\n> Defines the default browser to use.\n>\n> @defaultValue `chrome`\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:1-50]()\n\n### 浏览器特定配置\n\n每种浏览器都有独立的配置命名空间：\n\n```typescript\ninterface Configuration {\n  chrome?: ChromeSettings;\n  ['chrome-headless-shell']?: ChromeHeadlessShellSettings;\n  firefox?: FirefoxSettings;\n}\n```\n\n**Chrome 设置参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `skipDownload` | `boolean` | `false` | 跳过浏览器下载 |\n| `downloadBaseUrl` | `string` | `https://storage.googleapis.com/chrome-for-testing-public` | 下载基础 URL |\n| `executablePath` | `string` | 自动推断 | 自定义可执行文件路径 |\n\n**Firefox 设置参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `skipDownload` | `boolean` | `true` | 跳过浏览器下载 |\n| `downloadBaseUrl` | `string` | `https://archive.mozilla.org/pub/firefox/releases` | 下载基础 URL |\n| `version` | `string` | Puppeteer 固定的版本 | 指定 Firefox 版本 |\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:50-150]()\n\n## 启动选项详解\n\n`LaunchOptions` 接口定义了启动浏览器时可配置的所有参数：\n\n### 基础配置参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `executablePath` | `string` | 捆绑浏览器 | 指定自定义浏览器可执行文件路径 |\n| `ignoreDefaultArgs` | `boolean \\| string[]` | `false` | 是否忽略默认参数或排除指定参数 |\n| `enableExtensions` | `boolean \\| string[]` | `false` | 启用扩展支持 |\n\n> If `true`, avoids passing default arguments to the browser that would prevent extensions from being enabled. Passing a list of strings will load the provided paths as unpacked extensions.\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:1-60]()\n\n### 进程信号控制\n\nPuppeteer 提供了完善的进程信号处理机制，确保在不同终止场景下浏览器进程能被正确关闭：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `handleSIGINT` | `boolean` | `true` | 接收到 `Ctrl+C` 时关闭浏览器 |\n| `handleSIGTERM` | `boolean` | `true` | 接收到 `SIGTERM` 信号时关闭浏览器 |\n| `handleSIGHUP` | `boolean` | `true` | 接收到 `SIGHUP` 信号时关闭浏览器 |\n\n### 超时配置\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `timeout` | `number` | `30_000` (30秒) | 浏览器启动超时时间（毫秒），设为 `0` 禁用超时 |\n\n> Maximum time in milliseconds to wait for the browser to start. Pass `0` to disable the timeout.\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:60-100]()\n\n### 其他启动参数\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `pipe` | `boolean` | 使用管道而非 WebSocket 连接 |\n| `dumpio` | `boolean` | 将浏览器 stdout/stderr 导出到进程 |\n| `userDataDir` | `string` | 用户数据目录（-profile 路径） |\n| `env` | `Record<string, string>` | 浏览器进程环境变量 |\n\n## Browser 类 API\n\n`Browser` 类是浏览器实例的抽象表示，封装了所有浏览器操作：\n\n### 核心方法\n\n| 方法 | 返回值 | 说明 |\n|------|--------|------|\n| `newPage()` | `Promise<Page>` | 创建新页面 |\n| `pages()` | `Promise<Page[]>` | 获取所有打开的页面 |\n| `createIncognitoBrowserContext()` | `Promise<BrowserContext>` | 创建私有浏览器上下文 |\n| `browserContexts()` | `BrowserContext[]` | 获取所有浏览器上下文 |\n| `version()` | `Promise<string>` | 获取浏览器版本 |\n| `process()` | `ChildProcess \\| null` | 获取浏览器进程对象 |\n| `close()` | `Promise<void>` | 关闭浏览器 |\n\n资料来源：[packages/puppeteer-core/src/api/Browser.ts:1-100]()\n\n### 浏览器进程管理\n\n通过 `process()` 方法可以访问底层的 Node.js 子进程：\n\n```typescript\nconst browser = await puppeteer.launch();\nconst proc = browser.process();\n\nif (proc) {\n  console.log(`Browser PID: ${proc.pid}`);\n  proc.kill(); // 强制终止\n}\n```\n\n### 版本检测\n\n```typescript\nconst browser = await puppeteer.launch();\nconst version = await browser.version();\nconsole.log(`Browser version: ${version}`);\n```\n\n## BrowserContext 浏览器上下文\n\n`BrowserContext` 提供了浏览器实例的隔离机制，类似于浏览器中的\"无痕模式\"：\n\n### 特性说明\n\n- 每个 BrowserContext 拥有独立的 cookie 存储\n- 每个 BrowserContext 拥有独立的会话存储\n- 不同 BrowserContext 之间的页面完全隔离\n- 共享进程但通过不同 CDP 会话隔离\n\n```mermaid\ngraph LR\n    A[Browser] --> B[BrowserContext A]\n    A --> C[BrowserContext B]\n    A --> D[BrowserContext C]\n    B --> E[Page 1]\n    B --> F[Page 2]\n    C --> G[Page 3]\n    D --> H[Page 4]\n    \n    style B fill:#e1f5fe\n    style C fill:#e1f5fe\n    style D fill:#e1f5fe\n```\n\n### 上下文 API\n\n| 方法 | 说明 |\n|------|------|\n| `createPage()` | 在当前上下文中创建新页面 |\n| `pages()` | 获取当前上下文中的所有页面 |\n| `close()` | 关闭浏览器上下文 |\n| `overridePermissions()` | 覆盖指定源的权限 |\n| `clearPermissionOverrides()` | 清除所有权限覆盖 |\n\n资料来源：[packages/puppeteer-core/src/api/BrowserContext.ts:1-80]()\n\n### 使用示例\n\n```typescript\n// 创建两个隔离的浏览器上下文\nconst context1 = await browser.createIncognitoBrowserContext();\nconst context2 = await browser.createIncognitoBrowserContext();\n\nconst page1 = await context1.newPage();\nconst page2 = await context2.newPage();\n\n// 两个页面的 cookie 完全隔离\nawait page1.goto('https://example.com');\nawait page2.goto('https://example.com');\n\n// 关闭上下文时释放资源\nawait context1.close();\n```\n\n## 生命周期管理\n\n### 启动阶段\n\n```mermaid\nflowchart TD\n    A[调用 launch] --> B{是否指定 executablePath}\n    B -->|是| C[验证可执行文件存在]\n    B -->|否| D[从缓存目录查找]\n    C --> E{文件存在?}\n    D --> E\n    E -->|否| F[抛出错误]\n    E -->|是| G[应用默认参数]\n    G --> H[启动子进程]\n    H --> I[建立 CDP 连接]\n    I --> J[等待浏览器就绪]\n    J --> K[返回 Browser 实例]\n```\n\n### 关闭阶段\n\n| 关闭方式 | 触发条件 | 行为 |\n|----------|----------|------|\n| 正常关闭 | 调用 `browser.close()` | 优雅关闭所有页面和上下文 |\n| SIGINT | `Ctrl+C` | 触发正常关闭流程 |\n| SIGTERM | 系统终止信号 | 触发正常关闭流程 |\n| SIGHUP | 终端挂起 | 触发正常关闭流程 |\n| 强制终止 | `process.exit()` | 浏览器进程可能残留 |\n\n### 错误处理\n\n浏览器启动失败时，Puppeteer 会根据失败原因抛出详细的错误信息：\n\n> Could not find Firefox (rev. ${browserVersion}). This can occur if either\n> 1. you did not perform an installation for Firefox before running the script (e.g. `npx puppeteer browsers install firefox`) or\n> 2. your cache path is incorrectly configured\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:80-100]()\n\n## 配置管理\n\n### 环境变量覆盖\n\nPuppeteer 支持通过环境变量覆盖配置：\n\n| 环境变量 | 配置属性 | 说明 |\n|----------|----------|------|\n| `PUPPETEER_SKIP_DOWNLOAD` | `skipDownload` | 跳过浏览器下载 |\n| `PUPPETEER_TMP_DIR` | `temporaryDirectory` | 临时文件目录 |\n| `PUPPETEER_CACHE_DIR` | `cacheDirectory` | 浏览器缓存目录 |\n| `PUPPETEER_CHROME_SKIP_DOWNLOAD` | `chrome.skipDownload` | 跳过 Chrome 下载 |\n| `PUPPETEER_FIREFOX_SKIP_DOWNLOAD` | `firefox.skipDownload` | 跳过 Firefox 下载 |\n\n### 配置文件方式\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nconst browser = await puppeteer.launch({\n  // 启动选项\n  timeout: 60000,\n  headless: true,\n  \n  // 浏览器特定配置\n  chrome: {\n    executablePath: '/custom/chrome/path',\n    args: ['--disable-dev-shm-usage']\n  }\n});\n```\n\n## 实际使用示例\n\n### 基础启动\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\nawait page.goto('https://example.com');\n\nawait browser.close();\n```\n\n### 自定义配置启动\n\n```typescript\nconst browser = await puppeteer.launch({\n  headless: false,\n  executablePath: '/path/to/chrome',\n  args: [\n    '--disable-gpu',\n    '--no-sandbox',\n    '--disable-setuid-sandbox',\n    '--disable-dev-shm-usage'\n  ],\n  timeout: 60000,\n  handleSIGINT: true,\n  handleSIGTERM: true\n});\n```\n\n### 多上下文隔离\n\n```typescript\nconst browser = await puppeteer.launch();\n\n// 用户 A 的上下文\nconst contextA = await browser.createIncognitoBrowserContext();\nconst pageA = await contextA.newPage();\nawait pageA.goto('https://login.example.com');\nawait pageA.type('#username', 'user_a');\n\n// 用户 B 的上下文\nconst contextB = await browser.createIncognitoBrowserContext();\nconst pageB = await contextB.newPage();\nawait pageB.goto('https://login.example.com');\nawait pageB.type('#username', 'user_b');\n\n// 独立验证，不会互相干扰\nawait Promise.all([\n  pageA.click('#submit'),\n  pageB.click('#submit')\n]);\n\nawait contextA.close();\nawait contextB.close();\nawait browser.close();\n```\n\n## 最佳实践\n\n### 资源管理\n\n1. **始终关闭浏览器**：使用 `try...finally` 或 `await browser.close()` 确保资源释放\n2. **限制页面数量**：避免创建过多页面导致资源耗尽\n3. **使用上下文隔离**：需要隔离操作时使用 `BrowserContext` 而非启动多个浏览器实例\n\n### 稳定性建议\n\n| 场景 | 推荐配置 |\n|------|----------|\n| Docker/容器环境 | 添加 `--no-sandbox`、`--disable-dev-shm-usage` 参数 |\n| CI/CD 环境 | 使用 `headless: true` 并设置合理的 `timeout` |\n| 资源受限环境 | 使用 `chrome-headless-shell` 减少内存占用 |\n| 需要扩展支持 | 设置 `enableExtensions` 为 `true` |\n\n### 调试技巧\n\n1. **查看浏览器日志**：`dumpio: true` 可捕获浏览器输出\n2. **使用自定义用户数据目录**：便于检查浏览器状态\n3. **禁用默认参数调试**：`ignoreDefaultArgs: true` 后手动添加所需参数\n\n## 相关命令\n\n### 浏览器管理 CLI\n\n通过 `@puppeteer/browsers` 包管理已安装的浏览器：\n\n```bash\n# 列出已安装的浏览器\nnpx @puppeteer/browsers list\n\n# 安装 Chrome Stable\nnpx @puppeteer/browsers install chrome@stable\n\n# 安装指定版本 Chrome\nnpx @puppeteer/browsers install chrome@116.0.5793.0\n\n# 安装最新 ChromeDriver\nnpx @puppeteer/browsers install chromedriver@canary\n\n# 清理所有已安装浏览器\nnpx @puppeteer/browsers clear\n```\n\n资料来源：[packages/browsers/README.md:1-80]()\n\n## 总结\n\nPuppeteer 的浏览器启动与管理模块通过统一的抽象层，优雅地解决了跨浏览器、跨平台的启动管理问题。其核心设计包括：\n\n- **统一接口**：`BrowserLauncher` 抽象基类为不同浏览器提供一致的操作体验\n- **灵活配置**：通过 `LaunchOptions` 和 `Configuration` 支持细粒度的参数控制\n- **进程安全**：完善的信号处理机制确保浏览器进程在各种场景下都能正确关闭\n- **上下文隔离**：`BrowserContext` 提供会话级隔离，适合多用户模拟场景\n- **错误友好**：详细的错误信息帮助开发者快速定位问题\n\n掌握这些机制，能够帮助开发者构建更加稳定、可靠的浏览器自动化应用。\n\n---\n\n<a id='page-page-api'></a>\n\n## Page页面操作API\n\n### 相关页面\n\n相关主题：[元素定位器与操作](#page-element-locator), [网络请求拦截与管理](#page-network)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/cdp/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Page.ts)\n- [packages/puppeteer-core/src/bidi/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/Page.ts)\n- [packages/puppeteer-core/src/api/Frame.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Frame.ts)\n- [docs/guides/page-interactions.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/page-interactions.md)\n- [docs/guides/screenshots.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/screenshots.md)\n- [docs/guides/pdf-generation.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/pdf-generation.md)\n</details>\n\n# Page页面操作API\n\n## 概述\n\nPage页面操作API是Puppeteer的核心模块之一，提供了与浏览器页面进行交互的完整能力。该API封装了浏览器自动化所需的各种操作，包括页面导航、内容查询、元素交互、JavaScript执行、截图和PDF生成等功能。\n\nPage类继承自Puppeteer的EventEmitter类，会发出各种在PageEvent枚举中定义的事件。Puppeteer支持两种底层协议实现：Chrome DevTools Protocol (CDP) 和 WebDriver BiDi (BiDi)，它们都实现了统一的Page抽象接口。\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:100]()\n\n## 架构设计\n\n### 实现层次结构\n\n```mermaid\ngraph TD\n    A[Page 抽象基类] --> B[CDPPage CDP协议实现]\n    A --> C[BiDiPage BiDi协议实现]\n    D[Frame 抽象基类] --> E[CDPFrame]\n    D --> F[BiDiFrame]\n    G[EventEmitter] --> A\n    H[JSHandle] --> I[ElementHandle]\n```\n\n### 核心组件关系\n\n| 组件 | 类型 | 职责 |\n|------|------|------|\n| Page | 抽象类 | 定义页面操作的统一接口 |\n| CDPPage | 实现类 | 通过CDP协议与Chrome通信 |\n| BiDiPage | 实现类 | 通过BiDi协议与浏览器通信 |\n| Frame | 抽象类 | 管理页面帧结构 |\n| JSHandle | 抽象类 | JavaScript对象句柄 |\n| ElementHandle | 抽象类 | DOM元素句柄 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:97-120]()\n\n## 页面生命周期\n\n### 页面状态管理\n\n```mermaid\nstateDiagram-v2\n    [*] --> 创建中: browser.newPage()\n    创建中 --> 已加载: 页面初始化完成\n    已加载 --> 导航中: goto() / setContent()\n    导航中 --> 已加载: 导航完成\n    已加载 --> 关闭中: close()\n    关闭中 --> [*]: 资源清理完成\n    已加载 --> 已加载: 页面刷新/前进后退\n```\n\n### 内部状态变量\n\nPage类维护以下内部状态：\n\n```typescript\n_isDragging = false;           // 拖拽状态\n_timeoutSettings = new TimeoutSettings();  // 超时配置\n_tabId = '';                   // 浏览器标签页ID\n#requestHandlers = WeakMap;    // 请求处理器映射\n#inflight$ = ReplaySubject;    // 进行中的请求流\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:105-115]()\n\n## 页面导航操作\n\n### goto - 页面跳转\n\n导航到指定URL并等待页面加载完成。\n\n```typescript\nawait page.goto('https://developer.chrome.com/');\n```\n\n**参数说明：**\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| url | string | 是 | 目标页面URL |\n| options | NavigationOptions | 否 | 导航选项配置 |\n\n**导航选项：**\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| timeout | number | 30s | 导航超时时间(毫秒) |\n| waitUntil | WaitUntilOptions | load | 等待条件 |\n| referer | string | - | 引荐来源URL |\n\n**waitUntil 支持的值：**\n\n| 值 | 说明 |\n|----|------|\n| `load` | 等待 load 事件触发 |\n| `domcontentloaded` | 等待 DOMContentLoaded 事件 |\n| `networkidle0` | 等待无网络连接(500ms内) |\n| `networkidle2` | 等待最多2个网络连接 |\n\n### setContent - 设置页面内容\n\n直接设置页面的HTML内容。\n\n```typescript\nawait page.setContent('<html><body><h1>Hello</h1></body></html>');\n```\n\n### reload - 刷新页面\n\n```typescript\nawait page.reload();\nawait page.reload({ timeout: 60000 });\n```\n\n### goBack / goForward - 历史导航\n\n```typescript\nawait page.goBack();      // 返回上一页\nawait page.goForward();   // 前进到下一页\n```\n\n## 元素查询与选择器\n\n### 选择器类型\n\nPuppeteer支持多种选择器类型，可以满足不同的查询需求：\n\n```mermaid\ngraph LR\n    A[选择器查询] --> B[CSS选择器]\n    A --> C[ARIA选择器]\n    A --> D[文本选择器]\n    A --> E[XPath选择器]\n    A --> F[Pierce选择器]\n```\n\n### 选择器类型对照表\n\n| 类型 | 语法 | 示例 |\n|------|------|------|\n| CSS | 标准CSS选择器 | `page.$('div.container')` |\n| ARIA | `::-p-aria(...)` | `page.locator('::-p-aria(Search)')` |\n| 文本 | `::-p-text(...)` | `page.locator('::-p-text(Click me)')` |\n| XPath | `::-p-xpath(...)` | `page.locator('::-p-xpath(//button)')` |\n| Pierce | `::-p-shadow(...)` | 穿透Shadow DOM查询 |\n\n资料来源：[packages/ng-schematics/README.md]()\n\n### 查询方法\n\n#### 单元素查询\n\n```typescript\n// CSS选择器\nconst button = await page.$('button.submit');\n\n// ARIA选择器\nconst searchInput = await page.$('::-p-aria(Search field)');\n\n// 文本选择器\nconst heading = await page.locator('::-p-text(Welcome)');\n```\n\n#### 多元素查询\n\n```typescript\nconst inputs = await page.$$('input[type=\"text\"]');\nconst items = await page.locator('li.item');\n```\n\n#### 高级查询\n\n```typescript\n// 跨Shadow DOM查询\nconst shadowElement = await page.locator('::-p-shadow(div.inner)');\n\n// 组合选择器\nconst complex = await page.locator('div.container >> text=Submit');\n```\n\n### $$eval - 批量元素操作\n\n在所有匹配元素上执行JavaScript函数：\n\n```typescript\nconst allInputValues = await page.$$eval('input', elements =>\n  elements.map(e => e.textContent)\n);\n```\n\n**参数说明：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| selector | string | CSS或其他类型选择器 |\n| pageFunction | Function | 在页面上下文执行的函数 |\n| args | any[] | 额外参数 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:220-240]()\n\n## JavaScript执行与函数注入\n\n### evaluate - 页面内执行JavaScript\n\n```typescript\nconst title = await page.evaluate(() => document.title);\n\nconst result = await page.evaluate(async () => {\n  const response = await fetch('/api/data');\n  return await response.json();\n});\n```\n\n### exposeFunction - 注入全局函数\n\n将Node.js函数暴露到页面window对象，页面JavaScript可以直接调用：\n\n```typescript\nimport crypto from 'crypto';\n\nawait page.exposeFunction('md5', text =>\n  crypto.createHash('md5').update(text).digest('hex')\n);\n\nawait page.evaluate(async () => {\n  const hash = await window.md5('PUPPETEER');\n  console.log(`md5: ${hash}`);\n});\n```\n\n**使用场景：**\n\n| 场景 | 说明 |\n|------|------|\n| 文件读取 | 在页面中读取服务器文件系统 |\n| 数据库访问 | 从页面查询数据库 |\n| API调用 | 使用Node.js HTTP客户端 |\n| 加密操作 | 复杂加密在Node端执行 |\n\n**特性：**\n\n- 通过`exposeFunction`注入的函数在页面导航后仍然有效\n- 如果注入的函数返回Promise，会自动await\n- 支持`Function`或`{default: Function}`类型\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:155-185]()\n\n### ExecutionContext - 执行上下文\n\nCDP实现的执行上下文提供了更底层的控制：\n\n```mermaid\nsequenceDiagram\n    participant P as Puppeteer\n    participant EC as ExecutionContext\n    participant B as Browser\n    \n    P->>EC: evaluate(pageFunction)\n    EC->>B: Runtime.evaluate\n    B-->>EC: result/exceptionDetails\n    EC-->>P: HandleFor<T> 或值\n```\n\n## 页面截图\n\n### 基本截图\n\n```typescript\nawait page.screenshot({ path: 'screenshot.png' });\n```\n\n### 截图选项\n\n| 选项 | 类型 | 说明 |\n|------|------|------|\n| type | 'png' \\| 'jpeg' \\| 'webp' | 图片格式 |\n| quality | number | 图片质量(0-100) |\n| fullPage | boolean | 是否截取完整页面 |\n| clip | Clip | 截图区域 |\n| omitBackground | boolean | 隐藏默认背景 |\n| encoding | 'binary' \\| 'base64' | 返回格式 |\n\n### 完整页面截图\n\n```typescript\nawait page.screenshot({\n  path: 'fullpage.png',\n  fullPage: true\n});\n```\n\n### 区域截图\n\n```typescript\nawait page.screenshot({\n  path: 'header.png',\n  clip: {\n    x: 0,\n    y: 0,\n    width: 800,\n    height: 100\n  }\n});\n```\n\n### Buffer返回\n\n```typescript\nconst buffer = await page.screenshot({\n  type: 'png',\n  encoding: 'binary'\n});\n```\n\n资料来源：[docs/guides/screenshots.md]()\n\n## PDF生成\n\n### 基本PDF生成\n\n```typescript\nawait page.pdf({ path: 'page.pdf' });\n```\n\n### PDF选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| printBackground | boolean | false | 打印背景色和图片 |\n| landscape | boolean | false | 横向打印 |\n| format | PaperFormat | 'Letter' | 纸张格式 |\n| width | string | - | 自定义宽度 |\n| height | string | - | 自定义高度 |\n| margin | Margin | - | 页边距 |\n| scale | number | 1 | 缩放比例 |\n| displayHeaderFooter | boolean | false | 显示页眉页脚 |\n| headerTemplate | string | - | 页眉HTML模板 |\n| footerTemplate | string | - | 页脚HTML模板 |\n\n### 常用纸张格式\n\n| 格式 | 尺寸 |\n|------|------|\n| Letter | 8.5in x 11in |\n| Legal | 8.5in x 14in |\n| Tabloid | 11in x 17in |\n| A4 | 210mm x 297mm |\n| A3 | 297mm x 420mm |\n| A5 | 148mm x 210mm |\n\n### 自定义尺寸示例\n\n```typescript\nawait page.pdf({\n  path: 'custom.pdf',\n  width: '210mm',\n  height: '297mm',\n  printBackground: true,\n  margin: {\n    top: '20mm',\n    bottom: '20mm',\n    left: '20mm',\n    right: '20mm'\n  }\n});\n```\n\n资料来源：[docs/guides/pdf-generation.md]()\n\n## 页面事件系统\n\n### 事件类型\n\nPage类继承自EventEmitter，支持以下核心事件：\n\n```mermaid\ngraph LR\n    A[Page Events] --> B[导航事件]\n    A --> C[请求事件]\n    A --> D[响应事件]\n    A --> E[对话框事件]\n    A --> F[帧事件]\n    \n    B --> B1[load]\n    B --> B2[domcontentloaded]\n    B --> B3[navigation]\n    \n    C --> C1[request]\n    C --> C2[requestfailed]\n    C --> C3[requestfinished]\n    \n    D --> D1[response]\n    \n    E --> E1[dialog]\n    \n    F --> F1[frameattached]\n    F --> F2[framedetached]\n    F --> F3[framenavigated]\n```\n\n### 常用事件监听\n\n```typescript\n// 页面加载完成\npage.once('load', () => console.log('Page loaded!'));\n\n// 监听所有请求\npage.on('request', request => {\n  console.log('Request:', request.url());\n});\n\n// 监听响应\npage.on('response', response => {\n  console.log('Response:', response.url(), response.status());\n});\n\n// 处理对话框\npage.on('dialog', async dialog => {\n  console.log('Dialog:', dialog.message());\n  await dialog.accept();\n});\n\n// 订阅与取消订阅\nconst handler = request => console.log(request.url());\npage.on('request', handler);\npage.off('request', handler);\n```\n\n### 导航相关事件\n\n| 事件 | 说明 | 回调参数 |\n|------|------|----------|\n| load | 页面完全加载 | - |\n| domcontentloaded | DOM解析完成 | - |\n| navigation | 导航开始 | - |\n| framenavigated | 帧导航完成 | Frame |\n\n### 请求相关事件\n\n| 事件 | 说明 | 回调参数 |\n|------|------|----------|\n| request | 发起请求 | HTTPRequest |\n| requestfailed | 请求失败 | HTTPRequest |\n| requestfinished | 请求完成 | HTTPRequest |\n| response | 收到响应 | HTTPResponse |\n\n## 帧(Frame)处理\n\n### Frame类结构\n\nFrame类提供了页面帧管理的能力，包括主框架和iframe。\n\n```mermaid\ngraph TD\n    Page --> Frame\n    Frame --> IFrame1[iframe]\n    Frame --> IFrame2[iframe]\n    IFrame1 --> NestedFrame[嵌套帧]\n```\n\n### 帧查询方法\n\n```typescript\n// 获取主框架\nconst mainFrame = page.mainFrame();\n\n// 获取所有框架\nconst frames = page.frames();\n\n// 根据name属性查找iframe\nconst iframe = page.frame('my-iframe');\n\n// 通过URL查找框架\nconst authFrame = page.frame({ url: /\\/auth/ });\n```\n\n### Frame中的操作\n\nFrame类实现了与Page类似的API，可以在帧上下文中执行操作：\n\n```typescript\n// 在特定帧中执行JavaScript\nconst result = await frame.evaluate(() => document.title);\n\n// 在特定帧中查找元素\nconst button = await frame.$('button.submit');\n\n// 等待帧加载\nawait frame.waitForSelector('.content-loaded');\n```\n\n### Frame与Page的关系\n\n```typescript\n// Frame的parentFrame\nconst parent = frame.parentFrame();  // 返回父帧或null\n\n// 帧的name属性\nconsole.log(frame.name());  // iframe的name属性值\n\n// 帧的URL\nconsole.log(frame.url());   // 帧的当前URL\n```\n\n资料来源：[packages/puppeteer-core/src/api/Frame.ts]()\n\n## Viewport与设备模拟\n\n### setViewport - 设置视口\n\n```typescript\nawait page.setViewport({ width: 1080, height: 1024 });\n```\n\n### 设备模拟\n\nPuppeteer内置了常用设备的配置：\n\n```typescript\nimport { KnownDevices } from 'puppeteer';\n\nconst iPhone = KnownDevices['iPhone 15 Pro'];\n\nawait page.emulate(iPhone);\n```\n\n### 自定义设备配置\n\n```typescript\nawait page.emulate({\n  name: 'Custom Device',\n  userAgent: 'Mozilla/5.0...',\n  viewport: {\n    width: 375,\n    height: 812,\n    deviceScaleFactor: 3,\n    isMobile: true,\n    hasTouch: true,\n    isLandscape: false\n  }\n});\n```\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts]()\n\n## 超时配置\n\n### TimeoutSettings\n\nPuppeteer使用TimeoutSettings类统一管理各种超时配置。\n\n### 常用超时配置\n\n```typescript\n// 设置默认导航超时\npage.setDefaultNavigationTimeout(60000);\n\n// 设置默认操作超时\npage.setDefaultTimeout(30000);\n\n// 设置单次操作超时\nawait page.waitForSelector('.element', { timeout: 5000 });\n```\n\n### 超时选项说明\n\n| 选项 | 默认值 | 说明 |\n|------|--------|------|\n| navigationTimeout | 30000ms | 页面导航超时 |\n| defaultTimeout | 30000ms | 默认操作超时 |\n| waitForTimeout | 30000ms | 等待元素超时 |\n\n## CDP与BiDi实现差异\n\n### 架构对比\n\n| 特性 | CDPPage | BiDiPage |\n|------|---------|----------|\n| 底层协议 | Chrome DevTools Protocol | WebDriver BiDi |\n| 浏览器支持 | Chrome/Edge | 所有主流浏览器 |\n| 功能完整性 | 完整 | 部分特性 |\n| 性能 | 较高 | 相对较低 |\n| 调试能力 | 强 | 一般 |\n\n### 实现文件\n\n- **CDP实现**: `packages/puppeteer-core/src/cdp/Page.ts`\n- **BiDi实现**: `packages/puppeteer-core/src/bidi/Page.ts`\n\n两种实现都遵循`packages/puppeteer-core/src/api/Page.ts`中定义的抽象接口，确保API行为的一致性。\n\n## 最佳实践\n\n### 页面操作流程\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[创建页面]\n    B --> C[设置Viewport]\n    C --> D[导航到URL]\n    D --> E{等待条件}\n    E -->|元素存在| F[执行操作]\n    E -->|等待超时| G[处理错误]\n    F --> H[截图/PDF]\n    H --> I[关闭页面]\n    G --> I\n```\n\n### 错误处理\n\n```typescript\ntry {\n  await page.goto('https://example.com', {\n    timeout: 30000,\n    waitUntil: 'networkidle0'\n  });\n} catch (error) {\n  if (error.message.includes('net::ERR_')) {\n    console.error('Network error occurred');\n  } else if (error.message.includes('timeout')) {\n    console.error('Navigation timeout');\n  }\n}\n```\n\n### 资源清理\n\n```typescript\n// 使用完记得关闭页面\nconst page = await browser.newPage();\ntry {\n  // 操作...\n} finally {\n  await page.close();\n}\n\n// 等待特定元素时使用waitForSelector的cleanup\nconst handle = await page.waitForSelector('.modal', {\n  timeout: 5000\n}).catch(() => null);\n\nif (handle) {\n  // 使用handle\n  await handle.dispose();\n}\n```\n\n### 性能优化建议\n\n1. **避免频繁截图** - 截图操作较耗时，按需使用\n2. **合理设置超时** - 过长超时会增加等待时间\n3. **使用waitForSelector** - 比固定延迟更高效\n4. **批量操作** - 减少页面交互次数\n5. **复用Page实例** - 避免频繁创建销毁页面\n\n## 相关链接\n\n- [Page Interactions 指南](https://pptr.dev/guides/page-interactions)\n- [Selectors 文档](https://pptr.dev/guides/selectors)\n- [Screenshots 指南](https://pptr.dev/guides/screenshots)\n- [PDF Generation 指南](https://pptr.dev/guides/pdf-generation)\n- [Locators API (实验性)](https://pptr.dev/guides/locators)\n\n---\n\n<a id='page-element-locator'></a>\n\n## 元素定位器与操作\n\n### 相关页面\n\n相关主题：[Page页面操作API](#page-page-api)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/ElementHandle.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/ElementHandle.ts)\n- [packages/puppeteer-core/src/api/locators/locators.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)\n- [packages/puppeteer-core/src/cdp/ElementHandle.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ElementHandle.ts)\n- [packages/puppeteer-core/src/injected/ARIAQuerySelector.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/ARIAQuerySelector.ts)\n- [packages/puppeteer-core/src/injected/PierceQuerySelector.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/PierceQuerySelector.ts)\n- [packages/puppeteer-core/src/common/CustomQueryHandler.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/CustomQueryHandler.ts)\n</details>\n\n# 元素定位器与操作\n\n## 概述\n\n元素定位器与操作是 Puppeteer 自动化框架中用于在网页中查找和交互 DOM 元素的核心模块。该系统提供了多种定位策略，包括 CSS 选择器、ARIA 角色定位、文本匹配、XPath 表达式以及穿透 Shadow DOM 的选择器，同时支持通过定位器 API 实现稳定的元素等待和交互操作。\n\n定位器（Locator）是对传统 `page.$()` 和 `page.$$()` 查询方式的现代化封装，提供了更好的错误处理、自动重试机制以及流畅的 API 设计。元素句柄（ElementHandle）则代表了页面中 DOM 元素的引用，通过它可以执行点击、填充、拖拽等交互操作。\n\n## 架构设计\n\n### 核心组件关系\n\n```mermaid\ngraph TD\n    A[Page] --> B[Locator API]\n    A --> C[ElementHandle API]\n    B --> D[Query Handler]\n    C --> D\n    D --> E[CSS Selector Handler]\n    D --> F[ARIA Selector Handler]\n    D --> G[Text Selector Handler]\n    D --> H[XPath Selector Handler]\n    D --> I[Pierce Selector Handler]\n    D --> J[Custom Query Handler]\n```\n\n### 定位器与元素句柄的职责划分\n\n| 组件 | 职责 | 特点 |\n|------|------|------|\n| Locator | 描述如何定位元素，提供延迟解析和自动等待 | 每次调用都会重新查询，支持重试 |\n| ElementHandle | 持有元素引用，执行具体操作 | 可能因导航而失效，需要管理生命周期 |\n| QueryHandler | 实现具体的查询逻辑 | 插件化设计，支持自定义扩展 |\n\n资料来源：[packages/puppeteer-core/src/api/locators/locators.ts:1-50](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)\n\n## 选择器类型详解\n\n### 支持的选择器类型\n\nPuppeteer 支持多种选择器语法，可通过前缀或组合方式使用：\n\n| 选择器类型 | 前缀 | 示例 | 说明 |\n|-----------|------|------|------|\n| CSS 选择器 | 无 | `div.container` | 标准 CSS 选择器 |\n| ARIA 角色 | `::-p-aria` | `::-p-aria([name=\"搜索\"])` | 通过无障碍属性定位 |\n| 文本匹配 | `::-p-text` | `::-p-text(提交)` | 通过元素文本内容定位 |\n| XPath | `::-p-xpath` | `::-p-xpath(//button)` | XPath 表达式 |\n| 穿透选择器 | `pierce/` | `pierce/>>> button` | 穿透 Shadow DOM 边界 |\n\n资料来源：[packages/puppeteer-core/src/common/CustomQueryHandler.ts:1-30](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/CustomQueryHandler.ts)\n\n### ARIA 选择器实现\n\nARIA 选择器通过无障碍 API 查询页面元素，其核心实现在 `ARIAQuerySelector.ts` 中：\n\n```typescript\nexport class ARIAQueryHandler {\n  async queryOne(\n    root: Node,\n    selector: string\n  ): Promise<ElementHandle<Node> | null> {\n    // 使用 ARIA 属性查询 DOM\n  }\n}\n```\n\n该处理器利用浏览器原生 ARIA 查询能力，支持通过角色、名称、状态等属性定位元素。\n\n资料来源：[packages/puppeteer-core/src/injected/ARIAQuerySelector.ts:1-80](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/ARIAQuerySelector.ts)\n\n### 穿透选择器实现\n\n穿透选择器（Pierce Selector）能够跨越 Shadow DOM 边界进行查询：\n\n```typescript\nexport class PierceQueryHandler {\n  async queryOne(\n    root: Node,\n    selector: string\n  ): Promise<ElementHandle<Node> | null> {\n    // 递归遍历 shadowRoot 查找匹配元素\n  }\n}\n```\n\n该选择器通过递归遍历文档树和所有 Shadow DOM 来查找匹配的元素，适用于复杂的 Web 组件场景。\n\n资料来源：[packages/puppeteer-core/src/injected/PierceQuerySelector.ts:1-60](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/PierceQuerySelector.ts)\n\n## 定位器 API\n\n### 定位器工作流程\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\n    participant Locator as Locator\n    participant QueryHandler as QueryHandler\n    participant Browser as 浏览器\n\n    User->>Locator: 创建定位器\n    Locator->>User: 返回 Locator 实例\n    User->>Locator: waitHandle()\n    Locator->>QueryHandler: 执行查询\n    QueryHandler->>Browser: DOM 查询\n    Browser-->>QueryHandler: 返回元素引用\n    QueryHandler-->>Locator: ElementHandle\n    Locator-->>User: Promise<Handle>\n```\n\n### 主要定位器方法\n\n| 方法 | 返回类型 | 说明 |\n|------|----------|------|\n| `locator(selector)` | Locator | 创建新的定位器 |\n| `waitHandle()` | Promise<Handle> | 等待并返回元素句柄 |\n| `first()` | Locator | 获取匹配的第一个元素定位器 |\n| `nth(index)` | Locator | 获取指定索引的定位器 |\n| `filter(options)` | Locator | 按条件过滤定位结果 |\n| `map(fn)` | ... | 映射操作 |\n| `wait(options?)` | Promise | 等待元素出现 |\n\n资料来源：[packages/puppeteer-core/src/api/locators/locators.ts:50-150](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)\n\n### 使用示例\n\n```typescript\n// 使用 locator API 进行稳定操作\nconst button = page.locator('button[type=\"submit\"]');\nawait button.wait();\nawait button.click();\n\n// 使用 ARIA 选择器\nconst searchInput = page.locator('::-p-aria([name=\"搜索框\"])');\n\n// 使用文本选择器\nconst submitBtn = page.locator('::-p-text(提交)');\n\n// 穿透 Shadow DOM\nconst nestedButton = page.locator('pierce/>>> my-component >>> button');\n```\n\n## 元素句柄操作\n\n### 元素句柄生命周期\n\n```mermaid\ngraph LR\n    A[创建 ElementHandle] --> B{页面导航}\n    B -->|发生| C[句柄失效]\n    B -->|未发生| D[可继续使用]\n    C --> E[需重新查询]\n    D --> F[执行操作]\n    F --> G[释放资源]\n```\n\n### ElementHandle 核心方法\n\n| 方法 | 说明 | 返回值 |\n|------|------|--------|\n| `click(options?)` | 点击元素 | Promise<void> |\n| `fill(value)` | 填充输入框 | Promise<void> |\n| `tap()` | 触发触摸事件 | Promise<void> |\n| `hover()` | 鼠标悬停 | Promise<void> |\n| `scrollIntoViewIfNeeded()` | 滚动到可视区域 | Promise<void> |\n| `drag(...targets)` | 执行拖拽操作 | Promise<void> |\n| `uploadFile(...filePaths)` | 上传文件 | Promise<void> |\n\n资料来源：[packages/puppeteer-core/src/api/ElementHandle.ts:50-200](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/ElementHandle.ts)\n\n### CDP 实现细节\n\nCDP（Chrome DevTools Protocol）实现提供了高性能的元素交互能力：\n\n```typescript\nclass ElementHandleImpl extends CDPJSHandle implements ElementHandle<Node> {\n  #client: CdpCDPClient;\n  \n  async click(options?: ClickOptions): Promise<void> {\n    const { x, y } = await this.clickablePoint();\n    this.#client.input.dispatchMouseEvent({\n      type: 'mousePressed',\n      button: 'left',\n      x, y\n    });\n  }\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/ElementHandle.ts:100-180](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ElementHandle.ts)\n\n## 自定义查询处理器\n\n### 注册自定义选择器\n\n通过 `CustomQueryHandler` 可以扩展 Puppeteer 的查询能力：\n\n```typescript\nimport { register } from 'puppeteer';\n\nregister('jQuery', {\n  queryOne: (root: Node, selector: string) => {\n    // 实现 jQuery 选择逻辑\n    return root.querySelector(selector);\n  },\n  queryAll: (root: Node, selector: string) => {\n    return root.querySelectorAll(selector);\n  }\n});\n```\n\n### 自定义处理器结构\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `queryOne` | `(root: Node, selector: string) => ElementHandle \\| null` | 返回第一个匹配元素 |\n| `queryAll` | `(root: Node, selector: string) => ElementHandle[]` | 返回所有匹配元素 |\n\n资料来源：[packages/puppeteer-core/src/common/CustomQueryHandler.ts:30-80](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/CustomQueryHandler.ts)\n\n## 等待与重试机制\n\n### 定位器等待策略\n\n```mermaid\ngraph TD\n    A[开始等待] --> B{超时?}\n    B -->|是| C[抛出 TimeoutError]\n    B -->|否| D{元素存在?}\n    D -->|否| E[重新查询]\n    E --> B\n    D -->|是| F{检查条件?}\n    F -->|否| G[等待后重新检查]\n    G --> B\n    F -->|是| H[返回元素句柄]\n```\n\n### 等待选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `timeout` | number | 继承自 page | 等待超时时间（毫秒） |\n| `state` | 'attached' \\| 'detached' \\| 'visible' \\| 'hidden' | 'visible' | 元素状态条件 |\n| `signal` | AbortSignal | undefined | 中止信号 |\n\n## 最佳实践\n\n### 选择器性能优化\n\n| 场景 | 推荐选择器 | 原因 |\n|------|-----------|------|\n| 唯一元素 | `#id` 或 `data-testid` | 最快，浏览器原生支持 |\n| 语义化查询 | `::-p-aria` | 可访问性好，不依赖样式 |\n| 复杂层级 | `pierce/` | 穿透 Shadow DOM |\n| 避免 | `:nth-of-type` 深层嵌套 | 性能较差 |\n\n### 稳定性建议\n\n1. **优先使用定位器 API**：相比 ElementHandle，定位器提供自动重试和更好的错误信息\n2. **显式等待而非硬编码延迟**：使用 `wait()` 方法等待元素状态变化\n3. **使用语义化选择器**：通过 ARIA 属性而非 CSS 类名定位元素\n4. **管理资源生命周期**：使用 `using` 声明自动释放 ElementHandle\n\n```typescript\n// 推荐写法\nawait page.locator('button[type=\"submit\"]').click();\n\n// 避免硬编码延迟\n// await new Promise(r => setTimeout(r, 2000));\n```\n\n## 相关文档\n\n- [Page 类 API](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [Frame 类 API](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Frame.ts)\n- [JSHandle 类 API](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/JSHandle.ts)\n\n---\n\n<a id='page-network'></a>\n\n## 网络请求拦截与管理\n\n### 相关页面\n\n相关主题：[Page页面操作API](#page-page-api), [浏览器启动与管理](#page-browser-management)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/cdp/ExecutionContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ExecutionContext.ts)\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n- [packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts)\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n- [packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n- [packages/puppeteer-core/src/cdp/utils.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/utils.ts)\n- [packages/puppeteer-core/src/bidi/util.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/util.ts)\n- [examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n</details>\n\n# 网络请求拦截与管理\n\n## 概述\n\nPuppeteer 的网络请求拦截与管理功能允许开发者监控、修改、阻止或重定向网页发出的 HTTP 请求和响应。该功能是浏览器自动化测试和开发调试的核心能力之一，开发者可以借此实现广告屏蔽、请求日志记录、网络条件模拟、API 响应模拟等高级功能。\n\n网络拦截机制基于事件驱动架构，通过 `request`、`response`、`requestfailed`、`requestfinished` 等事件向外暴露网络活动的完整生命周期。Puppeteer 支持两种协议实现：Chrome DevTools Protocol (CDP) 和 WebDriver BiDi，本质上都是通过底层协议拦截和处理网络请求。\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 核心架构\n\n### 组件关系图\n\n```mermaid\ngraph TD\n    A[Page] --> B[NetworkManager]\n    B --> C[HTTPRequest]\n    C --> D[HTTPResponse]\n    E[Request Handler] -.-> C\n    F[setRequestInterception] --> E\n    G[Service Worker] -.-> B\n    \n    style A fill:#e1f5fe\n    style C fill:#fff3e0\n    style D fill:#e8f5e9\n```\n\n### 网络请求生命周期\n\n```mermaid\nstateDiagram-v2\n    [*] --> RequestSent\n    RequestSent --> ResponseReceived: 收到响应头\n    ResponseReceived --> DataReceived: 接收数据\n    DataReceived --> RequestFinished: 传输完成\n    RequestSent --> RequestFailed: 连接失败\n    ResponseReceived --> RequestFailed: 中断错误\n    \n    RequestFinished --> [*]\n    RequestFailed --> [*]\n```\n\n---\n\n## 请求拦截机制\n\n### 启用请求拦截\n\n通过 `setRequestInterception` 方法启用请求拦截功能。启用后，所有通过页面的 HTTP 请求都会触发 `request` 事件，开发者可以在回调中对请求进行处理。\n\n```typescript\nawait page.setRequestInterception(true);\npage.on('request', interceptedRequest => {\n  if (interceptedRequest.url().endsWith('.png') ||\n      interceptedRequest.url().endsWith('.jpg')) {\n    interceptedRequest.abort();\n  } else {\n    interceptedRequest.continue();\n  }\n});\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n### 拦截方法对照表\n\n| 方法 | 描述 | 使用场景 |\n|------|------|----------|\n| `abort()` | 终止请求 | 屏蔽资源、模拟加载失败 |\n| `abort(errorCode)` | 带错误码终止请求 | 测试错误处理逻辑 |\n| `continue()` | 继续原始请求 | 放行请求 |\n| `continue(overrides)` | 修改后继续请求 | 修改请求头或 POST 数据 |\n| `respond(response)` | 直接返回响应 | 模拟 API 响应 |\n\n### 请求拦截参数\n\n`continue()` 方法支持以下参数覆盖：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `postData` | `string \\| Buffer` | POST 请求体数据 |\n| `headers` | `Record<string, string>` | 自定义请求头 |\n| `url` | `string` | 重定向目标 URL |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## HTTPRequest 类\n\n`HTTPRequest` 是 Puppeteer 中表示网络请求的核心类，封装了请求的完整信息及操作方法。\n\n### 主要属性\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `url` | `string` | 请求目标 URL |\n| `method` | `string` | HTTP 方法（GET、POST 等） |\n| `headers` | `Record<string, string>` | 请求头 |\n| `postData` | `string \\| undefined` | POST 请求体 |\n| `resourceType` | `ResourceType` | 资源类型（document、script、image 等） |\n| `frame` | `Frame \\| null` | 请求来源的 Frame |\n| `response` | `HTTPResponse \\| null` | 关联的响应对象 |\n| `isNavigationRequest` | `boolean` | 是否为导航请求 |\n| `redirectChain` | `HTTPRequest[]` | 重定向链 |\n\n### 核心方法\n\n| 方法 | 签名 | 功能 |\n|------|------|------|\n| `abort` | `abort(errorCode?: ErrorCode): Promise<void>` | 终止请求 |\n| `continue` | `continue(overrides?: ContinueOverrides): Promise<void>` | 继续/修改请求 |\n| `respond` | `respond(response: RespondOverrides): Promise<void>` | 直接响应 |\n| `failure` | `failure(): Error \\| null` | 获取请求失败信息 |\n| `enqueueNavigationHook` | `enqueueNavigationHook(hook: NavigationHook): Promise<void>` | 注册导航钩子 |\n\n---\n\n## HTTPResponse 类\n\n`HTTPResponse` 封装了 HTTP 响应的完整信息。\n\n### 主要属性\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `ok` | `boolean` | 响应状态码是否在 200-299 范围内 |\n| `status` | `number` | HTTP 状态码 |\n| `statusText` | `string` | 状态文本 |\n| `url` | `string` | 响应 URL |\n| `request` | `HTTPRequest` | 关联的请求对象 |\n| `fromCache` | `boolean` | 是否来自缓存 |\n| `fromServiceWorker` | `boolean` | 是否来自 Service Worker |\n\n### 响应方法\n\n| 方法 | 签名 | 功能 |\n|------|------|------|\n| `text` | `text(): Promise<string>` | 获取响应体文本 |\n| `json` | `json(): Promise<unknown>` | 解析 JSON 响应体 |\n| `buffer` | `buffer(): Promise<Buffer>` | 获取响应体二进制数据 |\n| `remoteAddress` | `{ip: string, port: number}` | 远程地址信息 |\n\n---\n\n## 网络事件系统\n\n### 事件类型\n\n```typescript\nenum PageEvent {\n  Request = 'request',\n  Response = 'response',\n  RequestFailed = 'requestfailed',\n  RequestFinished = 'requestfinished',\n  BeforeDHARequest = 'beforedhcprequest',\n  DHCCreated = 'dhcpcreated',\n  DHCPChanged = 'dhcpchanged',\n  DHCPDeleted = 'dhcpdeleted',\n}\n```\n\n### 事件监听示例\n\n```typescript\n// 监听所有请求\npage.on('request', request => {\n  console.log(`请求: ${request.method()} ${request.url()}`);\n});\n\n// 监听所有响应\npage.on('response', response => {\n  console.log(`响应: ${response.status()} ${response.url()}`);\n});\n\n// 监听失败请求\npage.on('requestfailed', request => {\n  console.log(`失败: ${request.failure()?.errorText}`);\n});\n\n// 监听完成请求\npage.on('requestfinished', request => {\n  console.log(`完成: ${request.url()}`);\n});\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 网络条件模拟\n\n### 离线模式\n\n`emulateNetworkConditions` 方法允许模拟各种网络条件：\n\n```typescript\nawait page.emulateNetworkConditions({\n  offline: true,           // 是否离线\n  download: 50 * 1024,     // 下载速度 (bytes/s)\n  upload: 20 * 1024,       // 上传速度 (bytes/s)\n  latency: 40              // 延迟 (ms)\n});\n```\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n\n### 预定义网络条件\n\nPuppeteer 提供了一系列预定义的网络条件配置：\n\n| 条件名称 | 延迟 | 下载速度 | 上传速度 | 适用场景 |\n|----------|------|----------|----------|----------|\n| `Regular3G` | 40ms | 750 KB/s | 250 KB/s | 3G 网络 |\n| `Slow3G` | 200ms | 250 KB/s | 50 KB/s | 慢速 3G |\n| `Good3G` | 20ms | 1.5 MB/s | 750 KB/s | 良好 3G |\n| `DSL` | 5ms | 2 MB/s | 1 MB/s | DSL 连接 |\n| `WiFi` | 2ms | 30 MB/s | 15 MB/s | WiFi 连接 |\n\n### 设备模拟\n\n通过 `emulate` 方法可以模拟特定设备的网络和视口配置：\n\n```typescript\nimport {KnownDevices} from 'puppeteer';\n\nconst iPhone = KnownDevices['iPhone 15 Pro'];\nawait page.emulate(iPhone);\n```\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n\n---\n\n## Service Worker 支持\n\n### Service Worker 绕过\n\n`setBypassServiceWorker` 方法用于控制是否绕过 Service Worker：\n\n```typescript\n// 绕过 Service Worker，直接从网络加载\nawait page.setBypassServiceWorker(true);\n\n// 使用 Service Worker\nawait page.setBypassServiceWorker(false);\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setBypassServiceWorker](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 拖拽拦截（已弃用）\n\n`setDragInterception` 方法用于拦截拖拽事件，但该功能已被弃用：\n\n```typescript\n@deprecated We no longer support intercepting drag payloads. Use the new\ndrag APIs found on {@link ElementHandle} to drag (or just use the\n{@link Page.mouse}).\nabstract setDragInterception(enabled: boolean): Promise<void>;\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setDragInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 错误处理\n\n### 请求失败处理\n\n当请求失败时，`requestfailed` 事件会携带失败信息：\n\n```typescript\npage.on('requestfailed', request => {\n  const failure = request.failure();\n  console.log(`请求失败: ${failure?.errorText}`);\n});\n```\n\n### 执行上下文销毁处理\n\n当执行上下文被销毁时（如页面导航），Puppeteer 会抛出明确的错误：\n\n```typescript\nif (\n  error.message.includes('ExecutionContext was destroyed') ||\n  error.message.includes('Inspected target navigated or closed')\n) {\n  throw new Error(\n    'Execution context was destroyed, most likely because of a navigation.',\n  );\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/utils.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/utils.ts)\n\n---\n\n## 调试支持\n\n### 调试日志配置\n\nPuppeteer 支持通过 `window.__PUPPETEER_DEBUG` 环境变量开启调试日志：\n\n```typescript\n// 开启所有调试日志\nwindow.__PUPPETEER_DEBUG = '*';\n\n// 只记录 Network 通道\nwindow.__PUPPETEER_DEBUG = 'Network';\n\n// 记录所有以 Net 开头的通道\nwindow.__PUPPETEER_DEBUG = 'Net*';\n```\n\n```typescript\nconst log = debug('Network');\nlog('new request intercepted');\n// 输出: \"Network: new request intercepted\"\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts)\n\n---\n\n## 完整使用示例\n\n### 示例 1：屏蔽图片请求\n\n```typescript\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\nawait page.setRequestInterception(true);\npage.on('request', request => {\n  if (request.resourceType() === 'image') {\n    request.abort();\n  } else {\n    request.continue();\n  }\n});\n\nawait page.goto('https://example.com');\nawait browser.close();\n```\n\n### 示例 2：模拟 API 响应\n\n```typescript\nawait page.setRequestInterception(true);\npage.on('request', async request => {\n  if (request.url().endsWith('/api/data')) {\n    await request.respond({\n      status: 200,\n      contentType: 'application/json',\n      body: JSON.stringify({message: 'Mocked response'}),\n    });\n  } else {\n    request.continue();\n  }\n});\n```\n\n### 示例 3：记录所有网络请求\n\n```typescript\npage.on('request', request => {\n  console.log(`>> ${request.method()} ${request.url()}`);\n});\n\npage.on('response', response => {\n  console.log(`<< ${response.status()} ${response.url()}`);\n});\n\npage.on('requestfailed', request => {\n  console.log(`!! FAILED: ${request.url()} - ${request.failure()?.errorText}`);\n});\n```\n\n资料来源：[examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n\n---\n\n## 配置选项\n\n### 启动配置\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `timeout` | `number` | 30000 | 浏览器启动超时（毫秒） |\n| `handleSIGINT` | `boolean` | true | Ctrl+C 时关闭浏览器 |\n| `handleSIGTERM` | `boolean` | true | SIGTERM 时关闭浏览器 |\n| `handleSIGHUP` | `boolean` | true | SIGHUP 时关闭浏览器 |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n\n### 下载配置\n\n| 配置项 | 环境变量 | 说明 |\n|--------|----------|------|\n| `defaultBrowser` | - | 默认浏览器类型 |\n| `temporaryDirectory` | `PUPPETEER_TMP_DIR` | 临时文件目录 |\n| `skipDownload` | `PUPPETEER_SKIP_DOWNLOAD` | 跳过浏览器下载 |\n| `logLevel` | - | 日志级别 (silent/error/warn) |\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n\n---\n\n## 最佳实践\n\n### 1. 及时关闭拦截\n\n```typescript\n// 拦截完成后及时关闭\nawait page.setRequestInterception(false);\npage.off('request', handler);\n```\n\n### 2. 避免在拦截回调中执行耗时操作\n\n拦截回调会阻塞请求，耗时操作应使用异步方式：\n\n```typescript\npage.on('request', async request => {\n  // 使用 async 处理\n  if (needMock) {\n    await request.respond({...});\n  } else {\n    request.continue();\n  }\n});\n```\n\n### 3. 处理导航场景\n\n导航请求可能触发上下文销毁，应在拦截逻辑中处理：\n\n```typescript\npage.on('request', request => {\n  try {\n    if (request.isNavigationRequest()) {\n      // 处理导航请求\n      request.continue({headers: {...}});\n    }\n  } catch (e) {\n    // 上下文可能已销毁\n  }\n});\n```\n\n---\n\n## 相关资源\n\n- [官方文档：网络拦截](https://pptr.dev/guides/network-interception)\n- [官方文档：网络日志](https://pptr.dev/guides/network-logging)\n- [示例代码库](../examples)\n\n---\n\n<a id='page-contexts-extensions'></a>\n\n## 浏览器上下文与扩展支持\n\n### 相关页面\n\n相关主题：[浏览器启动与管理](#page-browser-management), [覆盖率检测与调试功能](#page-coverage-debugging)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts) - 启动选项定义，包含扩展支持配置\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts) - Page 类抽象定义，exposeFunction 等方法\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts) - 全局配置接口\n- [packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts) - 调试日志系统\n- [packages/puppeteer-core/src/cdp/ExecutionContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ExecutionContext.ts) - CDP 执行上下文实现\n- [packages/puppeteer-core/src/bidi/util.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/util.ts) - BiDi 协议工具函数\n- [README.md](https://github.com/puppeteer/puppeteer/blob/main/README.md) - 主项目文档\n</details>\n\n# 浏览器上下文与扩展支持\n\n## 概述\n\nPuppeteer 的浏览器上下文（Browser Context）与扩展支持功能为开发者提供了在同一浏览器实例中创建隔离环境的能力，并支持加载 Chrome 扩展程序。这些功能使得高级自动化场景（如多租户隔离、扩展辅助测试、隐私浏览模式等）成为可能。\n\n### 核心概念\n\n- **浏览器上下文（Browser Context）**：一个独立的浏览器会话环境，拥有独立的 Cookie 存储、缓存和本地存储。不同上下文之间的数据完全隔离。\n- **扩展支持（Extension Support）**：Puppeteer 允许将未打包的扩展程序加载到浏览器实例中，以辅助自动化测试或实现自定义功能。\n\n## 浏览器上下文架构\n\n### 抽象层设计\n\nPuppeteer 在 `packages/puppeteer-core/src/api/` 目录下定义了 BrowserContext 的抽象接口。具体实现分别针对 CDP（Chrome DevTools Protocol）和 BiDi（WebDriver BiDi）协议提供了独立的实现类。\n\n### CDP 实现\n\n在 CDP（Chrome DevTools Protocol）实现中，浏览器上下文通过创建独立的浏览器会话来实现隔离。CDP 协议原生支持上下文隔离，每个上下文拥有独立的 Target（目标），包括页面、服务工作者等。\n\n### BiDi 实现\n\n在 BiDi（WebDriver BiDi）协议实现中，浏览器上下文作为独立的会话存在。BiDi 协议的上下文管理机制与 CDP 类似，但提供了标准化的跨浏览器支持。\n\n## 扩展加载机制\n\n### 启动配置\n\nPuppeteer 通过 `LaunchOptions` 接口提供扩展支持配置。扩展可以在浏览器启动时加载：\n\n```typescript\ninterface LaunchOptions {\n  /**\n   * 如果为 true，则避免传递会阻止扩展启用的默认参数。\n   * 传递字符串数组将加载提供的路径作为未打包的扩展程序。\n   */\n  enableExtensions?: boolean | string[];\n}\n```\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:1-50]()\n\n### 配置选项说明\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enableExtensions` | `boolean \\| string[]` | `undefined` | 启用扩展支持。布尔值启用所有默认扩展行为；字符串数组指定要加载的扩展路径 |\n| `handleSIGINT` | `boolean` | `true` | 在 Ctrl+C 时关闭浏览器进程 |\n| `handleSIGTERM` | `boolean` | `true` | 在 SIGTERM 时关闭浏览器进程 |\n| `handleSIGHUP` | `boolean` | `true` | 在 SIGHUP 时关闭浏览器进程 |\n\n## 扩展上下文通信\n\n### exposeFunction 方法\n\n`exposeFunction` 是 Page 类提供的核心方法，允许从浏览器页面调用 Node.js 环境中的函数。这对于扩展辅助测试和双向通信至关重要：\n\n```typescript\nabstract exposeFunction(\n  name: string,\n  pptrFunction: Function | {default: Function},\n): Promise<void>;\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:1-100]()\n\n### 使用模式\n\n#### 基本用法\n\n```typescript\nimport puppeteer from 'puppeteer';\nimport fs from 'node:fs';\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\npage.on('console', msg => console.log(msg.text()));\n\nawait page.exposeFunction('readfile', async filePath => {\n  return new Promise((resolve, reject) => {\n    fs.readFile(filePath, 'utf8', (err, text) => {\n      if (err) reject(err);\n      else resolve(text);\n    });\n  });\n});\n\nawait page.evaluate(async () => {\n  const content = await window.readfile('/etc/hosts');\n  console.log(content);\n});\n\nawait browser.close();\n```\n\n#### 与扩展配合使用\n\n通过 `exposeFunction`，开发者可以创建桥接函数，使扩展程序能够与 Node.js 环境交互：\n\n```typescript\nawait page.exposeFunction('md5', async (myString: string) => {\n  const hash = await window.md5(myString);\n  console.log(`md5 of ${myString} is ${hash}`);\n});\n```\n\n### 内部实现机制\n\n在 CDP 实现中，`exposeFunction` 通过以下步骤工作：\n\n1. 在页面的执行上下文中注册一个全局函数\n2. 监听页面中对该函数的调用\n3. 将调用参数从浏览器环境传递到 Node.js 环境\n4. 执行提供的 Node.js 回调函数\n5. 将结果返回到浏览器环境\n\n资料来源：[packages/puppeteer-core/src/cdp/ExecutionContext.ts:1-80]()\n\n## evaluateOnNewDocument 功能\n\n`evaluateOnNewDocument` 方法允许在每个新文档创建后、任何脚本运行前注入代码。这对于在页面加载前修改 JavaScript 环境非常有用：\n\n```typescript\nabstract evaluateOnNewDocument<\n  Params extends unknown[],\n  Func extends (...args: Params) => unknown = (...args: Params) => unknown,\n>(\n  pageFunction: Func | string,\n  ...args: Params\n): Promise<NewDocumentScriptEvaluation>;\n```\n\n### 应用场景\n\n#### 覆盖 navigator.languages\n\n```typescript\n// preload.js\nObject.defineProperty(navigator, 'languages', {\n  get: function () {\n    return ['en-US', 'en', 'bn'];\n  },\n});\n\n// 在 Puppeteer 脚本中使用\nconst preloadFile = fs.readFileSync('./preload.js', 'utf8');\nawait page.evaluateOnNewDocument(preloadFile);\n```\n\n## 配置系统\n\n### 全局配置接口\n\nPuppeteer 提供了 `Configuration` 接口用于全局配置：\n\n```typescript\nexport interface Configuration {\n  defaultBrowser?: SupportedBrowser;\n  temporaryDirectory?: string;\n  skipDownload?: boolean;\n  logLevel?: 'silent' | 'error' | 'warn';\n  experiments?: ExperimentsConfiguration;\n  chrome?: ChromeSettings;\n  ['chrome-headless-shell']?: ChromeHeadlessShellSettings;\n  firefox?: FirefoxSettings;\n}\n```\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:1-80]()\n\n### 环境变量覆盖\n\n| 环境变量 | 对应配置项 | 说明 |\n|----------|-----------|------|\n| `PUPPETEER_TMP_DIR` | `temporaryDirectory` | 临时文件目录 |\n| `PUPPETEER_SKIP_DOWNLOAD` | `skipDownload` | 跳过浏览器下载 |\n| `PUPPETEER_LOG_LEVEL` | `logLevel` | 日志级别 |\n| `PUPPETEER_CHROME_SKIP_DOWNLOAD` | `chrome.skipDownload` | 跳过 Chrome 下载 |\n| `PUPPETEER_CHROME_DOWNLOAD_BASE_URL` | `chrome.downloadBaseUrl` | Chrome 下载基础 URL |\n\n## 调试支持\n\nPuppeteer 提供了可配置的调试日志系统：\n\n```typescript\nexport const debug = (prefix: string): ((...args: unknown[]) => void) => {\n  if (isNode) {\n    return async (...logArgs: unknown[]) => {\n      if (captureLogs) {\n        capturedLogs.push(prefix + logArgs);\n      }\n      (await importDebug())(prefix)(logArgs);\n    };\n  }\n  // 浏览器环境实现...\n};\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:1-60]()\n\n### 调试通道\n\n| 通道前缀 | 说明 |\n|---------|------|\n| `Page` | 页面相关日志 |\n| `BrowserContext` | 浏览器上下文日志 |\n| `Extension` | 扩展相关日志 |\n| `Target` | 目标管理日志 |\n\n### 使用方法\n\n```javascript\n// 设置日志级别\nwindow.__PUPPETEER_DEBUG='Page';        // 仅记录 Page 通道\nwindow.__PUPPETEER_DEBUG='Page*';        // 记录所有 Page 开头的通道\nwindow.__PUPPETEER_DEBUG='*';           // 记录所有通道\n```\n\n## 错误处理\n\n### 执行上下文错误\n\nPuppeteer 提供了专门的错误重写函数用于处理常见错误场景：\n\n```typescript\nexport function rewriteEvaluationError(error: unknown): never {\n  if (error instanceof Error) {\n    if (\n      error.message.includes('ExecutionContext was destroyed') ||\n      error.message.includes('Inspected target navigated or closed')\n    ) {\n      throw new Error(\n        'Execution context was destroyed, most likely because of a navigation.',\n      );\n    }\n  }\n  throw error;\n}\n```\n\n资料来源：[packages/puppeteer-core/src/bidi/util.ts:1-80]()\n\n### 导航超时处理\n\n```typescript\nexport function rewriteNavigationError(\n  message: string,\n  ms: number,\n): (error: unknown) => never {\n  return error => {\n    if (error instanceof ProtocolError) {\n      error.message += ` at ${message}`;\n    } else if (error instanceof TimeoutError) {\n      error.message = `Navigation timeout of ${ms} ms exceeded`;\n    }\n    throw error;\n  };\n}\n```\n\n## 完整使用示例\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nasync function main() {\n  // 启用扩展支持\n  const browser = await puppeteer.launch({\n    enableExtensions: ['/path/to/unpacked/extension'],\n    handleSIGINT: true,\n    handleSIGTERM: true,\n    timeout: 30000,\n  });\n\n  // 创建隔离上下文\n  const context = browser.createBrowserContext();\n  const page = await context.newPage();\n\n  // 设置调试日志\n  page.on('console', msg => console.log('PAGE LOG:', msg.text()));\n\n  // 暴露 Node.js 函数到页面\n  await page.exposeFunction('getNodeVersion', () => process.version);\n  await page.exposeFunction('readConfig', async () => {\n    return {apiKey: 'xxx', endpoint: 'https://api.example.com'};\n  });\n\n  // 在文档创建前注入代码\n  await page.evaluateOnNewDocument(() => {\n    console.log('Document about to be created');\n  });\n\n  await page.goto('https://example.com');\n  await browser.close();\n}\n\nmain().catch(console.error);\n```\n\n## 最佳实践\n\n1. **资源清理**：使用完毕后调用 `browser.close()` 或 `context.close()` 释放资源\n2. **超时配置**：根据网络状况和目标网站性能合理设置超时时间\n3. **扩展路径**：使用绝对路径确保扩展能够正确加载\n4. **错误处理**：实现健壮的错误处理逻辑，特别是导航超时和执行上下文销毁场景\n5. **调试日志**：在开发阶段启用调试日志便于排查问题\n\n## 相关资源\n\n- [Puppeteer 官方文档](https://pptr.dev/)\n- [Chrome Extensions 文档](https://developer.chrome.com/docs/extensions/mv3/)\n- [Chrome DevTools Protocol 文档](https://chromedevtools.github.io/devtools-protocol/)\n- [WebDriver BiDi 规范](https://w3c.github.io/webdriver-bidi/)\n\n---\n\n<a id='page-coverage-debugging'></a>\n\n## 覆盖率检测与调试功能\n\n### 相关页面\n\n相关主题：[Page页面操作API](#page-page-api), [浏览器上下文与扩展支持](#page-contexts-extensions)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/cdp/Coverage.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Coverage.ts)\n- [packages/puppeteer-core/src/cdp/Accessibility.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Accessibility.ts)\n- [packages/puppeteer-core/src/cdp/Tracing.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Tracing.ts)\n- [packages/puppeteer-core/src/common/ConsoleMessage.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/ConsoleMessage.ts)\n- [packages/puppeteer-core/src/common/Errors.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Errors.ts)\n- [docs/guides/debugging.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/debugging.md)\n</details>\n\n# 覆盖率检测与调试功能\n\n## 概述\n\nPuppeteer 提供了丰富的覆盖率检测与调试功能，使开发者能够在浏览器自动化过程中收集性能指标、追踪代码执行、分析控制台输出以及诊断运行时错误。这些功能对于优化网页性能、调试自动化脚本以及生成详细的测试报告至关重要。\n\n覆盖率检测功能主要通过 Chrome DevTools Protocol (CDP) 实现，支持 JavaScript 代码覆盖率统计、堆快照捕获以及性能指标采集。调试功能则涵盖控制台消息捕获、页面事件监听、调试日志输出以及详细的错误报告机制。\n\n## 核心架构\n\n### 模块关系\n\nPuppeteer 的覆盖率检测与调试系统由多个核心模块组成，各模块协同工作以提供完整的诊断能力。\n\n```mermaid\ngraph TD\n    A[Puppeteer 核心层] --> B[覆盖率模块]\n    A --> C[调试模块]\n    A --> D[追踪模块]\n    B --> E[CDP Coverage API]\n    C --> F[ConsoleMessage 处理]\n    C --> G[Errors 处理]\n    D --> H[CDP Tracing API]\n    E --> I[CoverageResult]\n    F --> J[控制台事件]\n    G --> K[错误类型定义]\n    H --> L[追踪数据]\n```\n\n### 关键组件\n\n| 组件名称 | 文件路径 | 职责说明 |\n|---------|---------|----------|\n| Coverage | `packages/puppeteer-core/src/cdp/Coverage.ts` | 提供 JavaScript 和 CSS 覆盖率统计功能 |\n| Tracing | `packages/puppeteer-core/src/cdp/Tracing.ts` | 管理性能追踪和事件流记录 |\n| ConsoleMessage | `packages/puppeteer-core/src/common/ConsoleMessage.ts` | 处理和解析控制台消息 |\n| Errors | `packages/puppeteer-core/src/common/Errors.ts` | 定义错误类型和错误处理机制 |\n| Accessibility | `packages/puppeteer-core/src/cdp/Accessibility.ts` | 提供无障碍访问相关诊断 |\n\n## 覆盖率检测功能\n\n### JavaScript 代码覆盖率\n\nPuppeteer 支持获取页面的性能指标数据，这些数据包括文档数量、帧数、JavaScript 事件监听器数量、DOM 节点数量以及布局和样式重算的统计信息。\n\n性能指标数据结构定义如下：\n\n| 属性名 | 类型 | 说明 |\n|-------|------|------|\n| Timestamp | number | 指标采样的时间戳（单调递增） |\n| Documents | number | 页面中的文档数量 |\n| Frames | number | 页面中的帧数量 |\n| JSEventListeners | number | 页面中的 JavaScript 事件监听器数量 |\n| Nodes | number | DOM 节点总数 |\n| LayoutCount | number | 完整或部分页面布局的总次数 |\n| RecalcStyleCount | number | 页面样式重算的总次数 |\n| LayoutDuration | number | 所有页面布局的累计时长 |\n| RecalcStyleDuration | number | 所有样式重算的累计时长 |\n| ScriptDuration | number | JavaScript 执行的总时长 |\n| TaskDuration | number | 浏览器执行的所有任务累计时长 |\n| JSHeapUsedSize | number | 已使用的 JavaScript 堆大小 |\n| JSHeapTotalSize | number | JavaScript 堆总大小 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:250-290]()\n\n### 堆快照捕获\n\nPuppeteer 提供了 `captureHeapSnapshot()` 方法用于捕获 JavaScript 堆的快照并写入文件。这对于内存泄漏排查和堆内存分析非常有价值。该方法为抽象方法，需要在具体的 Page 实现中由 CDP 或其他浏览器协议实现。\n\n```typescript\n// 捕获堆快照的典型用法\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\n// 执行页面操作后捕获堆快照\nawait page.captureHeapSnapshot({ path: 'heap-snapshot.json' });\n\nawait browser.close();\n```\n\n### CSS 覆盖率\n\n通过 CDP 的 Coverage API，Puppeteer 能够追踪 CSS 规则的使用情况，帮助开发者识别页面中未使用的 CSS 样式。\n\n## 调试功能\n\n### 调试日志系统\n\nPuppeteer 实现了灵活的调试日志系统，支持通过环境变量 `window.__PUPPETEER_DEBUG` 配置日志输出级别和通道。\n\n```javascript\n// 输出所有调试日志\nwindow.__PUPPETEER_DEBUG = '*';\n\n// 输出特定通道的日志\nwindow.__PUPPETEER_DEBUG = 'Page';\n\n// 输出以指定前缀开头的所有通道\nwindow.__PUPPETEER_DEBUG = 'Page*';\n```\n\n调试日志函数接受一个前缀参数，该前缀会被添加到每条日志消息的开头，便于区分不同模块的输出：\n\n```typescript\nconst log = debug('Page');\nlog('new page created');\n// 输出: \"Page: new page created\"\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:30-60]()\n\n### 日志输出流程\n\n```mermaid\ngraph LR\n    A[日志调用] --> B{运行环境检测}\n    B -->|Node.js| C[debug 模块]\n    B -->|浏览器| D[环境变量检查]\n    D --> E{匹配检查}\n    E -->|完全匹配| F[console.log 输出]\n    E -->|通配符匹配| F\n    E -->|不匹配| G[无输出]\n    C --> H[异步日志输出]\n```\n\n### 控制台消息处理\n\nConsoleMessage 模块负责解析和传递来自页面的控制台消息。该模块支持多种消息类型，包括日志、警告、错误、信息和调试消息。\n\n| 消息类型 | 说明 | 典型用途 |\n|---------|------|---------|\n| log | 日志消息 | 一般性信息输出 |\n| warn | 警告消息 | 潜在问题的提示 |\n| error | 错误消息 | 运行时错误的报告 |\n| info | 信息消息 | 提示性信息 |\n| debug | 调试消息 | 开发调试信息 |\n\n监听控制台消息的标准模式：\n\n```typescript\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\npage.on('console', msg => {\n  console.log(`[${msg.type()}] ${msg.text()}`);\n});\n\nawait page.goto('https://example.com');\n\nawait browser.close();\n```\n\n资料来源：[packages/puppeteer-core/src/common/ConsoleMessage.ts]()\n\n### 错误处理机制\n\nPuppeteer 定义了完整的错误类型体系，确保各种运行时异常能够被正确识别和处理。\n\n| 错误类型 | 错误码 | 说明 |\n|---------|-------|------|\n| UnsupportedOperationError | 错误码定义在 Errors.ts | 不支持的操作错误 |\n| EvaluationError | 错误码定义在 Errors.ts | JavaScript 评估错误 |\n| TimeoutError | 错误码定义在 Errors.ts | 操作超时错误 |\n| ProtocolError | 错误码定义在 Errors.ts | CDP 协议通信错误 |\n\n评估上下文中发生的异常会被捕获并转换为结构化的错误对象：\n\n```typescript\nconst {exceptionDetails, result: remoteObject} = await this.#client\n  .send('Runtime.evaluate', {\n    expression: expressionWithSourceUrl,\n    contextId,\n    returnByValue,\n    awaitPromise: true,\n    userGesture: true,\n  })\n  .catch(rewriteError);\n\nif (exceptionDetails) {\n  throw createEvaluationError(exceptionDetails);\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/ExecutionContext.ts:40-70]()\n\n## 性能追踪功能\n\n### Tracing 模块概述\n\nTracing 模块提供了强大的性能追踪能力，能够记录页面的各种事件流并生成详细的追踪报告。这对于分析页面加载性能、识别性能瓶颈以及生成 Chrome DevTools 兼容的追踪文件非常有用。\n\n### 追踪数据流\n\n```mermaid\ngraph TD\n    A[追踪开始] --> B[CDP Tracing.start]\n    B --> C[事件收集阶段]\n    C --> D[Page 事件]\n    C --> E[Network 事件]\n    C --> F[JavaScript 事件]\n    D --> G[缓冲区写入]\n    E --> G\n    F --> G\n    G --> H[CDP Tracing.end]\n    H --> I[追踪数据处理]\n    I --> J[结果输出]\n```\n\n## 无障碍功能诊断\n\nAccessibility 模块提供了页面无障碍访问相关的诊断能力，帮助开发者检查页面元素的可访问性属性。\n\n### ARIA 选择器支持\n\nPuppeteer 支持通过 ARIA 选择器查询页面元素，这依赖于 Accessibility 组件提供的基础能力：\n\n```typescript\n// 使用 ARIA 选择器定位元素\nawait page.locator('::-p-aria(Search)').fill('automate beyond recorder');\n```\n\n## 配置选项\n\n### 覆盖率相关配置\n\n| 配置项 | 类型 | 默认值 | 说明 |\n|-------|------|-------|------|\n| defaultBrowser | SupportedBrowser | 'chrome' | 默认浏览器类型 |\n| temporaryDirectory | string | os.tmpdir() | 临时文件目录 |\n| skipDownload | boolean | false | 是否跳过浏览器下载 |\n| logLevel | 'silent' \\| 'error' \\| 'warn' | 'warn' | 日志级别 |\n\n### 浏览器启动调试选项\n\n| 选项名称 | 类型 | 说明 |\n|---------|------|------|\n| executablePath | string | 浏览器可执行文件路径 |\n| ignoreDefaultArgs | boolean \\| string[] | 是否忽略默认参数 |\n| enableExtensions | boolean \\| string[] | 启用扩展支持 |\n| handleSIGINT | boolean | 是否处理 Ctrl+C 信号 |\n| handleSIGTERM | boolean | 是否处理 SIGTERM 信号 |\n| handleSIGHUP | boolean | 是否处理 SIGHUP 信号 |\n| timeout | number | 浏览器启动超时时间（毫秒） |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:40-80]()\n\n## 最佳实践\n\n### 调试模式启用\n\n在开发环境中启用完整调试日志：\n\n```bash\nPUPPETEER_DEBUG='*' node your-script.js\n```\n\n### 性能分析工作流\n\n1. **启动追踪**：使用 Tracing API 开始记录性能数据\n2. **执行操作**：在页面上执行待分析的操作\n3. **结束追踪**：停止数据收集并获取结果\n4. **分析结果**：使用 Chrome DevTools 或其他工具分析追踪数据\n\n### 覆盖率采集建议\n\n- 在关键测试场景中启用覆盖率统计\n- 定期检查未使用的 CSS 和 JavaScript 代码\n- 结合性能指标识别优化机会\n\n## 相关资源\n\n- [Puppeteer 官方文档](https://pptr.dev)\n- [Chrome DevTools Protocol 文档](https://chromedevtools.github.io/devtools-protocol/)\n- [调试功能指南](../guides/debugging.md)\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：puppeteer/puppeteer\n\n摘要：发现 21 个潜在踩坑项，其中 4 个为 high/blocking；最高优先级：安装坑 - 来源证据：Chrome Canary/Firefox Nightly test results。\n\n## 1. 安装坑 · 来源证据：Chrome Canary/Firefox Nightly test results\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Chrome Canary/Firefox Nightly test results\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1aabe120a9df47a2adbd293381b50a64 | https://github.com/puppeteer/puppeteer/issues/12379 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 2. 安装坑 · 来源证据：Puppeteer v25\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Puppeteer v25\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_050f65ceff2a455da4a3538895a7538b | https://github.com/puppeteer/puppeteer/issues/14342 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 3. 安全/权限坑 · 来源证据：[Bug]: GHSA issued a false malicious package alert for puppeteer\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: GHSA issued a false malicious package alert for puppeteer\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_55588dfbd41442fdb8a2f4f1be57e4c9 | https://github.com/puppeteer/puppeteer/issues/14986 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 4. 安全/权限坑 · 来源证据：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_9b1ef7c38ed14c41b3e4ce786adcdf26 | https://github.com/puppeteer/puppeteer/issues/14774 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。\n\n## 5. 安装坑 · 来源证据：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_5d1f448d8768460a806ab32e8d4f6997 | https://github.com/puppeteer/puppeteer/issues/14957 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 6. 安装坑 · 来源证据：[Bug]: `setViewport` crashes on Firefox if uncaught\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: `setViewport` crashes on Firefox if uncaught\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_75bddb8a74194cf7a8978853f19db23a | https://github.com/puppeteer/puppeteer/issues/14989 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 7. 安装坑 · 来源证据：[Bug]: chrome binary is not present when installing latest chrome\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: chrome binary is not present when installing latest chrome\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1e85cdab2b684dda8e5c83f55b8ff7b6 | https://github.com/puppeteer/puppeteer/issues/14988 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 8. 安装坑 · 来源证据：[Feature]: Make proxy-agent dependency optional\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Feature]: Make proxy-agent dependency optional\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_195c51e4a5e84edda14a2a79b456821c | https://github.com/puppeteer/puppeteer/issues/13775 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 9. 安装坑 · 来源证据：browsers: v3.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：browsers: v3.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_bf2d83568c54447fbfd3047d24be0c48 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 10. 能力坑 · 来源证据：browsers: v3.0.2\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：browsers: v3.0.2\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_c9f08632e7ee4e9485d27b864a21e462 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 11. 能力坑 · 来源证据：puppeteer-core: v25.0.2\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：puppeteer-core: v25.0.2\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3a8b10a5263e4d6488e16972c8249a38 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 12. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:90796663 | https://github.com/puppeteer/puppeteer | README/documentation is current enough for a first validation pass.\n\n## 13. 维护坑 · 来源证据：ng-schematics: v0.8.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：ng-schematics: v0.8.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_4e7ee6a70b1d4fb6879ab4670099d205 | https://github.com/puppeteer/puppeteer/releases/tag/ng-schematics-v0.8.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 14. 维护坑 · 来源证据：puppeteer-core: v25.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer-core: v25.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3e6a5770b15146ddab5249f1aa687cae | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 15. 维护坑 · 来源证据：puppeteer: v25.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer: v25.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_9294fdbab95d446887bdb54a11df66d2 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 16. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | last_activity_observed missing\n\n## 17. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium\n\n## 18. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium\n\n## 19. 安全/权限坑 · 来源证据：[Feature]: Reducing dependencies\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Feature]: Reducing dependencies\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_cb21a546ebb04ca39b334255b205c9da | https://github.com/puppeteer/puppeteer/issues/13552 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 20. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | issue_or_pr_quality=unknown\n\n## 21. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | release_recency=unknown\n\n<!-- canonical_name: puppeteer/puppeteer; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "puppeteer",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:90796663",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/puppeteer/puppeteer"
        },
        {
          "evidence_id": "art_98bdc3ac95604419bbb62b7ca1e325c0",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/puppeteer/puppeteer#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "puppeteer 说明书",
      "toc": [
        "https://github.com/puppeteer/puppeteer 项目说明书",
        "目录",
        "Puppeteer项目概览",
        "1. 项目简介",
        "2. 项目架构",
        "3. 安装与配置",
        "完整安装（自动下载Chrome）",
        "仅安装核心库（不下载浏览器）",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "3aadc38c533caa8df87f381868291ede870883e2",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "package.json",
      "README.md",
      "docs/contributing.md",
      "docs/index.md",
      "docs/troubleshooting.md",
      "docs/webdriver-bidi.md",
      "docs/examples.md",
      "docs/faq.md",
      "docs/supported-browsers.md",
      "docs/CHANGELOG.md",
      "docs/api/puppeteer.page.emulate.md",
      "docs/api/puppeteer.locatorevents.md",
      "docs/api/puppeteer.page.windowid.md",
      "docs/api/puppeteer.page.evaluatehandle.md",
      "docs/api/puppeteer.page.bringtofront.md",
      "docs/api/puppeteer.commoneventemitter.removealllisteners.md",
      "docs/api/puppeteer.quad.md",
      "docs/api/puppeteer.page.setuseragent.md",
      "docs/api/puppeteer.browser.setcookie.md",
      "docs/api/puppeteer.permissionstate_2.md",
      "docs/api/puppeteer.puppeteernode.trimcache.md",
      "docs/api/puppeteer.httprequest.postdata.md",
      "docs/api/puppeteer.mouse.drop.md",
      "docs/api/puppeteer.page.setrequestinterception.md",
      "docs/api/puppeteer.customqueryhandler.md",
      "docs/api/puppeteer.puppeteernode.defaultargs.md",
      "docs/api/puppeteer.browser.wsendpoint.md",
      "docs/api/puppeteer.page.browser.md",
      "docs/api/puppeteer.networkconditions.md",
      "docs/api/puppeteer.executablepath.md",
      "docs/api/puppeteer.downloadpolicy.md",
      "docs/api/puppeteer.offset.md",
      "docs/api/puppeteer.resourcetype.md",
      "docs/api/puppeteer.devicerequestprompt.cancel.md",
      "docs/api/puppeteer.jshandle.getproperties.md",
      "docs/api/puppeteer.predicate.md",
      "docs/api/puppeteer.coverage.md",
      "docs/api/puppeteer.evaluatefuncwith.md",
      "docs/api/puppeteer.touchscreen.tap.md",
      "docs/api/puppeteer.pageevent.md"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# puppeteer-repo - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 puppeteer-repo 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **想在安装前理解开源项目价值和边界的用户**：当前证据主要来自项目文档。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md`, `packages/browsers/README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `npm i puppeteer # Downloads compatible Chrome during installation.` 证据：`README.md` Claim：`clm_0003` supported 0.86\n- `npm i puppeteer-core # Alternatively, install as a library, without downloading Chrome.` 证据：`README.md` Claim：`clm_0004` supported 0.86\n- `npx @puppeteer/browsers --help` 证据：`packages/browsers/README.md` Claim：`clm_0005` supported 0.86, `clm_0006` supported 0.86\n- `npx @puppeteer/browsers --help # help for all commands` 证据：`packages/browsers/README.md` Claim：`clm_0006` supported 0.86\n- `npx @puppeteer/browsers install --help # help for the install command` 证据：`packages/browsers/README.md` Claim：`clm_0007` supported 0.86\n- `npx @puppeteer/browsers launch --help # help for the launch command` 证据：`packages/browsers/README.md` Claim：`clm_0008` supported 0.86\n- `npx @puppeteer/browsers clear --help # help for the clear command` 证据：`packages/browsers/README.md` Claim：`clm_0009` supported 0.86\n- `npx @puppeteer/browsers list --help # help for the list command` 证据：`packages/browsers/README.md` Claim：`clm_0010` supported 0.86\n- `npx @puppeteer/browsers@latest --help` 证据：`packages/browsers/README.md` Claim：`clm_0011` supported 0.86\n- `npx @puppeteer/browsers@2.4.1 --help` 证据：`packages/browsers/README.md` Claim：`clm_0012` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：需要管理员/安全审批\n- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。\n\n### 30 秒判断\n\n- **现在怎么做**：需要管理员/安全审批\n- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装\n- **先别相信**：角色质量和任务匹配不能直接相信。\n- **继续会触碰**：角色选择偏差、命令执行、本地环境或项目文件\n\n### 现在可以相信\n\n- **适合人群线索：想在安装前理解开源项目价值和边界的用户**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md`, `packages/browsers/README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **角色质量和任务匹配不能直接相信。**（unverified）：角色库证明有很多角色，不证明每个角色都适合你的具体任务，也不证明角色能产生高质量结果。\n- **不能把角色文案当成真实执行能力。**（unverified）：安装前只能判断角色描述和任务画像是否匹配，不能证明它能在宿主 AI 里完成任务。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n\n### 继续会触碰什么\n\n- **角色选择偏差**：用户对任务应该由哪个专家角色处理的判断。 原因：选错角色会让 AI 从错误专业视角回答，浪费时间或误导决策。\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`, `packages/browsers/README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`, `packages/browsers/README.md`\n- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`package.json`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：先用交互式试用验证任务画像和角色匹配，不要先导入整套角色库。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **保留原始角色选择记录**：如果输出偏题，可以回到任务画像阶段重新选择角色，而不是继续沿着错误角色推进。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0023` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md`, `packages/browsers/README.md` Claim：`clm_0024` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md`, `packages/browsers/README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：2105\n- 重要文件覆盖：40/2105\n- 证据索引条目：80\n- 角色 / Skill 条目：63\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 puppeteer-repo 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 puppeteer-repo 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 puppeteer-repo 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 63 个角色 / Skill / 项目文档条目。\n\n- **Contributing**（project_doc）：First of all, thank you for your interest in Puppeteer! We'd love to accept your patches and contributions! 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/contributing.md`\n- **Puppeteer**（project_doc）：! build https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml/badge.svg?branch=main https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml ! npm puppeteer package https://img.shields.io/npm/v/puppeteer.svg https://npmjs.org/package/puppeteer 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **Dockerfile for Puppeteer**（project_doc）：This directory contains files needed to containerize Puppeteer. The major problem that this is solving is the problem of providing all dependencies required to run a browser instance. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docker/README.md`\n- **Puppeteer: Examples**（project_doc）：This is the official set of Puppeteer examples. For a list of curated examples and use-cases, including third-party ones, see pptr.dev/examples https://pptr.dev/examples . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/README.md`\n- **Puppeteer tests**（project_doc）：Unit tests in Puppeteer are written using Mocha as the test runner and Expect as the assertions library. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`test/README.md`\n- **Website**（project_doc）：This website is built using Docusaurus 3 https://docusaurus.io/ . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`website/README.md`\n- **@puppeteer/browsers**（project_doc）：Manage and launch browsers/drivers from a CLI or programmatically. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/browsers/README.md`\n- **Puppeteer Angular Schematic**（project_doc）：Adds Puppeteer-based e2e tests to your Angular project. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/ng-schematics/README.md`\n- **bidi/core**（project_doc）：bidi/core is a low-level layer that sits above the WebDriver BiDi transport to provide a structured API to WebDriver BiDi's flat API. In particular, bidi/core provides object-oriented semantics around WebDriver BiDi resources and automatically carries out the correct order of events in WebDriver BiDi through the use of events. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/puppeteer-core/src/bidi/core/README.md`\n- **Injected**（project_doc）：This folder contains code that is injected into every Puppeteer execution context. Each file is transpiled using esbuild into a script in src/generated which is then imported into server code. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/puppeteer-core/src/injected/README.md`\n- **Templated Artifacts**（project_doc）：These files are generated as TypeScript files in the src/generated folder. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/puppeteer-core/src/templates/README.md`\n- **third party**（project_doc）：This folder contains code that interacts with third party node modules that will be vendored with puppeteer during publishing. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/puppeteer-core/third_party/README.md`\n- **Mocha Runner**（project_doc）：Mocha Runner is a test runner on top of mocha. It uses /test/TestSuites.json and /test/TestExpectations.json files to run mocha tests in multiple configurations and interpret results. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`tools/mocha-runner/README.md`\n- **Contributing**（project_doc）：First of all, thank you for your interest in Puppeteer! We'd love to accept your patches and contributions! 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`website/versioned_docs/version-25.0.2/contributing.md`\n- **TestServer**（project_doc）：This test server is used internally by Puppeteer to test Puppeteer itself. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/testserver/README.md`\n- **Changelog**（project_doc）：Combined changelog for puppeteer and puppeteer-core. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/CHANGELOG.md`\n- **Examples & Use cases**（project_doc）：The Puppeteer repository https://github.com/puppeteer/puppeteer/tree/main/examples includes a small number of examples maintained by the Puppeteer team. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/examples.md`\n- **FAQ**（project_doc）：The Chrome Browser Automation team maintains the library, but we'd love your help and expertise on the project! See our contributing guide https://pptr.dev/contributing . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/faq.md`\n- **Puppeteer**（project_doc）：! build https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml/badge.svg?branch=main https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml ! npm puppeteer package https://img.shields.io/npm/v/puppeteer.svg https://npmjs.org/package/puppeteer 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/index.md`\n- **Supported browsers**（project_doc）：Starting with v20.0.0 Puppeteer downloads and works with Chrome for Testing https://github.com/GoogleChromeLabs/chrome-for-testing?tab=readme-ov-file what-is-chrome-for-testing , which supports both headless and headful modes sharing the same code path in the browser. The old headless mode is now a separate program called chrome-headless-shell https://developer.chrome.com/blog/chrome-headless-shell use headless: 'sh… 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/supported-browsers.md`\n- **Troubleshooting**（project_doc）：To keep this page up-to-date we largely rely on community contributions. Please send a PR if you notice something is no longer up-to-date. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/troubleshooting.md`\n- **WebDriver BiDi support**（project_doc）：WebDriver BiDi https://w3c.github.io/webdriver-bidi/ is a new cross-browser automation protocol currently under development, aiming to combine the best of both WebDriver “Classic” and CDP. WebDriver BiDi enables bi-directional communication, making it fast by default, and it comes packed with low-level control. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/webdriver-bidi.md`\n- **API Reference**（project_doc）：Accessibility ./puppeteer.accessibility.md 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/index.md`\n- **Accessibility class**（project_doc）：The Accessibility class provides methods for inspecting the browser's accessibility tree. The accessibility tree is used by assistive technology such as screen readers https://en.wikipedia.org/wiki/Screen reader or switches https://en.wikipedia.org/wiki/Switch access . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.accessibility.md`\n- **Accessibility.snapshot method**（project_doc）：Captures the current state of the accessibility tree. The returned object represents the root accessible node of the page. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.accessibility.snapshot.md`\n- **ActionOptions interface**（project_doc）：A signal to abort the locator action. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.actionoptions.md`\n- **ActionResult type**（project_doc）： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.actionresult.md`\n- **AdapterState type**（project_doc）： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.adapterstate.md`\n- **AddScreenParams interface**（project_doc）：WorkAreaInsets ./puppeteer.workareainsets.md 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.addscreenparams.md`\n- **AutofillAddressField enum**（project_doc）：Supported autofill address field names. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.autofilladdressfield.md`\n- **AutofillData type**（project_doc）：References: AutofillAddressField ./puppeteer.autofilladdressfield.md 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.autofilldata.md`\n- **Awaitable type**（project_doc）： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.awaitable.md`\n- **AwaitableIterable type**（project_doc）： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.awaitableiterable.md`\n- **AwaitablePredicate type**（project_doc）：References: Awaitable ./puppeteer.awaitable.md 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.awaitablepredicate.md`\n- **AwaitedLocator type**（project_doc）：References: Locator ./puppeteer.locator.md 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.awaitedlocator.md`\n- **BluetoothEmulation.disableEmulation method**（project_doc）：BluetoothEmulation.disableEmulation method 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.bluetoothemulation.disableemulation.md`\n- **BluetoothEmulation.emulateAdapter method**（project_doc）：BluetoothEmulation.emulateAdapter method 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.bluetoothemulation.emulateadapter.md`\n- **BluetoothEmulation interface**（project_doc）：Exposes the bluetooth emulation abilities. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.bluetoothemulation.md`\n- **BluetoothEmulation.simulatePreconnectedPeripheral method**（project_doc）：BluetoothEmulation.simulatePreconnectedPeripheral method 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.bluetoothemulation.simulatepreconnectedperipheral.md`\n- **BluetoothManufacturerData interface**（project_doc）：BluetoothManufacturerData interface 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.bluetoothmanufacturerdata.md`\n- **BoundingBox interface**（project_doc）：Extends: Point ./puppeteer.point.md 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.boundingbox.md`\n- **BoxModel interface**（project_doc）： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.boxmodel.md`\n- **Browser.addScreen method**（project_doc）：Adds a new screen, returns the added screen information object ./puppeteer.screeninfo.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.addscreen.md`\n- **Browser.browserContexts method**（project_doc）：Gets a list of open browser contexts ./puppeteer.browsercontext.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.browsercontexts.md`\n- **Browser.close method**（project_doc）：Closes this browser ./puppeteer.browser.md and all associated pages ./puppeteer.page.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.close.md`\n- **Browser.cookies method**（project_doc）：Returns all cookies in the default BrowserContext ./puppeteer.browsercontext.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.cookies.md`\n- **Browser.createBrowserContext method**（project_doc）：Browser.createBrowserContext method 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.createbrowsercontext.md`\n- **Browser.defaultBrowserContext method**（project_doc）：Browser.defaultBrowserContext method 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.defaultbrowsercontext.md`\n- **Browser.deleteCookie method**（project_doc）：Removes cookies from the default BrowserContext ./puppeteer.browsercontext.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.deletecookie.md`\n- **Browser.deleteMatchingCookies method**（project_doc）：Browser.deleteMatchingCookies method 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.deletematchingcookies.md`\n- **Browser.disconnect method**（project_doc）：Disconnects Puppeteer from this browser ./puppeteer.browser.md , but leaves the process running. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.disconnect.md`\n- **Browser.extensions method**（project_doc）：Retrieves a map of all extensions installed in the browser, where the keys are extension IDs and the values are the corresponding Extension ./puppeteer.extension.md instances. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.extensions.md`\n- **Browser.getWindowBounds method**（project_doc）：Gets the specified window bounds ./puppeteer.windowbounds.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.getwindowbounds.md`\n- **Browser.installExtension method**（project_doc）：Installs an extension and returns the ID. In Chrome, this is only available if the browser was created using pipe: true and the --enable-unsafe-extension-debugging flag is set. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.installextension.md`\n- **Browser class**（project_doc）：Browser ./puppeteer.browser.md represents a browser instance that is either: 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.md`\n- **Browser.newPage method**（project_doc）：Creates a new page ./puppeteer.page.md in the default browser context ./puppeteer.browser.defaultbrowsercontext.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.newpage.md`\n- **Browser.pages method**（project_doc）：Gets a list of all open pages ./puppeteer.page.md inside this Browser ./puppeteer.browser.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.pages.md`\n- **Browser.process method**（project_doc）：Gets the associated ChildProcess https://nodejs.org/api/child process.html class-childprocess . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.process.md`\n- **Browser.removeScreen method**（project_doc）：Only supported in headless mode. Fails if the primary screen id is specified. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.removescreen.md`\n- **Browser.screens method**（project_doc）：Gets a list of screen information objects ./puppeteer.screeninfo.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.screens.md`\n- **Browser.setCookie method**（project_doc）：Sets cookies in the default BrowserContext ./puppeteer.browsercontext.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.setcookie.md`\n- **Browser.setPermission method**（project_doc）：Sets the permission for a specific origin in the default BrowserContext ./puppeteer.browsercontext.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.setpermission.md`\n- **Browser.setWindowBounds method**（project_doc）：Sets the specified window bounds ./puppeteer.windowbounds.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/puppeteer.browser.setwindowbounds.md`\n\n## 证据索引\n\n- 共索引 80 条证据。\n\n- **Contributing**（documentation）：First of all, thank you for your interest in Puppeteer! We'd love to accept your patches and contributions! 证据：`docs/contributing.md`\n- **Puppeteer**（documentation）：! build https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml/badge.svg?branch=main https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml ! npm puppeteer package https://img.shields.io/npm/v/puppeteer.svg https://npmjs.org/package/puppeteer 证据：`README.md`\n- **Dockerfile for Puppeteer**（documentation）：This directory contains files needed to containerize Puppeteer. The major problem that this is solving is the problem of providing all dependencies required to run a browser instance. 证据：`docker/README.md`\n- **Puppeteer: Examples**（documentation）：This is the official set of Puppeteer examples. For a list of curated examples and use-cases, including third-party ones, see pptr.dev/examples https://pptr.dev/examples . 证据：`examples/README.md`\n- **Puppeteer tests**（documentation）：Unit tests in Puppeteer are written using Mocha as the test runner and Expect as the assertions library. 证据：`test/README.md`\n- **Website**（documentation）：This website is built using Docusaurus 3 https://docusaurus.io/ . 证据：`website/README.md`\n- **@puppeteer/browsers**（documentation）：Manage and launch browsers/drivers from a CLI or programmatically. 证据：`packages/browsers/README.md`\n- **Puppeteer Angular Schematic**（documentation）：Adds Puppeteer-based e2e tests to your Angular project. 证据：`packages/ng-schematics/README.md`\n- **bidi/core**（documentation）：bidi/core is a low-level layer that sits above the WebDriver BiDi transport to provide a structured API to WebDriver BiDi's flat API. In particular, bidi/core provides object-oriented semantics around WebDriver BiDi resources and automatically carries out the correct order of events in WebDriver BiDi through the use of events. 证据：`packages/puppeteer-core/src/bidi/core/README.md`\n- **Injected**（documentation）：This folder contains code that is injected into every Puppeteer execution context. Each file is transpiled using esbuild into a script in src/generated which is then imported into server code. 证据：`packages/puppeteer-core/src/injected/README.md`\n- **Templated Artifacts**（documentation）：These files are generated as TypeScript files in the src/generated folder. 证据：`packages/puppeteer-core/src/templates/README.md`\n- **third party**（documentation）：This folder contains code that interacts with third party node modules that will be vendored with puppeteer during publishing. 证据：`packages/puppeteer-core/third_party/README.md`\n- **Mocha Runner**（documentation）：Mocha Runner is a test runner on top of mocha. It uses /test/TestSuites.json and /test/TestExpectations.json files to run mocha tests in multiple configurations and interpret results. 证据：`tools/mocha-runner/README.md`\n- **Package**（package_manifest）：{ \"name\": \"puppeteer-repo\", \"private\": true, \"repository\": { \"type\": \"git\", \"url\": \"https://github.com/puppeteer/puppeteer\" }, \"type\": \"module\", \"scripts\": { \"build\": \"wireit\", \"build:tools\": \"wireit\", \"check\": \"npm run check --workspaces --if-present\", \"clean\": \"npm run clean --workspaces --if-present\", \"debug\": \"mocha --inspect-brk\", \"docs\": \"wireit\", \"doctest\": \"wireit\", \"format\": \"wireit\", \"format:eslint\": \"wireit\", \"format:expectations\": \"node tools/sort-test-expectations.mjs\", \"format:prettier\": \"prettier --write --cache . \", \"lint\": \"wireit\", \"lint:eslint\": \"wireit\", \"lint:prettier\": \"prettier --check --cache .\", \"lint:expectations\": \"node tools/sort-test-expectations.mjs --lint\", \"p… 证据：`package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer-test/test\", \"version\": \"latest\", \"private\": true, \"type\": \"module\", \"scripts\": { \"build\": \"wireit\", \"clean\": \"../tools/clean.mjs\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b\", \"clean\": \"if-file-deleted\", \"dependencies\": \"../packages/puppeteer:build\", \"../packages/testserver:build\" , \"files\": \"src/ \" , \"output\": \"build/ \", \"tsconfig.tsbuildinfo\" } }, \"dependencies\": { \"diff\": \"9.0.0\", \"mime\": \"4.1.0\", \"jpeg-js\": \"0.4.4\", \"pixelmatch\": \"7.1.0\", \"pngjs\": \"7.0.0\" }, \"devDependencies\": { \"@types/pngjs\": \"6.0.5\" } } 证据：`test/package.json`\n- **Package**（package_manifest）：{ \"name\": \"website\", \"version\": \"0.0.0\", \"private\": true, \"scripts\": { \"docusaurus\": \"docusaurus\", \"start\": \"docusaurus start\", \"build\": \"docusaurus build\", \"swizzle\": \"docusaurus swizzle\", \"deploy\": \"docusaurus deploy\", \"clear\": \"docusaurus clear\", \"serve\": \"docusaurus serve\", \"write-translations\": \"docusaurus write-translations\", \"write-heading-ids\": \"docusaurus write-heading-ids\", \"archive\": \"node archive.js\" }, \"dependencies\": { \"@docsearch/react\": \"4.6.3\", \"@docusaurus/core\": \"3.10.1\", \"@docusaurus/plugin-client-redirects\": \"3.10.1\", \"@docusaurus/plugin-content-docs\": \"3.10.1\", \"@docusaurus/preset-classic\": \"3.10.1\", \"@docusaurus/remark-plugin-npm2yarn\": \"3.10.1\", \"@docusaurus/theme-co… 证据：`website/package.json`\n- **Package**（package_manifest）：{ \"name\": \"puppeteer-in-browser\", \"version\": \"1.0.0\", \"description\": \"\", \"main\": \"index.js\", \"scripts\": { \"build\": \"rm -rf out && rollup -c && terser out/main.js --compress --mangle --output out/main.min.js && gzip -k --best -r -f out\" }, \"keywords\": , \"author\": \"\", \"license\": \"MIT\", \"devDependencies\": { \"@rollup/plugin-node-resolve\": \"^15.2.3\", \"rollup\": \"^4.59.0\", \"terser\": \"^5.30.4\" } } 证据：`examples/puppeteer-in-browser/package.json`\n- **Package**（package_manifest）：{ \"name\": \"puppeteer-in-extension\", \"version\": \"1.0.0\", \"description\": \"\", \"main\": \"index.js\", \"scripts\": { \"build\": \"rollup -c && cp manifest.json out/\" }, \"keywords\": , \"author\": \"\", \"license\": \"MIT\", \"devDependencies\": { \"@rollup/plugin-node-resolve\": \"^15.2.3\", \"rollup\": \"^4.59.0\" } } 证据：`examples/puppeteer-in-extension/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer/browsers\", \"version\": \"3.0.2\", \"description\": \"Download and launch browsers\", \"scripts\": { \"build:docs\": \"wireit\", \"build\": \"wireit\", \"build:test\": \"wireit\", \"clean\": \"../../tools/clean.mjs\", \"test\": \"wireit\" }, \"type\": \"module\", \"bin\": \"lib/main-cli.js\", \"main\": \"./lib/main.js\", \"module\": \"./lib/main.js\", \"wireit\": { \"build\": { \"command\": \"tsc -b && node --experimental-strip-types ../../tools/chmod.ts 755 lib/main-cli.js\", \"files\": \"src/ / .ts\", \"tsconfig.json\" , \"clean\": \"if-file-deleted\", \"output\": \"lib/ \" }, \"build:docs\": { \"command\": \"api-extractor run --local --config \\\"./api-extractor.docs.json\\\"\", \"files\": \"api-extractor.docs.json\", \"lib/main.d.ts\", \"tsconfig.j… 证据：`packages/browsers/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer/ng-schematics\", \"version\": \"0.8.0\", \"description\": \"Puppeteer Angular schematics\", \"type\": \"module\", \"scripts\": { \"build\": \"wireit\", \"clean\": \"../../tools/clean.mjs\", \"dev:test\": \"npm run test --watch\", \"dev\": \"npm run build --watch\", \"unit\": \"wireit\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b && node tools/copySchemaFiles.mjs\", \"clean\": \"if-file-deleted\", \"files\": \"tsconfig.json\", \"tsconfig.test.json\", \"src/ \", \"test/src/ \" , \"output\": \"lib/ \", \"test/build/ \", \" .tsbuildinfo\" }, \"build:test\": { \"command\": \"tsc -b test/tsconfig.json\" }, \"unit\": { \"command\": \"node --test --test-reporter=spec \\\"test/build/ / .test.js\\\"\", \"dependencies\": \"build\", \"build:test\" } }, \"keyw… 证据：`packages/ng-schematics/package.json`\n- **Package**（package_manifest）：{ \"name\": \"puppeteer-core\", \"version\": \"25.0.2\", \"description\": \"A high-level API to control headless Chrome over the DevTools Protocol\", \"keywords\": \"puppeteer\", \"chrome\", \"headless\", \"automation\" , \"type\": \"module\", \"main\": \"./lib/puppeteer/puppeteer-core.js\", \"browser\": \"./lib/puppeteer/puppeteer-core-browser.js\", \"module\": \"./lib/puppeteer/puppeteer-core.js\", \"types\": \"./lib/types.d.ts\", \"exports\": { \".\": { \"types\": \"./lib/types.d.ts\", \"import\": \"./lib/puppeteer/puppeteer-core.js\", \"require\": \"./lib/puppeteer/puppeteer-core.js\" }, \"./internal/ \": { \"import\": \"./lib/puppeteer/ \", \"require\": \"./lib/puppeteer/ \" }, \"./ \": { \"import\": \"./ \", \"require\": \"./ \" } }, \"repository\": { \"type\": \"gi… 证据：`packages/puppeteer-core/package.json`\n- **Package**（package_manifest）：{ \"type\": \"module\" } 证据：`packages/puppeteer-core/third_party/parsel-js/package.json`\n- **Package**（package_manifest）：{ \"name\": \"puppeteer\", \"version\": \"25.0.2\", \"description\": \"A high-level API to control headless Chrome over the DevTools Protocol\", \"keywords\": \"puppeteer\", \"chrome\", \"headless\", \"automation\" , \"type\": \"module\", \"bin\": \"./lib/puppeteer/node/cli.js\", \"main\": \"./lib/puppeteer/puppeteer.js\", \"module\": \"./lib/puppeteer/puppeteer.js\", \"types\": \"./lib/types.d.ts\", \"exports\": { \".\": { \"types\": \"./lib/types.d.ts\", \"import\": \"./lib/puppeteer/puppeteer.js\", \"require\": \"./lib/puppeteer/puppeteer.js\" }, \"./internal/ \": { \"import\": \"./lib/puppeteer/ \", \"require\": \"./lib/puppeteer/ \" }, \"./ \": { \"import\": \"./ \", \"require\": \"./ \" } }, \"repository\": { \"type\": \"git\", \"url\": \"https://github.com/puppeteer/pu… 证据：`packages/puppeteer/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer-test/installation\", \"version\": \"latest\", \"type\": \"module\", \"private\": true, \"scripts\": { \"build\": \"wireit\", \"clean\": \"../../tools/clean.mjs\", \"test\": \"wireit\", \"test-ci\": \"mocha\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b\", \"clean\": \"if-file-deleted\", \"dependencies\": \"build:packages\" , \"files\": \"tsconfig.json\", \"src/ \" , \"output\": \"build/ \", \"tsconfig.tsbuildinfo\" }, \"build:packages\": { \"command\": \"npm pack --quiet --workspace puppeteer --workspace puppeteer-core --workspace @puppeteer/browsers\", \"dependencies\": \"../../packages/puppeteer:build\", \"../../packages/puppeteer-core:build\", \"../../packages/browsers:build\", \"../../packages/testserver:build\" , \"files\": , \"out… 证据：`test/installation/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer/docgen\", \"version\": \"0.1.0\", \"type\": \"module\", \"private\": true, \"main\": \"./lib/docgen.js\", \"description\": \"Documentation generator for Puppeteer\", \"license\": \"Apache-2.0\", \"scripts\": { \"build\": \"wireit\", \"clean\": \"../clean.mjs\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b\", \"clean\": \"if-file-deleted\", \"files\": \"src/ \" , \"output\": \"lib/ \", \"tsconfig.tsbuildinfo\" } }, \"devDependencies\": { \"@microsoft/api-documenter\": \"7.30.5\", \"@microsoft/api-extractor-model\": \"7.33.8\", \"@microsoft/tsdoc\": \"0.16.0\", \"@rushstack/node-core-library\": \"5.22.0\" } } 证据：`tools/docgen/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer/doctest\", \"version\": \"0.1.0\", \"type\": \"module\", \"private\": true, \"bin\": \"./bin/doctest.js\", \"description\": \"Tests JSDoc @example code within a file.\", \"license\": \"Apache-2.0\", \"scripts\": { \"build\": \"wireit\", \"clean\": \"../clean.mjs\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b && node --experimental-strip-types ../../tools/chmod.ts 755 ./bin/doctest.js\", \"clean\": \"if-file-deleted\", \"files\": \"src/ \" , \"output\": \"bin/ \", \"tsconfig.tsbuildinfo\" } }, \"devDependencies\": { \"@swc/core\": \"1.15.33\", \"@types/doctrine\": \"0.0.9\", \"@types/source-map-support\": \"0.5.10\", \"@types/yargs\": \"17.0.33\", \"acorn\": \"8.16.0\", \"doctrine\": \"3.0.0\", \"glob\": \"13.0.6\", \"package-directory\": \"8.2.0\",… 证据：`tools/doctest/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer/eslint\", \"version\": \"0.1.0\", \"private\": true, \"type\": \"module\", \"main\": \"./lib/plugin.js\", \"repository\": { \"type\": \"git\", \"url\": \"https://github.com/puppeteer/puppeteer/tree/main/tools/eslint\" }, \"scripts\": { \"build\": \"wireit\", \"prepare\": \"wireit\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b\", \"clean\": \"if-file-deleted\", \"files\": \"src/ \" , \"output\": \"lib/ \", \"tsconfig.tsbuildinfo\" }, \"prepare\": { \"dependencies\": \"build\" } }, \"author\": \"The Chromium Authors\", \"license\": \"Apache-2.0\", \"devDependencies\": { \"@prettier/sync\": \"0.6.1\", \"@typescript-eslint/utils\": \"8.26.1\" } } 证据：`tools/eslint/package.json`\n- **Package**（package_manifest）：{ \"name\": \"@puppeteer/mocha-runner\", \"version\": \"0.1.0\", \"type\": \"module\", \"private\": true, \"bin\": \"./bin/mocha-runner.js\", \"description\": \"Mocha runner for Puppeteer\", \"license\": \"Apache-2.0\", \"scripts\": { \"build\": \"wireit\", \"test\": \"wireit\", \"clean\": \"../clean.mjs\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b && node --experimental-strip-types ../../tools/chmod.ts 755 ./bin/mocha-runner.js\", \"clean\": \"if-file-deleted\", \"files\": \"src/ \" , \"output\": \"bin/ \", \"tsconfig.tsbuildinfo\" , \"dependencies\": \"../../packages/puppeteer-core:build\" }, \"test\": { \"command\": \"c8 node ./bin/test.js\", \"dependencies\": \"build\" } }, \"devDependencies\": { \"@types/yargs\": \"17.0.33\", \"c8\": \"11.0.0\", \"glob\": \"13.0.6… 证据：`tools/mocha-runner/package.json`\n- **Contributing**（documentation）：First of all, thank you for your interest in Puppeteer! We'd love to accept your patches and contributions! 证据：`website/versioned_docs/version-25.0.2/contributing.md`\n- **TestServer**（documentation）：This test server is used internally by Puppeteer to test Puppeteer itself. 证据：`packages/testserver/README.md`\n- **Package**（package_manifest）：{ \"name\": \"@pptr/testserver\", \"version\": \"0.6.1\", \"description\": \"testing server\", \"type\": \"module\", \"main\": \"lib/index.js\", \"scripts\": { \"build\": \"wireit\", \"clean\": \"../../tools/clean.mjs\" }, \"wireit\": { \"build\": { \"command\": \"tsc -b\", \"clean\": \"if-file-deleted\", \"files\": \"src/ \" , \"output\": \"lib/ \", \"tsconfig.tsbuildinfo\" } }, \"repository\": { \"type\": \"git\", \"url\": \"https://github.com/puppeteer/puppeteer/tree/main/packages/testserver\" }, \"author\": \"The Chromium Authors\", \"license\": \"Apache-2.0\", \"dependencies\": { \"mime\": \"4.1.0\", \"ws\": \"8.20.0\" }, \"devDependencies\": { \"@types/ws\": \"8.18.1\" } } 证据：`packages/testserver/package.json`\n- **License**（source_file）：Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ 证据：`LICENSE`\n- **Changelog**（documentation）：Combined changelog for puppeteer and puppeteer-core. 证据：`docs/CHANGELOG.md`\n- **Examples & Use cases**（documentation）：The Puppeteer repository https://github.com/puppeteer/puppeteer/tree/main/examples includes a small number of examples maintained by the Puppeteer team. 证据：`docs/examples.md`\n- **FAQ**（documentation）：The Chrome Browser Automation team maintains the library, but we'd love your help and expertise on the project! See our contributing guide https://pptr.dev/contributing . 证据：`docs/faq.md`\n- **Puppeteer**（documentation）：! build https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml/badge.svg?branch=main https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml ! npm puppeteer package https://img.shields.io/npm/v/puppeteer.svg https://npmjs.org/package/puppeteer 证据：`docs/index.md`\n- **Supported browsers**（documentation）：Starting with v20.0.0 Puppeteer downloads and works with Chrome for Testing https://github.com/GoogleChromeLabs/chrome-for-testing?tab=readme-ov-file what-is-chrome-for-testing , which supports both headless and headful modes sharing the same code path in the browser. The old headless mode is now a separate program called chrome-headless-shell https://developer.chrome.com/blog/chrome-headless-shell use headless: 'shell' with Puppeteer . 证据：`docs/supported-browsers.md`\n- **Troubleshooting**（documentation）：To keep this page up-to-date we largely rely on community contributions. Please send a PR if you notice something is no longer up-to-date. 证据：`docs/troubleshooting.md`\n- **WebDriver BiDi support**（documentation）：WebDriver BiDi https://w3c.github.io/webdriver-bidi/ is a new cross-browser automation protocol currently under development, aiming to combine the best of both WebDriver “Classic” and CDP. WebDriver BiDi enables bi-directional communication, making it fast by default, and it comes packed with low-level control. 证据：`docs/webdriver-bidi.md`\n- **API Reference**（documentation）：Accessibility ./puppeteer.accessibility.md 证据：`docs/api/index.md`\n- **Accessibility class**（documentation）：The Accessibility class provides methods for inspecting the browser's accessibility tree. The accessibility tree is used by assistive technology such as screen readers https://en.wikipedia.org/wiki/Screen reader or switches https://en.wikipedia.org/wiki/Switch access . 证据：`docs/api/puppeteer.accessibility.md`\n- **Accessibility.snapshot method**（documentation）：Captures the current state of the accessibility tree. The returned object represents the root accessible node of the page. 证据：`docs/api/puppeteer.accessibility.snapshot.md`\n- **ActionOptions interface**（documentation）：A signal to abort the locator action. 证据：`docs/api/puppeteer.actionoptions.md`\n- **ActionResult type**（documentation）：--- sidebar label: ActionResult --- ActionResult type Signature 证据：`docs/api/puppeteer.actionresult.md`\n- **AdapterState type**（documentation）：--- sidebar label: AdapterState --- AdapterState type Emulated bluetooth adapter state. Signature 证据：`docs/api/puppeteer.adapterstate.md`\n- **AddScreenParams interface**（documentation）：WorkAreaInsets ./puppeteer.workareainsets.md 证据：`docs/api/puppeteer.addscreenparams.md`\n- **AutofillAddressField enum**（documentation）：Supported autofill address field names. 证据：`docs/api/puppeteer.autofilladdressfield.md`\n- **AutofillData type**（documentation）：References: AutofillAddressField ./puppeteer.autofilladdressfield.md 证据：`docs/api/puppeteer.autofilldata.md`\n- **Awaitable type**（documentation）：--- sidebar label: Awaitable --- Awaitable type Signature 证据：`docs/api/puppeteer.awaitable.md`\n- **AwaitableIterable type**（documentation）：--- sidebar label: AwaitableIterable --- AwaitableIterable type Signature 证据：`docs/api/puppeteer.awaitableiterable.md`\n- **AwaitablePredicate type**（documentation）：References: Awaitable ./puppeteer.awaitable.md 证据：`docs/api/puppeteer.awaitablepredicate.md`\n- **AwaitedLocator type**（documentation）：References: Locator ./puppeteer.locator.md 证据：`docs/api/puppeteer.awaitedlocator.md`\n- **BluetoothEmulation.disableEmulation method**（documentation）：BluetoothEmulation.disableEmulation method 证据：`docs/api/puppeteer.bluetoothemulation.disableemulation.md`\n- **BluetoothEmulation.emulateAdapter method**（documentation）：BluetoothEmulation.emulateAdapter method 证据：`docs/api/puppeteer.bluetoothemulation.emulateadapter.md`\n- **BluetoothEmulation interface**（documentation）：Exposes the bluetooth emulation abilities. 证据：`docs/api/puppeteer.bluetoothemulation.md`\n- **BluetoothEmulation.simulatePreconnectedPeripheral method**（documentation）：BluetoothEmulation.simulatePreconnectedPeripheral method 证据：`docs/api/puppeteer.bluetoothemulation.simulatepreconnectedperipheral.md`\n- **BluetoothManufacturerData interface**（documentation）：BluetoothManufacturerData interface 证据：`docs/api/puppeteer.bluetoothmanufacturerdata.md`\n- **BoundingBox interface**（documentation）：Extends: Point ./puppeteer.point.md 证据：`docs/api/puppeteer.boundingbox.md`\n- **BoxModel interface**（documentation）：--- sidebar label: BoxModel --- BoxModel interface Signature Properties Property Modifiers Type Description Default border Quad ./puppeteer.quad.md content Quad ./puppeteer.quad.md height number margin Quad ./puppeteer.quad.md padding Quad ./puppeteer.quad.md width number 证据：`docs/api/puppeteer.boxmodel.md`\n- **Browser.addScreen method**（documentation）：Adds a new screen, returns the added screen information object ./puppeteer.screeninfo.md . 证据：`docs/api/puppeteer.browser.addscreen.md`\n- 其余 20 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`docs/contributing.md`, `README.md`, `docker/README.md`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`docs/contributing.md`, `README.md`, `docker/README.md`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **Puppeteer项目概览**：importance `high`\n  - source_paths: README.md, package.json, packages/puppeteer-core/package.json, docs/guides/what-is-puppeteer.md, packages/puppeteer-core/src/puppeteer-core.ts\n- **安装与入门指南**：importance `high`\n  - source_paths: packages/puppeteer/install.mjs, packages/puppeteer/src/install.ts, docs/guides/installation.md, docs/guides/getting-started.md, examples/README.md\n- **Puppeteer系统架构**：importance `high`\n  - source_paths: packages/puppeteer-core/src/index.ts, packages/puppeteer-core/src/api/api.ts, packages/puppeteer-core/src/common/common.ts, packages/puppeteer-core/src/node/node.ts, packages/puppeteer-core/src/puppeteer-core.ts\n- **协议实现：CDP与WebDriver BiDi**：importance `high`\n  - source_paths: packages/puppeteer-core/src/cdp/Browser.ts, packages/puppeteer-core/src/cdp/Connection.ts, packages/puppeteer-core/src/bidi/Browser.ts, packages/puppeteer-core/src/bidi/Connection.ts, packages/puppeteer-core/src/bidi/core/core.ts\n- **浏览器启动与管理**：importance `high`\n  - source_paths: packages/puppeteer-core/src/node/ChromeLauncher.ts, packages/puppeteer-core/src/node/FirefoxLauncher.ts, packages/puppeteer-core/src/node/BrowserLauncher.ts, packages/puppeteer-core/src/api/Browser.ts, packages/puppeteer-core/src/api/BrowserContext.ts\n- **Page页面操作API**：importance `high`\n  - source_paths: packages/puppeteer-core/src/api/Page.ts, packages/puppeteer-core/src/cdp/Page.ts, packages/puppeteer-core/src/bidi/Page.ts, packages/puppeteer-core/src/api/Frame.ts, docs/guides/page-interactions.md\n- **元素定位器与操作**：importance `high`\n  - source_paths: packages/puppeteer-core/src/api/ElementHandle.ts, packages/puppeteer-core/src/api/locators/locators.ts, packages/puppeteer-core/src/cdp/ElementHandle.ts, packages/puppeteer-core/src/injected/ARIAQuerySelector.ts, packages/puppeteer-core/src/injected/PierceQuerySelector.ts\n- **网络请求拦截与管理**：importance `medium`\n  - source_paths: packages/puppeteer-core/src/api/HTTPRequest.ts, packages/puppeteer-core/src/api/HTTPResponse.ts, packages/puppeteer-core/src/cdp/HTTPRequest.ts, packages/puppeteer-core/src/cdp/NetworkManager.ts, packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `3aadc38c533caa8df87f381868291ede870883e2`\n- inspected_files: `package.json`, `README.md`, `docs/contributing.md`, `docs/index.md`, `docs/troubleshooting.md`, `docs/webdriver-bidi.md`, `docs/examples.md`, `docs/faq.md`, `docs/supported-browsers.md`, `docs/CHANGELOG.md`, `docs/api/puppeteer.page.emulate.md`, `docs/api/puppeteer.locatorevents.md`, `docs/api/puppeteer.page.windowid.md`, `docs/api/puppeteer.page.evaluatehandle.md`, `docs/api/puppeteer.page.bringtofront.md`, `docs/api/puppeteer.commoneventemitter.removealllisteners.md`, `docs/api/puppeteer.quad.md`, `docs/api/puppeteer.page.setuseragent.md`, `docs/api/puppeteer.browser.setcookie.md`, `docs/api/puppeteer.permissionstate_2.md`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 来源证据：Chrome Canary/Firefox Nightly test results\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Chrome Canary/Firefox Nightly test results\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_1aabe120a9df47a2adbd293381b50a64 | https://github.com/puppeteer/puppeteer/issues/12379 | 来源类型 github_issue 暴露的待验证使用条件。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 来源证据：Puppeteer v25\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Puppeteer v25\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能影响升级、迁移或版本选择。\n- Evidence: community_evidence:github | cevd_050f65ceff2a455da4a3538895a7538b | https://github.com/puppeteer/puppeteer/issues/14342 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 来源证据：[Bug]: GHSA issued a false malicious package alert for puppeteer\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: GHSA issued a false malicious package alert for puppeteer\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_55588dfbd41442fdb8a2f4f1be57e4c9 | https://github.com/puppeteer/puppeteer/issues/14986 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 来源证据：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能影响授权、密钥配置或安全边界。\n- Evidence: community_evidence:github | cevd_9b1ef7c38ed14c41b3e4ce786adcdf26 | https://github.com/puppeteer/puppeteer/issues/14774 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 来源证据：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_5d1f448d8768460a806ab32e8d4f6997 | https://github.com/puppeteer/puppeteer/issues/14957 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 来源证据：[Bug]: `setViewport` crashes on Firefox if uncaught\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: `setViewport` crashes on Firefox if uncaught\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能阻塞安装或首次运行。\n- Evidence: community_evidence:github | cevd_75bddb8a74194cf7a8978853f19db23a | https://github.com/puppeteer/puppeteer/issues/14989 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: 来源证据：[Bug]: chrome binary is not present when installing latest chrome\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: chrome binary is not present when installing latest chrome\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_1e85cdab2b684dda8e5c83f55b8ff7b6 | https://github.com/puppeteer/puppeteer/issues/14988 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 8: 来源证据：[Feature]: Make proxy-agent dependency optional\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Feature]: Make proxy-agent dependency optional\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响升级、迁移或版本选择。\n- Evidence: community_evidence:github | cevd_195c51e4a5e84edda14a2a79b456821c | https://github.com/puppeteer/puppeteer/issues/13775 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 9: 来源证据：browsers: v3.0.0\n\n- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：browsers: v3.0.0\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能影响升级、迁移或版本选择。\n- Evidence: community_evidence:github | cevd_bf2d83568c54447fbfd3047d24be0c48 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 10: 来源证据：browsers: v3.0.2\n\n- Trigger: GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：browsers: v3.0.2\n- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- Why it matters: 可能增加新用户试用和生产接入成本。\n- Evidence: community_evidence:github | cevd_c9f08632e7ee4e9485d27b864a21e462 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：puppeteer/puppeteer\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：local_cli\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- 无阻塞项。\n\n## 项目专属踩坑\n\n- 来源证据：Chrome Canary/Firefox Nightly test results（high）：可能增加新用户试用和生产接入成本。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 来源证据：Puppeteer v25（high）：可能影响升级、迁移或版本选择。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 来源证据：[Bug]: GHSA issued a false malicious package alert for puppeteer（high）：可能增加新用户试用和生产接入成本。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 来源证据：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`（high）：可能影响授权、密钥配置或安全边界。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 来源证据：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)（medium）：可能增加新用户试用和生产接入成本。 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/puppeteer/puppeteer 项目说明书\n\n生成时间：2026-05-16 04:41:15 UTC\n\n## 目录\n\n- [Puppeteer项目概览](#page-overview)\n- [安装与入门指南](#page-installation)\n- [Puppeteer系统架构](#page-architecture)\n- [协议实现：CDP与WebDriver BiDi](#page-protocols)\n- [浏览器启动与管理](#page-browser-management)\n- [Page页面操作API](#page-page-api)\n- [元素定位器与操作](#page-element-locator)\n- [网络请求拦截与管理](#page-network)\n- [浏览器上下文与扩展支持](#page-contexts-extensions)\n- [覆盖率检测与调试功能](#page-coverage-debugging)\n\n<a id='page-overview'></a>\n\n## Puppeteer项目概览\n\n### 相关页面\n\n相关主题：[Puppeteer系统架构](#page-architecture), [安装与入门指南](#page-installation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/puppeteer/puppeteer/blob/main/README.md)\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n- [packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n- [packages/browsers/README.md](https://github.com/puppeteer/puppeteer/blob/main/packages/browsers/README.md)\n- [examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n</details>\n\n# Puppeteer项目概览\n\n## 1. 项目简介\n\nPuppeteer是一个由Google维护的Node.js库，它提供了高级API来通过[Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/)控制无头Chrome或Chromium浏览器。Puppeteer本质上是Chrome浏览器的自动化工具，允许开发者以编程方式执行通常需要手动操作的任务。\n\n### 1.1 核心功能\n\n| 功能类别 | 说明 |\n|---------|------|\n| 页面导航 | 加载网页、访问URL、处理导航事件 |\n| 内容抓取 | 提取页面DOM、获取元素内容、截图 |\n| 用户交互 | 模拟键盘输入、鼠标点击、表单提交 |\n| 性能监控 | 跟踪网络请求、测量页面性能 |\n| 设备模拟 | 模拟移动设备、iPhone、Android等 |\n| 浏览器扩展 | 支持加载Chrome扩展程序 |\n\n资料来源：[README.md:1-15]()\n\n## 2. 项目架构\n\nPuppeteer采用monorepo架构，主要由核心包和配套工具组成。\n\n### 2.1 核心包结构\n\n```mermaid\ngraph TD\n    A[Puppeteer] --> B[puppeteer-core]\n    A --> C[@puppeteer/browsers]\n    A --> D[@puppeteer/ng-schematics]\n    \n    B --> E[API层]\n    B --> F[CDP通信层]\n    B --> G[公共组件]\n    \n    E --> H[Page]\n    E --> I[Browser]\n    E --> J[BrowserContext]\n    \n    G --> K[Configuration]\n    G --> L[Device]\n    G --> M[LazyArg]\n    G --> N[Debug]\n```\n\n### 2.2 主要包说明\n\n| 包名 | 用途 |\n|------|------|\n| `puppeteer` | 完整包，包含浏览器下载功能 |\n| `puppeteer-core` | 轻量级核心库，不自动下载浏览器 |\n| `@puppeteer/browsers` | 浏览器管理和下载CLI工具 |\n| `@puppeteer/ng-schematics` | Angular集成工具 |\n\n资料来源：[README.md:1-10]()\n\n## 3. 安装与配置\n\n### 3.1 安装方式\n\n```bash\n# 完整安装（自动下载Chrome）\nnpm i puppeteer\n\n# 仅安装核心库（不下载浏览器）\nnpm i puppeteer-core\n```\n\n### 3.2 启动选项配置\n\nPuppeteer支持丰富的浏览器启动配置选项：\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `executablePath` | `string` | - | 指定浏览器可执行文件路径 |\n| `ignoreDefaultArgs` | `boolean \\| string[]` | `false` | 是否忽略默认启动参数 |\n| `enableExtensions` | `boolean \\| string[]` | - | 启用Chrome扩展 |\n| `handleSIGINT` | `boolean` | `true` | Ctrl+C时关闭浏览器 |\n| `handleSIGTERM` | `boolean` | `true` | SIGTERM时关闭浏览器 |\n| `handleSIGHUP` | `boolean` | `true` | SIGHUP时关闭浏览器 |\n| `timeout` | `number` | `30000` | 启动超时时间(毫秒) |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:1-50]()\n\n### 3.3 全局配置\n\nConfiguration接口定义了全局配置选项：\n\n```typescript\ninterface Configuration {\n  defaultBrowser?: SupportedBrowser;\n  temporaryDirectory?: string;\n  skipDownload?: boolean;\n  logLevel?: 'silent' | 'error' | 'warn';\n  experiments?: ExperimentsConfiguration;\n  chrome?: ChromeSettings;\n  firefox?: FirefoxSettings;\n}\n```\n\n| 配置项 | 说明 |\n|--------|------|\n| `defaultBrowser` | 默认浏览器类型，默认`chrome` |\n| `temporaryDirectory` | 临时文件目录，默认为`os.tmpdir()` |\n| `skipDownload` | 安装时跳过浏览器下载 |\n| `logLevel` | 日志级别，默认`warn` |\n| `chrome` | Chrome特定配置 |\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:1-40]()\n\n## 4. 核心API\n\n### 4.1 Page类\n\nPage类是Puppeteer最核心的类，继承自EventEmitter，负责页面操作和交互。\n\n```mermaid\ngraph LR\n    A[Page] --> B[事件监听]\n    A --> C[页面导航]\n    A --> D[元素查询]\n    A --> E[函数暴露]\n```\n\n#### 4.1.1 常用方法\n\n| 方法 | 说明 |\n|------|------|\n| `goto(url)` | 导航到指定URL |\n| `waitForSelector(selector)` | 等待元素出现 |\n| `click(selector)` | 点击元素 |\n| `type(selector, text)` | 输入文本 |\n| `evaluate(fn)` | 在页面上下文执行JavaScript |\n| `screenshot()` | 页面截图 |\n| `setViewport()` | 设置视口大小 |\n\n#### 4.1.2 事件系统\n\nPage类继承EventEmitter模式，支持以下典型事件：\n\n```typescript\npage.once('load', () => console.log('Page loaded!'));\n\nfunction logRequest(interceptedRequest) {\n  console.log('A request was made:', interceptedRequest.url());\n}\npage.on('request', logRequest);\npage.off('request', logRequest);\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:1-80]()\n\n### 4.2 exposeFunction方法\n\nexposeFunction允许将Node.js函数暴露给浏览器页面调用：\n\n```typescript\npage.exposeFunction('readfile', async filePath => {\n  return fs.readFile(filePath, 'utf8');\n});\n\nawait page.evaluate(async () => {\n  const content = await window.readfile('/etc/hosts');\n  console.log(content);\n});\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:100-140]()\n\n### 4.3 Locators API\n\nLocators是实验性的定位器API，提供更可靠的元素定位方式：\n\n```typescript\n// 使用ARIA文本定位\nawait page.locator('::-p-aria(Search)').fill('automate beyond recorder');\n\n// 使用文本内容定位\nawait page.locator('::-p-text(Customize and automate)').waitHandle();\n\n// 使用组合选择器\nawait page.locator('.devsite-result-item-link').click();\n```\n\n## 5. 设备模拟\n\nPuppeteer内置了丰富的设备模拟功能，通过KnownDevices对象提供：\n\n```typescript\nimport {KnownDevices} from 'puppeteer';\n\nconst iPhone = KnownDevices['iPhone 15 Pro'];\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\nawait page.emulate(iPhone);\n```\n\n| 设备类别 | 示例设备 |\n|---------|---------|\n| iPhone系列 | iPhone 12, iPhone 15 Pro |\n| iPad系列 | iPad Mini, iPad Pro |\n| Android | Android Phone, Android Tablet |\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts:1-30]()\n\n## 6. @puppeteer/browsers CLI\n\n@puppeteer/browsers包提供浏览器管理的命令行工具：\n\n### 6.1 常用命令\n\n```bash\n# 安装Chrome稳定版\nnpx @puppeteer/browsers install chrome@stable\n\n# 安装指定版本\nnpx @puppeteer/browsers install chrome@116.0.5793.0\n\n# 安装ChromeDriver\nnpx @puppeteer/browsers install chromedriver@canary\n\n# 列出已安装浏览器\nnpx @puppeteer/browsers list\n\n# 清除所有已安装浏览器\nnpx @puppeteer/browsers clear\n```\n\n### 6.2 系统要求\n\n| 平台 | 依赖 |\n|------|------|\n| Linux/MacOS | `unzip` |\n| Windows | `tar.exe` |\n| Firefox下载(Linux) | `xz`, `bzip2` |\n| Firefox下载(MacOS) | `hdiutil` |\n\n资料来源：[packages/browsers/README.md:1-60]()\n\n## 7. 工作流程示例\n\n### 7.1 基础使用流程\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[创建页面]\n    B --> C[设置视口]\n    C --> D[导航到URL]\n    D --> E[执行操作]\n    E --> F[提取数据]\n    F --> G[关闭浏览器]\n    \n    D -.->|网络请求| H[request事件]\n    E -.->|控制台| I[console事件]\n    F -.->|截图| J[screenshot]\n```\n\n### 7.2 完整示例代码\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\nawait page.setViewport({width: 1080, height: 1024});\nawait page.goto('https://developer.chrome.com/');\n\nawait page.keyboard.press('/');\nawait page.locator('::-p-aria(Search)').fill('automate beyond recorder');\nawait page.locator('.devsite-result-item-link').click();\n\nconst textSelector = await page\n  .locator('::-p-text(Customize and automate)')\n  .waitHandle();\nconst fullTitle = await textSelector?.evaluate(el => el.textContent);\n\nconsole.log('The title of this blog post is \"%s\".', fullTitle);\n\nawait browser.close();\n```\n\n资料来源：[README.md:15-40]()\n\n## 8. 调试功能\n\nPuppeteer提供内置调试支持，通过`__PUPPETEER_DEBUG`环境变量控制：\n\n```bash\n# 开启所有日志\nwindow.__PUPPETEER_DEBUG='*';\n\n# 仅记录Page通道\nwindow.__PUPPETEER_DEBUG='Page';\n\n# 记录所有以Page开头的通道\nwindow.__PUPPETEER_DEBUG='Page*';\n```\n\n调试输出示例：\n\n```typescript\nconst log = debug('Page');\nlog('new page created');\n// 输出: \"Page: new page created\"\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:1-30]()\n\n## 9. 项目组织结构\n\n```\npuppeteer/\n├── packages/\n│   ├── puppeteer-core/     # 核心API包\n│   │   └── src/\n│   │       ├── api/        # Page、Browser等API\n│   │       ├── cdp/        # Chrome DevTools Protocol通信\n│   │       └── common/     # 公共组件\n│   ├── browsers/           # 浏览器管理CLI\n│   └── ng-schematics/      # Angular集成\n├── examples/               # 示例代码\n├── docker/                 # Docker配置\n└── tools/                  # 开发工具(ESLint等)\n```\n\n## 10. 相关资源\n\n| 资源 | 链接 |\n|------|------|\n| 官方文档 | [pptr.dev](https://pptr.dev) |\n| 示例集合 | [pptr.dev/examples](https://pptr.dev/examples) |\n| 选择器指南 | [pptr.dev/guides/page-interactions#selectors](https://pptr.dev/guides/page-interactions#selectors) |\n| MCP支持 | [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) |\n| WebMCP | [pptr.dev/guides/webmcp](https://pptr.dev/guides/webmcp) |\n\n资料来源：[README.md:5-15](), [examples/README.md:1-20]()\n\n---\n\n<a id='page-installation'></a>\n\n## 安装与入门指南\n\n### 相关页面\n\n相关主题：[Puppeteer项目概览](#page-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer/install.mjs](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer/install.mjs)\n- [packages/puppeteer/src/install.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer/src/install.ts)\n- [docs/guides/installation.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/installation.md)\n- [docs/guides/getting-started.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/getting-started.md)\n- [examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n</details>\n\n# 安装与入门指南\n\n## 概述\n\nPuppeteer 是一个流行的 Node.js 库，它提供了高级 API 来通过 DevTools 协议控制 Chromium、Chrome 或 Firefox 浏览器。Puppeteer 主要用于网页自动化、网页抓取、生成截图、生成 PDF、测试 Web 应用等场景。\n\n本指南将详细介绍 Puppeteer 的安装方式、系统要求、浏览器配置以及快速入门方法，帮助开发者快速上手使用 Puppeteer。\n\n## 安装方式\n\n### 使用 npm 安装\n\nPuppeteer 提供两个主要的 npm 包，开发者可以根据需求选择合适的版本：\n\n| 包名 | 说明 | 适用场景 |\n|------|------|----------|\n| `puppeteer` | 完整版，包含浏览器下载功能 | 标准使用，需要自动下载 Chrome |\n| `puppeteer-core` | 精简版，不包含浏览器 | 已在环境中安装浏览器，或使用自定义浏览器 |\n\n标准安装命令如下：\n\n```bash\nnpm i puppeteer\n```\n\n此命令会在安装过程中自动下载与 Puppeteer 版本兼容的 Chrome 浏览器。\n\n如果只需要将 Puppeteer 作为库使用，而不包含浏览器：\n\n```bash\nnpm i puppeteer-core\n```\n\n资料来源：[README.md:Installation]()\n\n### 使用 puppeteer-core 的注意事项\n\n使用 `puppeteer-core` 时，需要在 `puppeteer.launch()` 方法中通过 `executablePath` 参数指定浏览器可执行文件路径：\n\n```typescript\nimport puppeteer from 'puppeteer-core';\n\nconst browser = await puppeteer.launch({\n  executablePath: '/path/to/chromium',\n  // 其他配置选项\n});\n```\n\n## 系统要求\n\n### Node.js 版本要求\n\nPuppeteer 对 Node.js 版本有特定要求，具体版本信息请参考 `package.json` 中的 `engines` 字段。建议使用 LTS（长期支持）版本的 Node.js 以确保稳定性。\n\n资料来源：[packages/browsers/README.md:1-10]()\n\n### 浏览器下载的系统依赖\n\n不同的浏览器下载需要不同的系统工具支持：\n\n#### Firefox 下载要求\n\n| 操作系统 | 必需工具 |\n|----------|----------|\n| Linux | `xz` 和 `bzip2` 工具（用于解压 `.tar.gz` 和 `.tar.bz2` 归档文件）|\n| macOS | `hdiutil`（用于解压 `.dmg` 归档文件）|\n\n#### Chrome 下载要求\n\n| 操作系统 | 必需工具 |\n|----------|----------|\n| Linux/macOS | `unzip` |\n| Windows | `tar.exe` |\n\n资料来源：[packages/browsers/README.md:System requirements]()\n\n## 浏览器管理\n\n### @puppeteer/browsers 包\n\n`@puppeteer/browsers` 是官方提供的浏览器管理工具，支持从命令行界面（CLI）或编程方式管理浏览器和驱动。\n\n### 核心命令\n\n#### 安装浏览器\n\n```bash\n# 下载最新的 Stable 频道 Chrome for Testing\nnpx @puppeteer/browsers install chrome@stable\n\n# 下载指定版本的 Chrome for Testing\nnpx @puppeteer/browsers install chrome@116.0.5793.0\n\n# 下载指定里程碑的最新版本\nnpx @puppeteer/browsers install chrome@117\n\n# 下载最新的 ChromeDriver（Canary 频道）\nnpx @puppeteer/browsers install chromedriver@canary\n\n# 下载指定版本的 ChromeDriver\nnpx @puppeteer/browsers install chromedriver@116\n```\n\n#### 列出已安装的浏览器\n\n```bash\nnpx @puppeteer/browsers list\n```\n\n#### 清除所有已安装的浏览器\n\n```bash\nnpx @puppeteer/browsers clear\n```\n\n#### 获取帮助信息\n\n```bash\n# 获取所有命令的帮助\nnpx @puppeteer/browsers --help\n\n# 获取特定命令的帮助\nnpx @puppeteer/browsers install --help\nnpx @puppeteer/browsers launch --help\n```\n\n### 版本指定方式\n\n| 指定方式 | 示例 | 说明 |\n|----------|------|------|\n| `latest` | `chrome@latest` | 下载最新稳定版 |\n| 里程碑版本 | `chrome@117` | 下载该里程碑的最新版本 |\n| 完整版本号 | `chrome@116.0.5793.0` | 下载指定精确版本 |\n| 频道 | `chromedriver@canary` | 下载指定频道的最新版本 |\n\n资料来源：[packages/browsers/README.md:CLI]()\n\n### 浏览器管理 API\n\n除了 CLI，还可以编程方式使用 `@puppeteer/browsers`：\n\n```typescript\nimport {install, launch, clear, list} from '@puppeteer/browsers';\n\n// 列出已安装的浏览器\nconst installed = await list({});\n\n// 安装浏览器\nawait install({\n  browser: 'chrome',\n  channel: 'stable',\n});\n\n// 启动浏览器\nconst process = await launch({\n  browser: 'chrome',\n  channel: 'stable',\n});\n```\n\n## 快速入门\n\n### 基本示例\n\n以下是一个完整的 Puppeteer 使用示例，展示了打开浏览器、导航到网页、模拟用户交互的基本流程：\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nasync function main() {\n  // 启动浏览器并打开新的空白页\n  const browser = await puppeteer.launch();\n  const page = await browser.newPage();\n\n  // 导航到目标 URL\n  await page.goto('https://developer.chrome.com/');\n\n  // 设置视口大小\n  await page.setViewport({width: 1080, height: 1024});\n\n  // 使用键盘按下搜索菜单快捷键\n  await page.keyboard.press('/');\n\n  // 使用可访问的输入框名称填写搜索内容\n  await page.locator('::-p-aria(Search)').fill('automate beyond recorder');\n\n  // 等待并点击第一个搜索结果\n  await page.locator('.devsite-result-item-link').click();\n\n  // 使用文本定位器获取元素句柄\n  const textSelector = await page\n    .locator('::-p-text(Customize and automate)')\n    .waitHandle();\n\n  // 获取元素的文本内容\n  const fullTitle = await textSelector?.evaluate(el => el.textContent);\n\n  // 打印结果\n  console.log('The title of this blog post is \"%s\".', fullTitle);\n\n  // 关闭浏览器\n  await browser.close();\n}\n\nmain();\n```\n\n资料来源：[README.md:Example]()\n\n### 核心概念说明\n\n#### 浏览器实例（Browser）\n\n通过 `puppeteer.launch()` 创建浏览器实例，这是所有浏览器操作的基础。\n\n```typescript\nconst browser = await puppeteer.launch({\n  headless: true,      // 是否使用无头模式\n  args: ['--no-sandbox'],  // 浏览器启动参数\n  timeout: 30000,      // 启动超时时间（毫秒）\n});\n```\n\n#### 页面（Page）\n\n通过 `browser.newPage()` 创建新的页面实例，Page 类继承自 EventEmitter，支持丰富的事件机制：\n\n```typescript\npage.on('console', msg => console.log('PAGE LOG:', msg.text()));\npage.on('request', request => console.log('REQUEST:', request.url()));\npage.on('load', () => console.log('Page loaded!'));\n```\n\n#### 定位器（Locator）\n\nPuppeteer 推荐使用 Locator API 进行元素定位和交互，Locator 提供了更强大的等待和重试机制：\n\n```typescript\n// 使用文本内容定位\nawait page.locator('::-p-text(Submit)').click();\n\n// 使用 ARIA 属性定位\nawait page.locator('::-p-aria(Search)').fill('query');\n\n// 使用 CSS 选择器定位\nawait page.locator('.button.primary').click();\n```\n\n#### 元素操作\n\n| 操作 | 方法 | 说明 |\n|------|------|------|\n| 点击 | `locator.click()` | 单击元素 |\n| 输入 | `locator.fill()` | 填充输入框 |\n| 获取文本 | `evaluate(el => el.textContent)` | 获取元素文本 |\n| 获取属性 | `locator.getAttribute()` | 获取元素属性值 |\n| 截图 | `page.screenshot()` | 截取页面截图 |\n| 生成 PDF | `page.pdf()` | 生成 PDF 文档 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:$$eval]()\n\n## 运行示例项目\n\n### 环境准备\n\n1. **克隆仓库并安装依赖**\n\n```bash\ngit clone https://github.com/puppeteer/puppeteer.git\ncd puppeteer\nnpm install\n```\n\n2. **构建 Puppeteer**\n\n```bash\nnpm run build\n```\n\n### 运行单个示例\n\n构建完成后，使用以下命令运行单个示例脚本：\n\n```bash\nNODE_PATH=../ node examples/search.js\n```\n\n示例脚本位于 `examples/` 目录下，提供了多种使用场景的参考实现，包括网页搜索、截图、PDF 生成等功能。\n\n资料来源：[examples/README.md:Run]()\n\n## 选择器语法参考\n\n### Puppeteer 专用选择器\n\n| 选择器类型 | 语法格式 | 示例 |\n|------------|----------|------|\n| 文本选择器 | `::-p-text(<文本>)` | `page.locator('::-p-text(Submit)')` |\n| ARIA 选择器 | `::-p-aria(<角色>[name=<名称>])` | `page.locator('::-p-aria(Button)')` |\n| XPath 选择器 | `::-p-xpath(<xpath>)` | `page.locator('::-p-xpath(//button)')` |\n| Shadow DOM | `>>> <选择器>` | `page.locator('>>> .custom-element')` |\n\n### Angular Schematics 选择器对照\n\n对于从 Angular/Protractor 迁移的用户，以下是选择器语法对照：\n\n| Protractor | Puppeteer |\n|------------|-----------|\n| `$(by.id('id'))` | `page.$('#id')` |\n| `$(by.cssContainingText('css', 'text'))` | `page.$('css ::-p-text(text)')` |\n| `$(by.deepCss('css'))` | `page.$(':scope >>> css')` |\n| `$(by.xpath('xpath'))` | `page.$('::-p-xpath(xpath)')` |\n\n资料来源：[packages/ng-schematics/README.md:Selectors]()\n\n## MCP 集成\n\nPuppeteer 支持 Model Context Protocol (MCP)，可以用于 AI 驱动的浏览器自动化：\n\n### 安装 chrome-devtools-mcp\n\n```bash\nnpm install chrome-devtools-mcp\n```\n\n### WebMCP 支持\n\nPuppeteer 还支持实验性的 WebMCP API，为基于 Web 的 AI 代理提供浏览器自动化能力。\n\n资料来源：[README.md:MCP]()\n\n## 故障排除\n\n### 常见安装问题\n\n#### 浏览器下载失败\n\n如果浏览器下载失败，可以尝试：\n\n1. 手动下载浏览器并使用 `executablePath` 指定路径\n2. 使用已安装系统的浏览器\n3. 检查网络连接和代理设置\n\n#### 权限错误\n\n在 Linux 或容器环境中，可能需要添加额外参数：\n\n```typescript\nconst browser = await puppeteer.launch({\n  args: ['--no-sandbox', '--disable-setuid-sandbox'],\n});\n```\n\n### 调试模式\n\n启用 Puppeteer 调试日志：\n\n```bash\n# 设置调试环境变量\nwindow.__PUPPETEER_DEBUG='*';  // 记录所有日志\nwindow.__PUPPETEER_DEBUG='Page';  // 只记录 Page 频道\nwindow.__PUPPETEER_DEBUG='foo*';  // 记录所有以 foo 开头的频道\n```\n\n在代码中使用调试日志：\n\n```typescript\nimport {debug} from '@puppeteer/puppeteer-core';\n\nconst log = debug('Page');\nlog('new page created');\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:Debug]()\n\n## 下一步\n\n完成安装和入门后，建议进一步了解以下内容：\n\n- **页面交互**：深入学习页面点击、表单填写、键盘输入等交互操作\n- **网络请求拦截**：掌握请求和响应的监控、修改和模拟\n- **性能分析**：使用 Puppeteer 进行页面性能测试和优化\n- **无头模式与有头模式**：了解不同模式下的使用场景和配置\n- **高级配置**：学习浏览器启动参数、代理设置、用户数据目录等高级特性\n\n如需更多示例和详细文档，请访问 [pptr.dev/examples](https://pptr.dev/examples)。\n\n---\n\n<a id='page-architecture'></a>\n\n## Puppeteer系统架构\n\n### 相关页面\n\n相关主题：[协议实现：CDP与WebDriver BiDi](#page-protocols), [Puppeteer项目概览](#page-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n- [packages/puppeteer-core/src/common/LazyArg.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/LazyArg.ts)\n- [packages/puppeteer-core/src/cdp/ExecutionContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ExecutionContext.ts)\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n- [packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts)\n- [packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n- [README.md](https://github.com/puppeteer/puppeteer/blob/main/README.md)\n</details>\n\n# Puppeteer系统架构\n\n## 概述\n\nPuppeteer是一个由Google维护的Node.js库，它提供了高级API来通过DevTools协议控制Chrome或Firefox浏览器。该项目的核心设计围绕浏览器自动化、网页抓取和性能监控等场景展开，采用分层架构以实现良好的模块化和可扩展性。\n\nPuppeteer的架构主要分为以下几个层次：\n\n| 层次 | 描述 | 主要模块 |\n|------|------|----------|\n| 用户API层 | 面向开发者的TypeScript/JavaScript接口 | Page、Browser、Frame |\n| 协议抽象层 | 封装浏览器通信协议 | CDP (Chrome DevTools Protocol) |\n| 核心引擎层 | 实现核心自动化逻辑 | puppeteer-core |\n| 节点运行时层 | Node.js环境特定功能 | LaunchOptions、PuppeteerNode |\n| 工具层 | 辅助功能 | 设备模拟、调试、配置管理 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:310-320]()\n\n## 核心模块架构\n\n### 1. 包结构\n\nPuppeteer项目采用monorepo结构，主要包含以下npm包：\n\n| 包名 | 用途 |\n|------|------|\n| `puppeteer` | 完整的Puppeteer包，包含浏览器下载 |\n| `puppeteer-core` | 核心库，不包含浏览器二进制文件 |\n| `@puppeteer/browsers` | 浏览器管理和启动CLI工具 |\n| `@puppeteer/ng-schematics` | Angular schematics集成 |\n\n资料来源：[README.md:1-10]()\n\n### 2. Page类架构\n\n`Page`是Puppeteer中最核心的类之一，它继承自`EventEmitter`并提供了丰富的浏览器页面操作能力。\n\n```mermaid\ngraph TD\n    EventEmitter --> Page\n    Page --> |extends| CDPPage\n    Page --> |extends| WebDriverPage\n    \n    Page --> |使用| TimeoutSettings\n    Page --> |管理| RequestHandlers\n    Page --> |发出| PageEvents\n    \n    subgraph \"Page核心功能\"\n        exposeFunction\n        evaluate\n        goto\n        setContent\n        locator\n    end\n```\n\n**Page类的关键内部状态**：\n\n```typescript\nabstract class Page extends EventEmitter<PageEvents> {\n  _isDragging = false;                    // 拖拽状态\n  _timeoutSettings = new TimeoutSettings(); // 超时设置\n  _tabId = '';                            // 标签页标识符\n  #requestHandlers = new WeakMap<>();    // 请求处理器\n  #inflight$ = new ReplaySubject<number>(1); // 进行中的请求\n}\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:290-305]()\n\n### 3. 抽象设计与实现分离\n\nPuppeteer采用了抽象基类的设计模式，定义了清晰的接口契约。这种设计允许不同的协议实现共存：\n\n```mermaid\ngraph LR\n    subgraph \"抽象层\"\n        Page\n        Browser\n        Frame\n    end\n    \n    subgraph \"CDP实现\"\n        CDPPage\n        CDPBrowser\n        CDPFrame\n    end\n    \n    subgraph \"WebDriver实现\"\n        WebDriverPage\n        WebDriverBrowser\n        WebDriverFrame\n    end\n    \n    Page --> CDPPage\n    Page --> WebDriverPage\n```\n\n## 配置系统\n\n### Configuration接口\n\nPuppeteer提供了灵活的配置系统，支持多种自定义选项：\n\n```typescript\ninterface Configuration {\n  defaultBrowser?: SupportedBrowser;     // 默认浏览器\n  temporaryDirectory?: string;           // 临时目录\n  skipDownload?: boolean;               // 跳过下载\n  logLevel?: 'silent' | 'error' | 'warn'; // 日志级别\n  experiments?: ExperimentsConfiguration; // 实验性选项\n  chrome?: ChromeSettings;              // Chrome特定设置\n  firefox?: FirefoxSettings;            // Firefox特定设置\n}\n```\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:30-60]()\n\n### 环境变量覆盖\n\n配置选项可以通过环境变量进行覆盖：\n\n| 配置属性 | 环境变量 | 默认值 |\n|----------|----------|--------|\n| `temporaryDirectory` | `PUPPETEER_TMP_DIR` | `os.tmpdir()` |\n| `skipDownload` | `PUPPETEER_SKIP_DOWNLOAD` | `false` |\n| Chrome `skipDownload` | `PUPPETEER_CHROME_SKIP_DOWNLOAD` | `false` |\n| Chrome `downloadBaseUrl` | `PUPPETEER_CHROME_DOWNLOAD_BASE_URL` | `storage.googleapis.com` |\n\n## 执行上下文与代码注入\n\n### ExecutionContext执行上下文\n\nPuppeteer通过`ExecutionContext`类封装了CDP的`Runtime.evaluate`和`Runtime.callFunctionOn`方法：\n\n```mermaid\nsequenceDiagram\n    用户代码 ->> Page: evaluate(pageFunction)\n    Page ->> ExecutionContext: evaluate(pageFunction)\n    ExecutionContext ->> CDPClient: Runtime.evaluate\n    CDPClient -->> ExecutionContext: remoteObject\n    ExecutionContext ->> ExecutionContext: createCdpHandle\n    ExecutionContext -->> 用户代码: JSHandle\n```\n\n**核心评估逻辑**：\n\n```typescript\n// 处理字符串表达式\nif (isString(pageFunction)) {\n  const expressionWithSourceUrl = `${expression}\\n${sourceUrlComment}\\n`;\n  const {exceptionDetails, result: remoteObject} = await client.send(\n    'Runtime.evaluate', {\n      expression: expressionWithSourceUrl,\n      contextId,\n      returnByValue,\n      awaitPromise: true,\n      userGesture: true,\n    }\n  );\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/ExecutionContext.ts:45-75]()\n\n### LazyArg延迟参数机制\n\n`LazyArg`是Puppeteer用于在页面上下文中延迟解析参数的机制：\n\n```typescript\nclass LazyArg<T, Context = PuppeteerUtilWrapper> {\n  static create = <T>(\n    get: (context: PuppeteerUtilWrapper) => Promise<T> | T\n  ): T => {\n    return new LazyArg(get) as unknown as T;\n  };\n\n  async get(context: Context): Promise<T> {\n    return await this.#get(context);\n  }\n}\n```\n\n这个机制确保了传递给页面函数的参数在被实际使用时才进行求值，避免了闭包捕获问题。\n\n资料来源：[packages/puppeteer-core/src/common/LazyArg.ts:20-35]()\n\n## 设备模拟系统\n\n### KnownDevices预定义设备\n\nPuppeteer内置了丰富的设备模拟配置，通过`KnownDevices`对象提供：\n\n```typescript\nexport const KnownDevices = Object.freeze(knownDevicesByName);\n```\n\n支持的设备包括各种iPhone、Android设备和桌面浏览器的预设配置，涵盖视口尺寸、用户代理字符串和触摸能力等属性。\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts:180-190]()\n\n### 设备模拟使用流程\n\n```mermaid\ngraph LR\n    A[获取设备配置] --> B[创建Browser]\n    B --> C[创建Page]\n    C --> D[page.emulate]\n    D --> E[导航到目标URL]\n```\n\n## 启动选项与浏览器管理\n\n### LaunchOptions启动配置\n\n`LaunchOptions`接口定义了浏览器启动时的各项参数：\n\n| 选项 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `executablePath` | `string` | - | 使用指定的浏览器可执行文件 |\n| `ignoreDefaultArgs` | `boolean \\| string[]` | `false` | 忽略默认启动参数 |\n| `enableExtensions` | `boolean \\| string[]` | - | 启用浏览器扩展 |\n| `handleSIGINT` | `boolean` | `true` | Ctrl+C关闭浏览器 |\n| `handleSIGTERM` | `boolean` | `true` | SIGTERM关闭浏览器 |\n| `handleSIGHUP` | `boolean` | `true` | SIGHUP关闭浏览器 |\n| `timeout` | `number` | `30000` | 启动超时(ms) |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:25-60]()\n\n### 信号处理机制\n\nPuppeteer实现了健壮的进程信号处理：\n\n```mermaid\ngraph TD\n    SIGINT --> handleSIGINT --> browser.close\n    SIGTERM --> handleSIGTERM --> browser.close\n    SIGHUP --> handleSIGHUP --> browser.close\n```\n\n## 调试系统\n\n### Debug模块架构\n\nPuppeteer提供了灵活的调试日志系统，支持Node.js和浏览器环境：\n\n```typescript\nexport const debug = (prefix: string): ((...args: unknown[]) => void) => {\n  if (isNode) {\n    return async (...logArgs: unknown[]) => {\n      if (captureLogs) {\n        capturedLogs.push(prefix + logArgs);\n      }\n      (await importDebug())(prefix)(logArgs);\n    };\n  }\n  \n  return (...logArgs: unknown[]): void => {\n    // 浏览器环境使用console.log\n    console.log(`${prefix}:`, ...logArgs);\n  };\n};\n```\n\n### 调试通道配置\n\n通过`window.__PUPPETEER_DEBUG`环境变量控制调试输出：\n\n| 值 | 行为 |\n|----|------|\n| `'*'` | 记录所有通道 |\n| `'Page'` | 仅记录Page通道 |\n| `'Page*'` | 记录所有以Page开头的通道 |\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:30-60]()\n\n## 事件系统\n\n### PageEvent事件类型\n\nPage类继承自`EventEmitter`，使用标准的事件发布-订阅模式：\n\n```typescript\n// 订阅事件\npage.on('request', logRequest);\n\n// 取消订阅\npage.off('request', logRequest);\n\n// 单次事件监听\npage.once('load', () => console.log('Page loaded!'));\n```\n\n常见的页面事件包括：`load`、`domcontentloaded`、`request`、`response`、`console`等。\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:1-50]()\n\n## 查询选择器系统\n\nPuppeteer支持多种选择器类型，实现灵活的元素定位：\n\n| 选择器类型 | 语法示例 | 描述 |\n|------------|----------|------|\n| CSS选择器 | `page.$('div.class')` | 标准CSS选择器 |\n| ARIA选择器 | `::-p-aria(Search)` | 无障碍角色和名称 |\n| 文本选择器 | `::-p-text(Submit)` | 按文本内容匹配 |\n| XPath选择器 | `::-p-xpath(//button)` | XPath表达式 |\n| Pierce选择器 | `::p-deep(div)` | 穿透Shadow DOM |\n\n资料来源：[packages/ng-schematics/README.md:40-60]()\n\n## 典型工作流程\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[创建新页面]\n    B --> C[设置视口和用户代理]\n    C --> D[导航到URL]\n    D --> E[执行自动化操作]\n    E --> F{是否需要交互}\n    F -->|是| G[执行交互操作]\n    G --> H[等待条件满足]\n    H --> E\n    F -->|否| I[提取数据]\n    I --> J[关闭浏览器]\n```\n\n## 安全考虑\n\n### 沙箱模式\n\nDocker运行Puppeteer时需要特殊权限：\n\n```bash\ndocker run -i --init --rm --cap-add=SYS_ADMIN \\\n  --name puppeteer-chrome puppeteer-chrome-linux \\\n  node -e \"...\"\n```\n\n`--cap-add=SYS_ADMIN`用于启用Chrome沙箱安全机制，或使用`--no-sandbox`标志禁用沙箱。\n\n资料来源：[docker/README.md:15-25]()\n\n## 总结\n\nPuppeteer的系统架构体现了以下设计原则：\n\n1. **抽象与实现分离**：通过抽象基类支持CDP和WebDriver等多种协议实现\n2. **模块化设计**：核心功能与特定运行时环境解耦\n3. **灵活的配置系统**：支持代码配置和环境变量覆盖\n4. **事件驱动架构**：基于EventEmitter的统一事件系统\n5. **跨平台支持**：同时支持Node.js和浏览器环境的调试能力\n\n这种架构使得Puppeteer能够适应各种复杂的浏览器自动化场景，同时保持代码的可维护性和可扩展性。\n\n---\n\n<a id='page-protocols'></a>\n\n## 协议实现：CDP与WebDriver BiDi\n\n### 相关页面\n\n相关主题：[Puppeteer系统架构](#page-architecture), [Page页面操作API](#page-page-api)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/cdp/Browser.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Browser.ts)\n- [packages/puppeteer-core/src/cdp/Connection.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Connection.ts)\n- [packages/puppeteer-core/src/bidi/Browser.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/Browser.ts)\n- [packages/puppeteer-core/src/bidi/Connection.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/Connection.ts)\n- [packages/puppeteer-core/src/bidi/core/core.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/core/core.ts)\n- [docs/webdriver-bidi.md](https://github.com/puppeteer/puppeteer/blob/main/docs/webdriver-bidi.md)\n- [packages/puppeteer-core/src/bidi/core/README.md](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/core/README.md)\n</details>\n\n# 协议实现：CDP与WebDriver BiDi\n\n## 概述\n\nPuppeteer 同时支持两种浏览器自动化协议：**CDP（Chrome DevTools Protocol）** 和 **WebDriver BiDi（WebDriver Bi-Directional）**。这种双协议支持使 Puppeteer 能够提供跨浏览器兼容性和向后兼容性。\n\n| 协议 | 类型 | 支持浏览器 | 用途 |\n|------|------|-----------|------|\n| CDP | Chrome 专有 | Chrome、Chromium | 提供最完整的 Chrome 控制能力 |\n| WebDriver BiDi | W3C 标准 | Chrome、Firefox、Edge | 跨浏览器兼容性 |\n\n资料来源：[packages/puppeteer-core/src/node/PuppeteerNode.ts](packages/puppeteer-core/src/node/PuppeteerNode.ts)\n\n## 架构设计\n\n### 双协议架构\n\nPuppeteer 的协议实现采用分层架构，抽象层将底层协议细节与高级 API 解耦：\n\n```mermaid\ngraph TB\n    subgraph \"高级API层\"\n        P[Page]\n        B[Browser]\n        T[Target]\n    end\n    \n    subgraph \"协议抽象层\"\n        CDPA[CDP Browser]\n        BiDiA[BiDi Browser]\n    end\n    \n    subgraph \"连接层\"\n        CDPC[CDP Connection]\n        BiDiC[BiDi Connection]\n    end\n    \n    P --> CDPA\n    P --> BiDiA\n    B --> CDPA\n    B --> BiDiA\n    T --> CDPA\n    T --> BiDiA\n    \n    CDPA --> CDPC\n    BiDiA --> BiDiC\n```\n\n### CDP over BiDi 混合模式\n\n当使用 CDP 连接时，Puppeteer 可以选择性地将 BiDi 协议叠加在 CDP 连接之上：\n\n```typescript\nconst bidiOnly = process.env['PUPPETEER_WEBDRIVER_BIDI_ONLY'] === 'true';\nconst BiDi = await import('../bidi/bidi.js');\nconst bidiConnection = await BiDi.connectBidiOverCdp(cdpConnection);\n```\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:45-48](packages/puppeteer-core/src/node/BrowserLauncher.ts)\n\n## CDP 实现\n\n### CDP Browser\n\nCDP Browser 类负责管理基于 Chrome DevTools Protocol 的浏览器实例。CDP 协议提供对 Chrome 内部功能的深度控制，包括：\n\n- 完整的 JavaScript 执行环境\n- 网络请求拦截和修改\n- 性能分析\n- 页面截图和 PDF 生成\n- DOM 操作\n\n### CDP Connection\n\nCDP Connection 实现了基于 WebSocket 的 CDP 通信机制：\n\n| 组件 | 职责 |\n|------|------|\n| WebSocket 传输 | 底层双向通信 |\n| 命令分发 | 将 API 调用转换为 CDP 命令 |\n| 事件监听 | 转发浏览器事件到上层 |\n| 会话管理 | 管理多个 CDP 会话 |\n\nCDP 连接支持通过 `puppeteer.connect()` 方法进行远程连接，实现浏览器控制与浏览器进程的分离。\n\n## WebDriver BiDi 实现\n\n### BiDi 协议核心\n\nWebDriver BiDi 是 W3C 标准化的一种双向协议，设计目标是提供跨浏览器统一的自动化接口。Puppeteer 的 BiDi 实现位于 `packages/puppeteer-core/src/bidi/core/` 目录。\n\n#### 设计原则\n\nBiDi 核心实现遵循以下原则：\n\n1. **遵循规范**：`bidi/core` 严格遵循 WebDriver BiDi 规范，而非 Puppeteer 特定需求\n2. **全面性**：按图结构实现所有节点和边，不跳过任何中间步骤\n3. **最小化**：仅实现协议必需的功能，避免过度设计\n\n资料来源：[packages/puppeteer-core/src/bidi/core/README.md](packages/puppeteer-core/src/bidi/core/README.md)\n\n### BiDi Browser\n\nBiDi Browser 类提供基于 WebDriver BiDi 协议的浏览器控制：\n\n```typescript\nreturn await BiDi.BidiBrowser.create({\n  connection: bidiConnection,\n  // 当启用 BiDi-only 模式时不传递 CDP 连接\n  cdpConnection: bidiOnly ? undefined : cdpConnection,\n  closeCallback,\n  process: browserProcess.nodeProcess,\n  defaultViewport: opts.defaultViewport,\n  acceptInsecureCerts: opts.acceptInsecureCerts,\n  networkEnabled: opts.networkEnabled,\n  issuesEnabled: opts.issuesEnabled,\n});\n```\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:50-60](packages/puppeteer-core/src/node/BrowserLauncher.ts)\n\n### BiDi Connection\n\nBiDi Connection 负责 WebSocket 双向通信，处理 BiDi 协议的握手和消息传递。\n\n### BiDi Core 模块\n\n`bidi/core` 模块是 WebDriver BiDi 协议的纯规范实现：\n\n| 模块 | 功能 |\n|------|------|\n| core.ts | 协议核心逻辑、命令处理、事件分发 |\n| EventEmitter | 双向事件传输 |\n| Browsing Context | 浏览器上下文管理 |\n| Script | JavaScript 执行域 |\n\n#### 事件图结构\n\nBiDi 协议中的事件遵循严格的图结构。例如，导航事件必须按以下顺序触发：\n\n```\nfragment navigation → navigation → browsing context\n```\n\n不允许跳过中间节点，也不允许存在组合边（如同时存在上述路径和 `fragment navigation → browsing context`）。\n\n资料来源：[packages/puppeteer-core/src/bidi/core/README.md](packages/puppeteer-core/src/bidi/core/README.md)\n\n## 协议选择与配置\n\n### 环境变量控制\n\n| 环境变量 | 作用 | 值 |\n|----------|------|-----|\n| `PUPPETEER_WEBDRIVER_BIDI_ONLY` | 启用纯 BiDi 模式 | `true` 或 `false` |\n\n当 `PUPPETEER_WEBDRIVER_BIDI_ONLY=true` 时，Browser 对象不会持有 CDP 连接引用，强制使用 BiDi 端点：\n\n```typescript\ncdpConnection: bidiOnly ? undefined : cdpConnection,\n```\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:55](packages/puppeteer-core/src/node/BrowserLauncher.ts)\n\n### 启动配置\n\n通过 LaunchOptions 可自定义浏览器启动行为：\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| executablePath | 浏览器可执行文件路径 | 自动检测 |\n| ignoreDefaultArgs | 跳过默认参数 | false |\n| enableExtensions | 启用扩展支持 | false |\n| timeout | 启动超时(ms) | 30000 |\n| protocolTimeout | 协议超时(ms) | undefined |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts](packages/puppeteer-core/src/node/LaunchOptions.ts)\n\n## Target 抽象\n\nPuppeteer 通过 Target 抽象统一管理不同类型的浏览器目标：\n\n```mermaid\ngraph TD\n    T[Target 抽象]\n    CDPT[CDP Target]\n    BiDiT[BiDi Target]\n    \n    CDPT --> CDPT_Browser[CDP Browser Target]\n    CDPT --> CDPT_Page[CDP Page Target]\n    \n    BiDiT --> BiDiT_Browser[BiDi Browser Target]\n    BiDiT --> BiDiT_Page[BiDi Page Target]\n    \n    T --> CDPT\n    T --> BiDiT\n```\n\n### BiDi Target 实现\n\nBiDi Target 类体系包括：\n\n| 类 | 类型 | 说明 |\n|----|------|------|\n| BidiBrowserTarget | TargetType.BROWSER | 浏览器级别目标 |\n| BidiPageTarget | TargetType.PAGE | 页面级别目标 |\n| BidiFrameTarget | TargetType.FRAME | 帧级别目标 |\n| BidiWorkerTarget | TargetType.WORKER | Web Worker 目标 |\n\n```typescript\nexport class BidiBrowserTarget extends Target {\n  override type(): TargetType {\n    return TargetType.BROWSER;\n  }\n  override browser(): BidiBrowser {\n    return this.#browser;\n  }\n}\n```\n\n资料来源：[packages/puppeteer-core/src/bidi/Target.ts](packages/puppeteer-core/src/bidi/Target.ts)\n\n## 协议特性对比\n\n| 特性 | CDP | WebDriver BiDi |\n|------|-----|----------------|\n| 标准化程度 | Chrome 专有 | W3C 标准 |\n| 浏览器支持 | 仅 Chrome | Chrome、Firefox、Edge |\n| API 完整性 | 完整 | 部分功能 |\n| 跨浏览器兼容 | ✗ | ✓ |\n| 网络拦截 | 完整支持 | 基础支持 |\n| 性能分析 | 深度支持 | 有限支持 |\n| JavaScript 执行 | 完整上下文 | 受限沙箱 |\n\n## 使用场景建议\n\n### 选择 CDP 的场景\n\n- 需要完整的 Chrome 特性支持\n- 进行性能分析和调试\n- 需要精细的网络请求控制\n- 仅针对 Chrome/Chromium 环境\n\n### 选择 WebDriver BiDi 的场景\n\n- 需要跨浏览器兼容性\n- 遵循标准化协议要求\n- 与 Selenium 等工具集成\n- 测试环境包含多种浏览器\n\n## 扩展机制\n\n### 协议扩展\n\nPuppeteer 支持通过自定义 Provider 扩展浏览器下载和安装机制：\n\n```typescript\nimport {install} from '@puppeteer/browsers';\n\nawait install({\n  browser: Browser.CHROMEDRIVER,\n  cacheDir: './cache',\n  providers: [new CustomProvider()],\n});\n```\n\n资料来源：[packages/browsers/src/install.ts](packages/browsers/src/install.ts)\n\n## 总结\n\nPuppeteer 的双协议架构提供了灵活性和兼容性的平衡：\n\n1. **CDP 协议** 提供最深度的 Chrome 控制能力，适合需要高级功能的项目\n2. **WebDriver BiDi** 提供跨浏览器标准化接口，适合需要多浏览器支持的项目\n3. **混合模式** 允许在 CDP 连接上叠加 BiDi 协议，兼顾功能完整性和标准化\n4. **严格规范遵循** 确保 BiDi 实现的可移植性和正确性\n\n---\n\n<a id='page-browser-management'></a>\n\n## 浏览器启动与管理\n\n### 相关页面\n\n相关主题：[Puppeteer系统架构](#page-architecture)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/node/ChromeLauncher.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/ChromeLauncher.ts)\n- [packages/puppeteer-core/src/node/FirefoxLauncher.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/FirefoxLauncher.ts)\n- [packages/puppeteer-core/src/node/BrowserLauncher.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/BrowserLauncher.ts)\n- [packages/puppeteer-core/src/api/Browser.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Browser.ts)\n- [packages/puppeteer-core/src/api/BrowserContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/BrowserContext.ts)\n- [packages/browsers/src/launch.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/browsers/src/launch.ts)\n- [docs/guides/browser-management.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/browser-management.md)\n</details>\n\n# 浏览器启动与管理\n\n## 概述\n\nPuppeteer 的浏览器启动与管理模块是整个项目的核心组件之一，负责协调浏览器的生命周期、进程管理和资源分配。该模块通过抽象统一的 API，支持 Chrome、Firefox 等多种浏览器的启动、配置和销毁操作，同时提供细粒度的信号控制、超时管理和多上下文隔离机制。\n\n浏览器启动系统的设计遵循以下核心原则：\n\n- **跨平台兼容性**：统一处理不同操作系统（Linux、macOS、Windows）上的浏览器启动差异\n- **进程生命周期管理**：通过信号处理机制确保浏览器进程能够被正确终止\n- **可扩展性**：支持自定义可执行路径、浏览器参数和实验性功能配置\n- **资源隔离**：通过 BrowserContext 实现多浏览器上下文隔离\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:1-50]()\n\n## 架构设计\n\n### 核心组件关系\n\nPuppeteer 的浏览器启动架构采用分层设计，各层职责分明：\n\n```mermaid\ngraph TD\n    A[用户调用 puppeteer.launch] --> B[BrowserLauncher 抽象基类]\n    B --> C[ChromeLauncher]\n    B --> D[FirefoxLauncher]\n    C --> E[Chrome/Chromium 进程]\n    D --> F[Firefox 进程]\n    G[Configuration 配置] --> B\n    H[LaunchOptions 启动选项] --> B\n```\n\n| 层级 | 组件 | 职责 |\n|------|------|------|\n| 接口层 | `BrowserLauncher` | 定义浏览器启动的统一接口和流程 |\n| 实现层 | `ChromeLauncher` | 处理 Chrome/Chromium 特定启动逻辑 |\n| 实现层 | `FirefoxLauncher` | 处理 Firefox 特定启动逻辑 |\n| 配置层 | `Configuration` | 全局默认配置和浏览器特定设置 |\n| 选项层 | `LaunchOptions` | 用户指定的运行时启动参数 |\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts]()\n\n### 启动流程时序\n\n浏览器启动涉及多个阶段的协调操作：\n\n```mermaid\nsequenceDiagram\n    participant U as 用户代码\n    participant P as Puppeteer\n    participant L as BrowserLauncher\n    participant B as 浏览器进程\n    participant C as CDP/WebDriver\n    \n    U->>P: puppeteer.launch(options)\n    P->>L: 创建 Launcher 实例\n    L->>L: 解析配置和选项\n    L->>B: 启动浏览器进程\n    B-->>L: 进程已启动\n    L->>C: 建立连接\n    C-->>L: 连接就绪\n    L-->>P: 返回 Browser 实例\n    P-->>U: 返回 Browser 实例\n```\n\n资料来源：[packages/browsers/src/launch.ts:1-100]()\n\n## 支持的浏览器类型\n\n### 浏览器枚举\n\nPuppeteer 通过 `SupportedBrowser` 枚举定义支持的浏览器类型：\n\n| 枚举值 | 浏览器 | 说明 |\n|--------|--------|------|\n| `chrome` | Chrome for Testing | 默认浏览器，Puppeteer 主要支持的浏览器 |\n| `chrome-headless-shell` | Chrome Headless Shell | 无头 Chrome 精简版，体积更小 |\n| `firefox` | Firefox | Mozilla Firefox 浏览器 |\n\n配置接口中指定默认浏览器为 `chrome`：\n\n> Defines the default browser to use.\n>\n> @defaultValue `chrome`\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:1-50]()\n\n### 浏览器特定配置\n\n每种浏览器都有独立的配置命名空间：\n\n```typescript\ninterface Configuration {\n  chrome?: ChromeSettings;\n  ['chrome-headless-shell']?: ChromeHeadlessShellSettings;\n  firefox?: FirefoxSettings;\n}\n```\n\n**Chrome 设置参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `skipDownload` | `boolean` | `false` | 跳过浏览器下载 |\n| `downloadBaseUrl` | `string` | `https://storage.googleapis.com/chrome-for-testing-public` | 下载基础 URL |\n| `executablePath` | `string` | 自动推断 | 自定义可执行文件路径 |\n\n**Firefox 设置参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `skipDownload` | `boolean` | `true` | 跳过浏览器下载 |\n| `downloadBaseUrl` | `string` | `https://archive.mozilla.org/pub/firefox/releases` | 下载基础 URL |\n| `version` | `string` | Puppeteer 固定的版本 | 指定 Firefox 版本 |\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:50-150]()\n\n## 启动选项详解\n\n`LaunchOptions` 接口定义了启动浏览器时可配置的所有参数：\n\n### 基础配置参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `executablePath` | `string` | 捆绑浏览器 | 指定自定义浏览器可执行文件路径 |\n| `ignoreDefaultArgs` | `boolean \\| string[]` | `false` | 是否忽略默认参数或排除指定参数 |\n| `enableExtensions` | `boolean \\| string[]` | `false` | 启用扩展支持 |\n\n> If `true`, avoids passing default arguments to the browser that would prevent extensions from being enabled. Passing a list of strings will load the provided paths as unpacked extensions.\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:1-60]()\n\n### 进程信号控制\n\nPuppeteer 提供了完善的进程信号处理机制，确保在不同终止场景下浏览器进程能被正确关闭：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `handleSIGINT` | `boolean` | `true` | 接收到 `Ctrl+C` 时关闭浏览器 |\n| `handleSIGTERM` | `boolean` | `true` | 接收到 `SIGTERM` 信号时关闭浏览器 |\n| `handleSIGHUP` | `boolean` | `true` | 接收到 `SIGHUP` 信号时关闭浏览器 |\n\n### 超时配置\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `timeout` | `number` | `30_000` (30秒) | 浏览器启动超时时间（毫秒），设为 `0` 禁用超时 |\n\n> Maximum time in milliseconds to wait for the browser to start. Pass `0` to disable the timeout.\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:60-100]()\n\n### 其他启动参数\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `pipe` | `boolean` | 使用管道而非 WebSocket 连接 |\n| `dumpio` | `boolean` | 将浏览器 stdout/stderr 导出到进程 |\n| `userDataDir` | `string` | 用户数据目录（-profile 路径） |\n| `env` | `Record<string, string>` | 浏览器进程环境变量 |\n\n## Browser 类 API\n\n`Browser` 类是浏览器实例的抽象表示，封装了所有浏览器操作：\n\n### 核心方法\n\n| 方法 | 返回值 | 说明 |\n|------|--------|------|\n| `newPage()` | `Promise<Page>` | 创建新页面 |\n| `pages()` | `Promise<Page[]>` | 获取所有打开的页面 |\n| `createIncognitoBrowserContext()` | `Promise<BrowserContext>` | 创建私有浏览器上下文 |\n| `browserContexts()` | `BrowserContext[]` | 获取所有浏览器上下文 |\n| `version()` | `Promise<string>` | 获取浏览器版本 |\n| `process()` | `ChildProcess \\| null` | 获取浏览器进程对象 |\n| `close()` | `Promise<void>` | 关闭浏览器 |\n\n资料来源：[packages/puppeteer-core/src/api/Browser.ts:1-100]()\n\n### 浏览器进程管理\n\n通过 `process()` 方法可以访问底层的 Node.js 子进程：\n\n```typescript\nconst browser = await puppeteer.launch();\nconst proc = browser.process();\n\nif (proc) {\n  console.log(`Browser PID: ${proc.pid}`);\n  proc.kill(); // 强制终止\n}\n```\n\n### 版本检测\n\n```typescript\nconst browser = await puppeteer.launch();\nconst version = await browser.version();\nconsole.log(`Browser version: ${version}`);\n```\n\n## BrowserContext 浏览器上下文\n\n`BrowserContext` 提供了浏览器实例的隔离机制，类似于浏览器中的\"无痕模式\"：\n\n### 特性说明\n\n- 每个 BrowserContext 拥有独立的 cookie 存储\n- 每个 BrowserContext 拥有独立的会话存储\n- 不同 BrowserContext 之间的页面完全隔离\n- 共享进程但通过不同 CDP 会话隔离\n\n```mermaid\ngraph LR\n    A[Browser] --> B[BrowserContext A]\n    A --> C[BrowserContext B]\n    A --> D[BrowserContext C]\n    B --> E[Page 1]\n    B --> F[Page 2]\n    C --> G[Page 3]\n    D --> H[Page 4]\n    \n    style B fill:#e1f5fe\n    style C fill:#e1f5fe\n    style D fill:#e1f5fe\n```\n\n### 上下文 API\n\n| 方法 | 说明 |\n|------|------|\n| `createPage()` | 在当前上下文中创建新页面 |\n| `pages()` | 获取当前上下文中的所有页面 |\n| `close()` | 关闭浏览器上下文 |\n| `overridePermissions()` | 覆盖指定源的权限 |\n| `clearPermissionOverrides()` | 清除所有权限覆盖 |\n\n资料来源：[packages/puppeteer-core/src/api/BrowserContext.ts:1-80]()\n\n### 使用示例\n\n```typescript\n// 创建两个隔离的浏览器上下文\nconst context1 = await browser.createIncognitoBrowserContext();\nconst context2 = await browser.createIncognitoBrowserContext();\n\nconst page1 = await context1.newPage();\nconst page2 = await context2.newPage();\n\n// 两个页面的 cookie 完全隔离\nawait page1.goto('https://example.com');\nawait page2.goto('https://example.com');\n\n// 关闭上下文时释放资源\nawait context1.close();\n```\n\n## 生命周期管理\n\n### 启动阶段\n\n```mermaid\nflowchart TD\n    A[调用 launch] --> B{是否指定 executablePath}\n    B -->|是| C[验证可执行文件存在]\n    B -->|否| D[从缓存目录查找]\n    C --> E{文件存在?}\n    D --> E\n    E -->|否| F[抛出错误]\n    E -->|是| G[应用默认参数]\n    G --> H[启动子进程]\n    H --> I[建立 CDP 连接]\n    I --> J[等待浏览器就绪]\n    J --> K[返回 Browser 实例]\n```\n\n### 关闭阶段\n\n| 关闭方式 | 触发条件 | 行为 |\n|----------|----------|------|\n| 正常关闭 | 调用 `browser.close()` | 优雅关闭所有页面和上下文 |\n| SIGINT | `Ctrl+C` | 触发正常关闭流程 |\n| SIGTERM | 系统终止信号 | 触发正常关闭流程 |\n| SIGHUP | 终端挂起 | 触发正常关闭流程 |\n| 强制终止 | `process.exit()` | 浏览器进程可能残留 |\n\n### 错误处理\n\n浏览器启动失败时，Puppeteer 会根据失败原因抛出详细的错误信息：\n\n> Could not find Firefox (rev. ${browserVersion}). This can occur if either\n> 1. you did not perform an installation for Firefox before running the script (e.g. `npx puppeteer browsers install firefox`) or\n> 2. your cache path is incorrectly configured\n\n资料来源：[packages/puppeteer-core/src/node/BrowserLauncher.ts:80-100]()\n\n## 配置管理\n\n### 环境变量覆盖\n\nPuppeteer 支持通过环境变量覆盖配置：\n\n| 环境变量 | 配置属性 | 说明 |\n|----------|----------|------|\n| `PUPPETEER_SKIP_DOWNLOAD` | `skipDownload` | 跳过浏览器下载 |\n| `PUPPETEER_TMP_DIR` | `temporaryDirectory` | 临时文件目录 |\n| `PUPPETEER_CACHE_DIR` | `cacheDirectory` | 浏览器缓存目录 |\n| `PUPPETEER_CHROME_SKIP_DOWNLOAD` | `chrome.skipDownload` | 跳过 Chrome 下载 |\n| `PUPPETEER_FIREFOX_SKIP_DOWNLOAD` | `firefox.skipDownload` | 跳过 Firefox 下载 |\n\n### 配置文件方式\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nconst browser = await puppeteer.launch({\n  // 启动选项\n  timeout: 60000,\n  headless: true,\n  \n  // 浏览器特定配置\n  chrome: {\n    executablePath: '/custom/chrome/path',\n    args: ['--disable-dev-shm-usage']\n  }\n});\n```\n\n## 实际使用示例\n\n### 基础启动\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\nawait page.goto('https://example.com');\n\nawait browser.close();\n```\n\n### 自定义配置启动\n\n```typescript\nconst browser = await puppeteer.launch({\n  headless: false,\n  executablePath: '/path/to/chrome',\n  args: [\n    '--disable-gpu',\n    '--no-sandbox',\n    '--disable-setuid-sandbox',\n    '--disable-dev-shm-usage'\n  ],\n  timeout: 60000,\n  handleSIGINT: true,\n  handleSIGTERM: true\n});\n```\n\n### 多上下文隔离\n\n```typescript\nconst browser = await puppeteer.launch();\n\n// 用户 A 的上下文\nconst contextA = await browser.createIncognitoBrowserContext();\nconst pageA = await contextA.newPage();\nawait pageA.goto('https://login.example.com');\nawait pageA.type('#username', 'user_a');\n\n// 用户 B 的上下文\nconst contextB = await browser.createIncognitoBrowserContext();\nconst pageB = await contextB.newPage();\nawait pageB.goto('https://login.example.com');\nawait pageB.type('#username', 'user_b');\n\n// 独立验证，不会互相干扰\nawait Promise.all([\n  pageA.click('#submit'),\n  pageB.click('#submit')\n]);\n\nawait contextA.close();\nawait contextB.close();\nawait browser.close();\n```\n\n## 最佳实践\n\n### 资源管理\n\n1. **始终关闭浏览器**：使用 `try...finally` 或 `await browser.close()` 确保资源释放\n2. **限制页面数量**：避免创建过多页面导致资源耗尽\n3. **使用上下文隔离**：需要隔离操作时使用 `BrowserContext` 而非启动多个浏览器实例\n\n### 稳定性建议\n\n| 场景 | 推荐配置 |\n|------|----------|\n| Docker/容器环境 | 添加 `--no-sandbox`、`--disable-dev-shm-usage` 参数 |\n| CI/CD 环境 | 使用 `headless: true` 并设置合理的 `timeout` |\n| 资源受限环境 | 使用 `chrome-headless-shell` 减少内存占用 |\n| 需要扩展支持 | 设置 `enableExtensions` 为 `true` |\n\n### 调试技巧\n\n1. **查看浏览器日志**：`dumpio: true` 可捕获浏览器输出\n2. **使用自定义用户数据目录**：便于检查浏览器状态\n3. **禁用默认参数调试**：`ignoreDefaultArgs: true` 后手动添加所需参数\n\n## 相关命令\n\n### 浏览器管理 CLI\n\n通过 `@puppeteer/browsers` 包管理已安装的浏览器：\n\n```bash\n# 列出已安装的浏览器\nnpx @puppeteer/browsers list\n\n# 安装 Chrome Stable\nnpx @puppeteer/browsers install chrome@stable\n\n# 安装指定版本 Chrome\nnpx @puppeteer/browsers install chrome@116.0.5793.0\n\n# 安装最新 ChromeDriver\nnpx @puppeteer/browsers install chromedriver@canary\n\n# 清理所有已安装浏览器\nnpx @puppeteer/browsers clear\n```\n\n资料来源：[packages/browsers/README.md:1-80]()\n\n## 总结\n\nPuppeteer 的浏览器启动与管理模块通过统一的抽象层，优雅地解决了跨浏览器、跨平台的启动管理问题。其核心设计包括：\n\n- **统一接口**：`BrowserLauncher` 抽象基类为不同浏览器提供一致的操作体验\n- **灵活配置**：通过 `LaunchOptions` 和 `Configuration` 支持细粒度的参数控制\n- **进程安全**：完善的信号处理机制确保浏览器进程在各种场景下都能正确关闭\n- **上下文隔离**：`BrowserContext` 提供会话级隔离，适合多用户模拟场景\n- **错误友好**：详细的错误信息帮助开发者快速定位问题\n\n掌握这些机制，能够帮助开发者构建更加稳定、可靠的浏览器自动化应用。\n\n---\n\n<a id='page-page-api'></a>\n\n## Page页面操作API\n\n### 相关页面\n\n相关主题：[元素定位器与操作](#page-element-locator), [网络请求拦截与管理](#page-network)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/cdp/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Page.ts)\n- [packages/puppeteer-core/src/bidi/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/Page.ts)\n- [packages/puppeteer-core/src/api/Frame.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Frame.ts)\n- [docs/guides/page-interactions.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/page-interactions.md)\n- [docs/guides/screenshots.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/screenshots.md)\n- [docs/guides/pdf-generation.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/pdf-generation.md)\n</details>\n\n# Page页面操作API\n\n## 概述\n\nPage页面操作API是Puppeteer的核心模块之一，提供了与浏览器页面进行交互的完整能力。该API封装了浏览器自动化所需的各种操作，包括页面导航、内容查询、元素交互、JavaScript执行、截图和PDF生成等功能。\n\nPage类继承自Puppeteer的EventEmitter类，会发出各种在PageEvent枚举中定义的事件。Puppeteer支持两种底层协议实现：Chrome DevTools Protocol (CDP) 和 WebDriver BiDi (BiDi)，它们都实现了统一的Page抽象接口。\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:100]()\n\n## 架构设计\n\n### 实现层次结构\n\n```mermaid\ngraph TD\n    A[Page 抽象基类] --> B[CDPPage CDP协议实现]\n    A --> C[BiDiPage BiDi协议实现]\n    D[Frame 抽象基类] --> E[CDPFrame]\n    D --> F[BiDiFrame]\n    G[EventEmitter] --> A\n    H[JSHandle] --> I[ElementHandle]\n```\n\n### 核心组件关系\n\n| 组件 | 类型 | 职责 |\n|------|------|------|\n| Page | 抽象类 | 定义页面操作的统一接口 |\n| CDPPage | 实现类 | 通过CDP协议与Chrome通信 |\n| BiDiPage | 实现类 | 通过BiDi协议与浏览器通信 |\n| Frame | 抽象类 | 管理页面帧结构 |\n| JSHandle | 抽象类 | JavaScript对象句柄 |\n| ElementHandle | 抽象类 | DOM元素句柄 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:97-120]()\n\n## 页面生命周期\n\n### 页面状态管理\n\n```mermaid\nstateDiagram-v2\n    [*] --> 创建中: browser.newPage()\n    创建中 --> 已加载: 页面初始化完成\n    已加载 --> 导航中: goto() / setContent()\n    导航中 --> 已加载: 导航完成\n    已加载 --> 关闭中: close()\n    关闭中 --> [*]: 资源清理完成\n    已加载 --> 已加载: 页面刷新/前进后退\n```\n\n### 内部状态变量\n\nPage类维护以下内部状态：\n\n```typescript\n_isDragging = false;           // 拖拽状态\n_timeoutSettings = new TimeoutSettings();  // 超时配置\n_tabId = '';                   // 浏览器标签页ID\n#requestHandlers = WeakMap;    // 请求处理器映射\n#inflight$ = ReplaySubject;    // 进行中的请求流\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:105-115]()\n\n## 页面导航操作\n\n### goto - 页面跳转\n\n导航到指定URL并等待页面加载完成。\n\n```typescript\nawait page.goto('https://developer.chrome.com/');\n```\n\n**参数说明：**\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| url | string | 是 | 目标页面URL |\n| options | NavigationOptions | 否 | 导航选项配置 |\n\n**导航选项：**\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| timeout | number | 30s | 导航超时时间(毫秒) |\n| waitUntil | WaitUntilOptions | load | 等待条件 |\n| referer | string | - | 引荐来源URL |\n\n**waitUntil 支持的值：**\n\n| 值 | 说明 |\n|----|------|\n| `load` | 等待 load 事件触发 |\n| `domcontentloaded` | 等待 DOMContentLoaded 事件 |\n| `networkidle0` | 等待无网络连接(500ms内) |\n| `networkidle2` | 等待最多2个网络连接 |\n\n### setContent - 设置页面内容\n\n直接设置页面的HTML内容。\n\n```typescript\nawait page.setContent('<html><body><h1>Hello</h1></body></html>');\n```\n\n### reload - 刷新页面\n\n```typescript\nawait page.reload();\nawait page.reload({ timeout: 60000 });\n```\n\n### goBack / goForward - 历史导航\n\n```typescript\nawait page.goBack();      // 返回上一页\nawait page.goForward();   // 前进到下一页\n```\n\n## 元素查询与选择器\n\n### 选择器类型\n\nPuppeteer支持多种选择器类型，可以满足不同的查询需求：\n\n```mermaid\ngraph LR\n    A[选择器查询] --> B[CSS选择器]\n    A --> C[ARIA选择器]\n    A --> D[文本选择器]\n    A --> E[XPath选择器]\n    A --> F[Pierce选择器]\n```\n\n### 选择器类型对照表\n\n| 类型 | 语法 | 示例 |\n|------|------|------|\n| CSS | 标准CSS选择器 | `page.$('div.container')` |\n| ARIA | `::-p-aria(...)` | `page.locator('::-p-aria(Search)')` |\n| 文本 | `::-p-text(...)` | `page.locator('::-p-text(Click me)')` |\n| XPath | `::-p-xpath(...)` | `page.locator('::-p-xpath(//button)')` |\n| Pierce | `::-p-shadow(...)` | 穿透Shadow DOM查询 |\n\n资料来源：[packages/ng-schematics/README.md]()\n\n### 查询方法\n\n#### 单元素查询\n\n```typescript\n// CSS选择器\nconst button = await page.$('button.submit');\n\n// ARIA选择器\nconst searchInput = await page.$('::-p-aria(Search field)');\n\n// 文本选择器\nconst heading = await page.locator('::-p-text(Welcome)');\n```\n\n#### 多元素查询\n\n```typescript\nconst inputs = await page.$$('input[type=\"text\"]');\nconst items = await page.locator('li.item');\n```\n\n#### 高级查询\n\n```typescript\n// 跨Shadow DOM查询\nconst shadowElement = await page.locator('::-p-shadow(div.inner)');\n\n// 组合选择器\nconst complex = await page.locator('div.container >> text=Submit');\n```\n\n### $$eval - 批量元素操作\n\n在所有匹配元素上执行JavaScript函数：\n\n```typescript\nconst allInputValues = await page.$$eval('input', elements =>\n  elements.map(e => e.textContent)\n);\n```\n\n**参数说明：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| selector | string | CSS或其他类型选择器 |\n| pageFunction | Function | 在页面上下文执行的函数 |\n| args | any[] | 额外参数 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:220-240]()\n\n## JavaScript执行与函数注入\n\n### evaluate - 页面内执行JavaScript\n\n```typescript\nconst title = await page.evaluate(() => document.title);\n\nconst result = await page.evaluate(async () => {\n  const response = await fetch('/api/data');\n  return await response.json();\n});\n```\n\n### exposeFunction - 注入全局函数\n\n将Node.js函数暴露到页面window对象，页面JavaScript可以直接调用：\n\n```typescript\nimport crypto from 'crypto';\n\nawait page.exposeFunction('md5', text =>\n  crypto.createHash('md5').update(text).digest('hex')\n);\n\nawait page.evaluate(async () => {\n  const hash = await window.md5('PUPPETEER');\n  console.log(`md5: ${hash}`);\n});\n```\n\n**使用场景：**\n\n| 场景 | 说明 |\n|------|------|\n| 文件读取 | 在页面中读取服务器文件系统 |\n| 数据库访问 | 从页面查询数据库 |\n| API调用 | 使用Node.js HTTP客户端 |\n| 加密操作 | 复杂加密在Node端执行 |\n\n**特性：**\n\n- 通过`exposeFunction`注入的函数在页面导航后仍然有效\n- 如果注入的函数返回Promise，会自动await\n- 支持`Function`或`{default: Function}`类型\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:155-185]()\n\n### ExecutionContext - 执行上下文\n\nCDP实现的执行上下文提供了更底层的控制：\n\n```mermaid\nsequenceDiagram\n    participant P as Puppeteer\n    participant EC as ExecutionContext\n    participant B as Browser\n    \n    P->>EC: evaluate(pageFunction)\n    EC->>B: Runtime.evaluate\n    B-->>EC: result/exceptionDetails\n    EC-->>P: HandleFor<T> 或值\n```\n\n## 页面截图\n\n### 基本截图\n\n```typescript\nawait page.screenshot({ path: 'screenshot.png' });\n```\n\n### 截图选项\n\n| 选项 | 类型 | 说明 |\n|------|------|------|\n| type | 'png' \\| 'jpeg' \\| 'webp' | 图片格式 |\n| quality | number | 图片质量(0-100) |\n| fullPage | boolean | 是否截取完整页面 |\n| clip | Clip | 截图区域 |\n| omitBackground | boolean | 隐藏默认背景 |\n| encoding | 'binary' \\| 'base64' | 返回格式 |\n\n### 完整页面截图\n\n```typescript\nawait page.screenshot({\n  path: 'fullpage.png',\n  fullPage: true\n});\n```\n\n### 区域截图\n\n```typescript\nawait page.screenshot({\n  path: 'header.png',\n  clip: {\n    x: 0,\n    y: 0,\n    width: 800,\n    height: 100\n  }\n});\n```\n\n### Buffer返回\n\n```typescript\nconst buffer = await page.screenshot({\n  type: 'png',\n  encoding: 'binary'\n});\n```\n\n资料来源：[docs/guides/screenshots.md]()\n\n## PDF生成\n\n### 基本PDF生成\n\n```typescript\nawait page.pdf({ path: 'page.pdf' });\n```\n\n### PDF选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| printBackground | boolean | false | 打印背景色和图片 |\n| landscape | boolean | false | 横向打印 |\n| format | PaperFormat | 'Letter' | 纸张格式 |\n| width | string | - | 自定义宽度 |\n| height | string | - | 自定义高度 |\n| margin | Margin | - | 页边距 |\n| scale | number | 1 | 缩放比例 |\n| displayHeaderFooter | boolean | false | 显示页眉页脚 |\n| headerTemplate | string | - | 页眉HTML模板 |\n| footerTemplate | string | - | 页脚HTML模板 |\n\n### 常用纸张格式\n\n| 格式 | 尺寸 |\n|------|------|\n| Letter | 8.5in x 11in |\n| Legal | 8.5in x 14in |\n| Tabloid | 11in x 17in |\n| A4 | 210mm x 297mm |\n| A3 | 297mm x 420mm |\n| A5 | 148mm x 210mm |\n\n### 自定义尺寸示例\n\n```typescript\nawait page.pdf({\n  path: 'custom.pdf',\n  width: '210mm',\n  height: '297mm',\n  printBackground: true,\n  margin: {\n    top: '20mm',\n    bottom: '20mm',\n    left: '20mm',\n    right: '20mm'\n  }\n});\n```\n\n资料来源：[docs/guides/pdf-generation.md]()\n\n## 页面事件系统\n\n### 事件类型\n\nPage类继承自EventEmitter，支持以下核心事件：\n\n```mermaid\ngraph LR\n    A[Page Events] --> B[导航事件]\n    A --> C[请求事件]\n    A --> D[响应事件]\n    A --> E[对话框事件]\n    A --> F[帧事件]\n    \n    B --> B1[load]\n    B --> B2[domcontentloaded]\n    B --> B3[navigation]\n    \n    C --> C1[request]\n    C --> C2[requestfailed]\n    C --> C3[requestfinished]\n    \n    D --> D1[response]\n    \n    E --> E1[dialog]\n    \n    F --> F1[frameattached]\n    F --> F2[framedetached]\n    F --> F3[framenavigated]\n```\n\n### 常用事件监听\n\n```typescript\n// 页面加载完成\npage.once('load', () => console.log('Page loaded!'));\n\n// 监听所有请求\npage.on('request', request => {\n  console.log('Request:', request.url());\n});\n\n// 监听响应\npage.on('response', response => {\n  console.log('Response:', response.url(), response.status());\n});\n\n// 处理对话框\npage.on('dialog', async dialog => {\n  console.log('Dialog:', dialog.message());\n  await dialog.accept();\n});\n\n// 订阅与取消订阅\nconst handler = request => console.log(request.url());\npage.on('request', handler);\npage.off('request', handler);\n```\n\n### 导航相关事件\n\n| 事件 | 说明 | 回调参数 |\n|------|------|----------|\n| load | 页面完全加载 | - |\n| domcontentloaded | DOM解析完成 | - |\n| navigation | 导航开始 | - |\n| framenavigated | 帧导航完成 | Frame |\n\n### 请求相关事件\n\n| 事件 | 说明 | 回调参数 |\n|------|------|----------|\n| request | 发起请求 | HTTPRequest |\n| requestfailed | 请求失败 | HTTPRequest |\n| requestfinished | 请求完成 | HTTPRequest |\n| response | 收到响应 | HTTPResponse |\n\n## 帧(Frame)处理\n\n### Frame类结构\n\nFrame类提供了页面帧管理的能力，包括主框架和iframe。\n\n```mermaid\ngraph TD\n    Page --> Frame\n    Frame --> IFrame1[iframe]\n    Frame --> IFrame2[iframe]\n    IFrame1 --> NestedFrame[嵌套帧]\n```\n\n### 帧查询方法\n\n```typescript\n// 获取主框架\nconst mainFrame = page.mainFrame();\n\n// 获取所有框架\nconst frames = page.frames();\n\n// 根据name属性查找iframe\nconst iframe = page.frame('my-iframe');\n\n// 通过URL查找框架\nconst authFrame = page.frame({ url: /\\/auth/ });\n```\n\n### Frame中的操作\n\nFrame类实现了与Page类似的API，可以在帧上下文中执行操作：\n\n```typescript\n// 在特定帧中执行JavaScript\nconst result = await frame.evaluate(() => document.title);\n\n// 在特定帧中查找元素\nconst button = await frame.$('button.submit');\n\n// 等待帧加载\nawait frame.waitForSelector('.content-loaded');\n```\n\n### Frame与Page的关系\n\n```typescript\n// Frame的parentFrame\nconst parent = frame.parentFrame();  // 返回父帧或null\n\n// 帧的name属性\nconsole.log(frame.name());  // iframe的name属性值\n\n// 帧的URL\nconsole.log(frame.url());   // 帧的当前URL\n```\n\n资料来源：[packages/puppeteer-core/src/api/Frame.ts]()\n\n## Viewport与设备模拟\n\n### setViewport - 设置视口\n\n```typescript\nawait page.setViewport({ width: 1080, height: 1024 });\n```\n\n### 设备模拟\n\nPuppeteer内置了常用设备的配置：\n\n```typescript\nimport { KnownDevices } from 'puppeteer';\n\nconst iPhone = KnownDevices['iPhone 15 Pro'];\n\nawait page.emulate(iPhone);\n```\n\n### 自定义设备配置\n\n```typescript\nawait page.emulate({\n  name: 'Custom Device',\n  userAgent: 'Mozilla/5.0...',\n  viewport: {\n    width: 375,\n    height: 812,\n    deviceScaleFactor: 3,\n    isMobile: true,\n    hasTouch: true,\n    isLandscape: false\n  }\n});\n```\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts]()\n\n## 超时配置\n\n### TimeoutSettings\n\nPuppeteer使用TimeoutSettings类统一管理各种超时配置。\n\n### 常用超时配置\n\n```typescript\n// 设置默认导航超时\npage.setDefaultNavigationTimeout(60000);\n\n// 设置默认操作超时\npage.setDefaultTimeout(30000);\n\n// 设置单次操作超时\nawait page.waitForSelector('.element', { timeout: 5000 });\n```\n\n### 超时选项说明\n\n| 选项 | 默认值 | 说明 |\n|------|--------|------|\n| navigationTimeout | 30000ms | 页面导航超时 |\n| defaultTimeout | 30000ms | 默认操作超时 |\n| waitForTimeout | 30000ms | 等待元素超时 |\n\n## CDP与BiDi实现差异\n\n### 架构对比\n\n| 特性 | CDPPage | BiDiPage |\n|------|---------|----------|\n| 底层协议 | Chrome DevTools Protocol | WebDriver BiDi |\n| 浏览器支持 | Chrome/Edge | 所有主流浏览器 |\n| 功能完整性 | 完整 | 部分特性 |\n| 性能 | 较高 | 相对较低 |\n| 调试能力 | 强 | 一般 |\n\n### 实现文件\n\n- **CDP实现**: `packages/puppeteer-core/src/cdp/Page.ts`\n- **BiDi实现**: `packages/puppeteer-core/src/bidi/Page.ts`\n\n两种实现都遵循`packages/puppeteer-core/src/api/Page.ts`中定义的抽象接口，确保API行为的一致性。\n\n## 最佳实践\n\n### 页面操作流程\n\n```mermaid\ngraph TD\n    A[启动浏览器] --> B[创建页面]\n    B --> C[设置Viewport]\n    C --> D[导航到URL]\n    D --> E{等待条件}\n    E -->|元素存在| F[执行操作]\n    E -->|等待超时| G[处理错误]\n    F --> H[截图/PDF]\n    H --> I[关闭页面]\n    G --> I\n```\n\n### 错误处理\n\n```typescript\ntry {\n  await page.goto('https://example.com', {\n    timeout: 30000,\n    waitUntil: 'networkidle0'\n  });\n} catch (error) {\n  if (error.message.includes('net::ERR_')) {\n    console.error('Network error occurred');\n  } else if (error.message.includes('timeout')) {\n    console.error('Navigation timeout');\n  }\n}\n```\n\n### 资源清理\n\n```typescript\n// 使用完记得关闭页面\nconst page = await browser.newPage();\ntry {\n  // 操作...\n} finally {\n  await page.close();\n}\n\n// 等待特定元素时使用waitForSelector的cleanup\nconst handle = await page.waitForSelector('.modal', {\n  timeout: 5000\n}).catch(() => null);\n\nif (handle) {\n  // 使用handle\n  await handle.dispose();\n}\n```\n\n### 性能优化建议\n\n1. **避免频繁截图** - 截图操作较耗时，按需使用\n2. **合理设置超时** - 过长超时会增加等待时间\n3. **使用waitForSelector** - 比固定延迟更高效\n4. **批量操作** - 减少页面交互次数\n5. **复用Page实例** - 避免频繁创建销毁页面\n\n## 相关链接\n\n- [Page Interactions 指南](https://pptr.dev/guides/page-interactions)\n- [Selectors 文档](https://pptr.dev/guides/selectors)\n- [Screenshots 指南](https://pptr.dev/guides/screenshots)\n- [PDF Generation 指南](https://pptr.dev/guides/pdf-generation)\n- [Locators API (实验性)](https://pptr.dev/guides/locators)\n\n---\n\n<a id='page-element-locator'></a>\n\n## 元素定位器与操作\n\n### 相关页面\n\n相关主题：[Page页面操作API](#page-page-api)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/ElementHandle.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/ElementHandle.ts)\n- [packages/puppeteer-core/src/api/locators/locators.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)\n- [packages/puppeteer-core/src/cdp/ElementHandle.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ElementHandle.ts)\n- [packages/puppeteer-core/src/injected/ARIAQuerySelector.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/ARIAQuerySelector.ts)\n- [packages/puppeteer-core/src/injected/PierceQuerySelector.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/PierceQuerySelector.ts)\n- [packages/puppeteer-core/src/common/CustomQueryHandler.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/CustomQueryHandler.ts)\n</details>\n\n# 元素定位器与操作\n\n## 概述\n\n元素定位器与操作是 Puppeteer 自动化框架中用于在网页中查找和交互 DOM 元素的核心模块。该系统提供了多种定位策略，包括 CSS 选择器、ARIA 角色定位、文本匹配、XPath 表达式以及穿透 Shadow DOM 的选择器，同时支持通过定位器 API 实现稳定的元素等待和交互操作。\n\n定位器（Locator）是对传统 `page.$()` 和 `page.$$()` 查询方式的现代化封装，提供了更好的错误处理、自动重试机制以及流畅的 API 设计。元素句柄（ElementHandle）则代表了页面中 DOM 元素的引用，通过它可以执行点击、填充、拖拽等交互操作。\n\n## 架构设计\n\n### 核心组件关系\n\n```mermaid\ngraph TD\n    A[Page] --> B[Locator API]\n    A --> C[ElementHandle API]\n    B --> D[Query Handler]\n    C --> D\n    D --> E[CSS Selector Handler]\n    D --> F[ARIA Selector Handler]\n    D --> G[Text Selector Handler]\n    D --> H[XPath Selector Handler]\n    D --> I[Pierce Selector Handler]\n    D --> J[Custom Query Handler]\n```\n\n### 定位器与元素句柄的职责划分\n\n| 组件 | 职责 | 特点 |\n|------|------|------|\n| Locator | 描述如何定位元素，提供延迟解析和自动等待 | 每次调用都会重新查询，支持重试 |\n| ElementHandle | 持有元素引用，执行具体操作 | 可能因导航而失效，需要管理生命周期 |\n| QueryHandler | 实现具体的查询逻辑 | 插件化设计，支持自定义扩展 |\n\n资料来源：[packages/puppeteer-core/src/api/locators/locators.ts:1-50](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)\n\n## 选择器类型详解\n\n### 支持的选择器类型\n\nPuppeteer 支持多种选择器语法，可通过前缀或组合方式使用：\n\n| 选择器类型 | 前缀 | 示例 | 说明 |\n|-----------|------|------|------|\n| CSS 选择器 | 无 | `div.container` | 标准 CSS 选择器 |\n| ARIA 角色 | `::-p-aria` | `::-p-aria([name=\"搜索\"])` | 通过无障碍属性定位 |\n| 文本匹配 | `::-p-text` | `::-p-text(提交)` | 通过元素文本内容定位 |\n| XPath | `::-p-xpath` | `::-p-xpath(//button)` | XPath 表达式 |\n| 穿透选择器 | `pierce/` | `pierce/>>> button` | 穿透 Shadow DOM 边界 |\n\n资料来源：[packages/puppeteer-core/src/common/CustomQueryHandler.ts:1-30](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/CustomQueryHandler.ts)\n\n### ARIA 选择器实现\n\nARIA 选择器通过无障碍 API 查询页面元素，其核心实现在 `ARIAQuerySelector.ts` 中：\n\n```typescript\nexport class ARIAQueryHandler {\n  async queryOne(\n    root: Node,\n    selector: string\n  ): Promise<ElementHandle<Node> | null> {\n    // 使用 ARIA 属性查询 DOM\n  }\n}\n```\n\n该处理器利用浏览器原生 ARIA 查询能力，支持通过角色、名称、状态等属性定位元素。\n\n资料来源：[packages/puppeteer-core/src/injected/ARIAQuerySelector.ts:1-80](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/ARIAQuerySelector.ts)\n\n### 穿透选择器实现\n\n穿透选择器（Pierce Selector）能够跨越 Shadow DOM 边界进行查询：\n\n```typescript\nexport class PierceQueryHandler {\n  async queryOne(\n    root: Node,\n    selector: string\n  ): Promise<ElementHandle<Node> | null> {\n    // 递归遍历 shadowRoot 查找匹配元素\n  }\n}\n```\n\n该选择器通过递归遍历文档树和所有 Shadow DOM 来查找匹配的元素，适用于复杂的 Web 组件场景。\n\n资料来源：[packages/puppeteer-core/src/injected/PierceQuerySelector.ts:1-60](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/injected/PierceQuerySelector.ts)\n\n## 定位器 API\n\n### 定位器工作流程\n\n```mermaid\nsequenceDiagram\n    participant User as 用户\n    participant Locator as Locator\n    participant QueryHandler as QueryHandler\n    participant Browser as 浏览器\n\n    User->>Locator: 创建定位器\n    Locator->>User: 返回 Locator 实例\n    User->>Locator: waitHandle()\n    Locator->>QueryHandler: 执行查询\n    QueryHandler->>Browser: DOM 查询\n    Browser-->>QueryHandler: 返回元素引用\n    QueryHandler-->>Locator: ElementHandle\n    Locator-->>User: Promise<Handle>\n```\n\n### 主要定位器方法\n\n| 方法 | 返回类型 | 说明 |\n|------|----------|------|\n| `locator(selector)` | Locator | 创建新的定位器 |\n| `waitHandle()` | Promise<Handle> | 等待并返回元素句柄 |\n| `first()` | Locator | 获取匹配的第一个元素定位器 |\n| `nth(index)` | Locator | 获取指定索引的定位器 |\n| `filter(options)` | Locator | 按条件过滤定位结果 |\n| `map(fn)` | ... | 映射操作 |\n| `wait(options?)` | Promise | 等待元素出现 |\n\n资料来源：[packages/puppeteer-core/src/api/locators/locators.ts:50-150](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/locators/locators.ts)\n\n### 使用示例\n\n```typescript\n// 使用 locator API 进行稳定操作\nconst button = page.locator('button[type=\"submit\"]');\nawait button.wait();\nawait button.click();\n\n// 使用 ARIA 选择器\nconst searchInput = page.locator('::-p-aria([name=\"搜索框\"])');\n\n// 使用文本选择器\nconst submitBtn = page.locator('::-p-text(提交)');\n\n// 穿透 Shadow DOM\nconst nestedButton = page.locator('pierce/>>> my-component >>> button');\n```\n\n## 元素句柄操作\n\n### 元素句柄生命周期\n\n```mermaid\ngraph LR\n    A[创建 ElementHandle] --> B{页面导航}\n    B -->|发生| C[句柄失效]\n    B -->|未发生| D[可继续使用]\n    C --> E[需重新查询]\n    D --> F[执行操作]\n    F --> G[释放资源]\n```\n\n### ElementHandle 核心方法\n\n| 方法 | 说明 | 返回值 |\n|------|------|--------|\n| `click(options?)` | 点击元素 | Promise<void> |\n| `fill(value)` | 填充输入框 | Promise<void> |\n| `tap()` | 触发触摸事件 | Promise<void> |\n| `hover()` | 鼠标悬停 | Promise<void> |\n| `scrollIntoViewIfNeeded()` | 滚动到可视区域 | Promise<void> |\n| `drag(...targets)` | 执行拖拽操作 | Promise<void> |\n| `uploadFile(...filePaths)` | 上传文件 | Promise<void> |\n\n资料来源：[packages/puppeteer-core/src/api/ElementHandle.ts:50-200](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/ElementHandle.ts)\n\n### CDP 实现细节\n\nCDP（Chrome DevTools Protocol）实现提供了高性能的元素交互能力：\n\n```typescript\nclass ElementHandleImpl extends CDPJSHandle implements ElementHandle<Node> {\n  #client: CdpCDPClient;\n  \n  async click(options?: ClickOptions): Promise<void> {\n    const { x, y } = await this.clickablePoint();\n    this.#client.input.dispatchMouseEvent({\n      type: 'mousePressed',\n      button: 'left',\n      x, y\n    });\n  }\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/ElementHandle.ts:100-180](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ElementHandle.ts)\n\n## 自定义查询处理器\n\n### 注册自定义选择器\n\n通过 `CustomQueryHandler` 可以扩展 Puppeteer 的查询能力：\n\n```typescript\nimport { register } from 'puppeteer';\n\nregister('jQuery', {\n  queryOne: (root: Node, selector: string) => {\n    // 实现 jQuery 选择逻辑\n    return root.querySelector(selector);\n  },\n  queryAll: (root: Node, selector: string) => {\n    return root.querySelectorAll(selector);\n  }\n});\n```\n\n### 自定义处理器结构\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `queryOne` | `(root: Node, selector: string) => ElementHandle \\| null` | 返回第一个匹配元素 |\n| `queryAll` | `(root: Node, selector: string) => ElementHandle[]` | 返回所有匹配元素 |\n\n资料来源：[packages/puppeteer-core/src/common/CustomQueryHandler.ts:30-80](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/CustomQueryHandler.ts)\n\n## 等待与重试机制\n\n### 定位器等待策略\n\n```mermaid\ngraph TD\n    A[开始等待] --> B{超时?}\n    B -->|是| C[抛出 TimeoutError]\n    B -->|否| D{元素存在?}\n    D -->|否| E[重新查询]\n    E --> B\n    D -->|是| F{检查条件?}\n    F -->|否| G[等待后重新检查]\n    G --> B\n    F -->|是| H[返回元素句柄]\n```\n\n### 等待选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `timeout` | number | 继承自 page | 等待超时时间（毫秒） |\n| `state` | 'attached' \\| 'detached' \\| 'visible' \\| 'hidden' | 'visible' | 元素状态条件 |\n| `signal` | AbortSignal | undefined | 中止信号 |\n\n## 最佳实践\n\n### 选择器性能优化\n\n| 场景 | 推荐选择器 | 原因 |\n|------|-----------|------|\n| 唯一元素 | `#id` 或 `data-testid` | 最快，浏览器原生支持 |\n| 语义化查询 | `::-p-aria` | 可访问性好，不依赖样式 |\n| 复杂层级 | `pierce/` | 穿透 Shadow DOM |\n| 避免 | `:nth-of-type` 深层嵌套 | 性能较差 |\n\n### 稳定性建议\n\n1. **优先使用定位器 API**：相比 ElementHandle，定位器提供自动重试和更好的错误信息\n2. **显式等待而非硬编码延迟**：使用 `wait()` 方法等待元素状态变化\n3. **使用语义化选择器**：通过 ARIA 属性而非 CSS 类名定位元素\n4. **管理资源生命周期**：使用 `using` 声明自动释放 ElementHandle\n\n```typescript\n// 推荐写法\nawait page.locator('button[type=\"submit\"]').click();\n\n// 避免硬编码延迟\n// await new Promise(r => setTimeout(r, 2000));\n```\n\n## 相关文档\n\n- [Page 类 API](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [Frame 类 API](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Frame.ts)\n- [JSHandle 类 API](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/JSHandle.ts)\n\n---\n\n<a id='page-network'></a>\n\n## 网络请求拦截与管理\n\n### 相关页面\n\n相关主题：[Page页面操作API](#page-page-api), [浏览器启动与管理](#page-browser-management)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n- [packages/puppeteer-core/src/cdp/ExecutionContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ExecutionContext.ts)\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n- [packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts)\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n- [packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n- [packages/puppeteer-core/src/cdp/utils.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/utils.ts)\n- [packages/puppeteer-core/src/bidi/util.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/util.ts)\n- [examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n</details>\n\n# 网络请求拦截与管理\n\n## 概述\n\nPuppeteer 的网络请求拦截与管理功能允许开发者监控、修改、阻止或重定向网页发出的 HTTP 请求和响应。该功能是浏览器自动化测试和开发调试的核心能力之一，开发者可以借此实现广告屏蔽、请求日志记录、网络条件模拟、API 响应模拟等高级功能。\n\n网络拦截机制基于事件驱动架构，通过 `request`、`response`、`requestfailed`、`requestfinished` 等事件向外暴露网络活动的完整生命周期。Puppeteer 支持两种协议实现：Chrome DevTools Protocol (CDP) 和 WebDriver BiDi，本质上都是通过底层协议拦截和处理网络请求。\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 核心架构\n\n### 组件关系图\n\n```mermaid\ngraph TD\n    A[Page] --> B[NetworkManager]\n    B --> C[HTTPRequest]\n    C --> D[HTTPResponse]\n    E[Request Handler] -.-> C\n    F[setRequestInterception] --> E\n    G[Service Worker] -.-> B\n    \n    style A fill:#e1f5fe\n    style C fill:#fff3e0\n    style D fill:#e8f5e9\n```\n\n### 网络请求生命周期\n\n```mermaid\nstateDiagram-v2\n    [*] --> RequestSent\n    RequestSent --> ResponseReceived: 收到响应头\n    ResponseReceived --> DataReceived: 接收数据\n    DataReceived --> RequestFinished: 传输完成\n    RequestSent --> RequestFailed: 连接失败\n    ResponseReceived --> RequestFailed: 中断错误\n    \n    RequestFinished --> [*]\n    RequestFailed --> [*]\n```\n\n---\n\n## 请求拦截机制\n\n### 启用请求拦截\n\n通过 `setRequestInterception` 方法启用请求拦截功能。启用后，所有通过页面的 HTTP 请求都会触发 `request` 事件，开发者可以在回调中对请求进行处理。\n\n```typescript\nawait page.setRequestInterception(true);\npage.on('request', interceptedRequest => {\n  if (interceptedRequest.url().endsWith('.png') ||\n      interceptedRequest.url().endsWith('.jpg')) {\n    interceptedRequest.abort();\n  } else {\n    interceptedRequest.continue();\n  }\n});\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n### 拦截方法对照表\n\n| 方法 | 描述 | 使用场景 |\n|------|------|----------|\n| `abort()` | 终止请求 | 屏蔽资源、模拟加载失败 |\n| `abort(errorCode)` | 带错误码终止请求 | 测试错误处理逻辑 |\n| `continue()` | 继续原始请求 | 放行请求 |\n| `continue(overrides)` | 修改后继续请求 | 修改请求头或 POST 数据 |\n| `respond(response)` | 直接返回响应 | 模拟 API 响应 |\n\n### 请求拦截参数\n\n`continue()` 方法支持以下参数覆盖：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `postData` | `string \\| Buffer` | POST 请求体数据 |\n| `headers` | `Record<string, string>` | 自定义请求头 |\n| `url` | `string` | 重定向目标 URL |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setRequestInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## HTTPRequest 类\n\n`HTTPRequest` 是 Puppeteer 中表示网络请求的核心类，封装了请求的完整信息及操作方法。\n\n### 主要属性\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `url` | `string` | 请求目标 URL |\n| `method` | `string` | HTTP 方法（GET、POST 等） |\n| `headers` | `Record<string, string>` | 请求头 |\n| `postData` | `string \\| undefined` | POST 请求体 |\n| `resourceType` | `ResourceType` | 资源类型（document、script、image 等） |\n| `frame` | `Frame \\| null` | 请求来源的 Frame |\n| `response` | `HTTPResponse \\| null` | 关联的响应对象 |\n| `isNavigationRequest` | `boolean` | 是否为导航请求 |\n| `redirectChain` | `HTTPRequest[]` | 重定向链 |\n\n### 核心方法\n\n| 方法 | 签名 | 功能 |\n|------|------|------|\n| `abort` | `abort(errorCode?: ErrorCode): Promise<void>` | 终止请求 |\n| `continue` | `continue(overrides?: ContinueOverrides): Promise<void>` | 继续/修改请求 |\n| `respond` | `respond(response: RespondOverrides): Promise<void>` | 直接响应 |\n| `failure` | `failure(): Error \\| null` | 获取请求失败信息 |\n| `enqueueNavigationHook` | `enqueueNavigationHook(hook: NavigationHook): Promise<void>` | 注册导航钩子 |\n\n---\n\n## HTTPResponse 类\n\n`HTTPResponse` 封装了 HTTP 响应的完整信息。\n\n### 主要属性\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `ok` | `boolean` | 响应状态码是否在 200-299 范围内 |\n| `status` | `number` | HTTP 状态码 |\n| `statusText` | `string` | 状态文本 |\n| `url` | `string` | 响应 URL |\n| `request` | `HTTPRequest` | 关联的请求对象 |\n| `fromCache` | `boolean` | 是否来自缓存 |\n| `fromServiceWorker` | `boolean` | 是否来自 Service Worker |\n\n### 响应方法\n\n| 方法 | 签名 | 功能 |\n|------|------|------|\n| `text` | `text(): Promise<string>` | 获取响应体文本 |\n| `json` | `json(): Promise<unknown>` | 解析 JSON 响应体 |\n| `buffer` | `buffer(): Promise<Buffer>` | 获取响应体二进制数据 |\n| `remoteAddress` | `{ip: string, port: number}` | 远程地址信息 |\n\n---\n\n## 网络事件系统\n\n### 事件类型\n\n```typescript\nenum PageEvent {\n  Request = 'request',\n  Response = 'response',\n  RequestFailed = 'requestfailed',\n  RequestFinished = 'requestfinished',\n  BeforeDHARequest = 'beforedhcprequest',\n  DHCCreated = 'dhcpcreated',\n  DHCPChanged = 'dhcpchanged',\n  DHCPDeleted = 'dhcpdeleted',\n}\n```\n\n### 事件监听示例\n\n```typescript\n// 监听所有请求\npage.on('request', request => {\n  console.log(`请求: ${request.method()} ${request.url()}`);\n});\n\n// 监听所有响应\npage.on('response', response => {\n  console.log(`响应: ${response.status()} ${response.url()}`);\n});\n\n// 监听失败请求\npage.on('requestfailed', request => {\n  console.log(`失败: ${request.failure()?.errorText}`);\n});\n\n// 监听完成请求\npage.on('requestfinished', request => {\n  console.log(`完成: ${request.url()}`);\n});\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 网络条件模拟\n\n### 离线模式\n\n`emulateNetworkConditions` 方法允许模拟各种网络条件：\n\n```typescript\nawait page.emulateNetworkConditions({\n  offline: true,           // 是否离线\n  download: 50 * 1024,     // 下载速度 (bytes/s)\n  upload: 20 * 1024,       // 上传速度 (bytes/s)\n  latency: 40              // 延迟 (ms)\n});\n```\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n\n### 预定义网络条件\n\nPuppeteer 提供了一系列预定义的网络条件配置：\n\n| 条件名称 | 延迟 | 下载速度 | 上传速度 | 适用场景 |\n|----------|------|----------|----------|----------|\n| `Regular3G` | 40ms | 750 KB/s | 250 KB/s | 3G 网络 |\n| `Slow3G` | 200ms | 250 KB/s | 50 KB/s | 慢速 3G |\n| `Good3G` | 20ms | 1.5 MB/s | 750 KB/s | 良好 3G |\n| `DSL` | 5ms | 2 MB/s | 1 MB/s | DSL 连接 |\n| `WiFi` | 2ms | 30 MB/s | 15 MB/s | WiFi 连接 |\n\n### 设备模拟\n\n通过 `emulate` 方法可以模拟特定设备的网络和视口配置：\n\n```typescript\nimport {KnownDevices} from 'puppeteer';\n\nconst iPhone = KnownDevices['iPhone 15 Pro'];\nawait page.emulate(iPhone);\n```\n\n资料来源：[packages/puppeteer-core/src/common/Device.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Device.ts)\n\n---\n\n## Service Worker 支持\n\n### Service Worker 绕过\n\n`setBypassServiceWorker` 方法用于控制是否绕过 Service Worker：\n\n```typescript\n// 绕过 Service Worker，直接从网络加载\nawait page.setBypassServiceWorker(true);\n\n// 使用 Service Worker\nawait page.setBypassServiceWorker(false);\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setBypassServiceWorker](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 拖拽拦截（已弃用）\n\n`setDragInterception` 方法用于拦截拖拽事件，但该功能已被弃用：\n\n```typescript\n@deprecated We no longer support intercepting drag payloads. Use the new\ndrag APIs found on {@link ElementHandle} to drag (or just use the\n{@link Page.mouse}).\nabstract setDragInterception(enabled: boolean): Promise<void>;\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:setDragInterception](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts)\n\n---\n\n## 错误处理\n\n### 请求失败处理\n\n当请求失败时，`requestfailed` 事件会携带失败信息：\n\n```typescript\npage.on('requestfailed', request => {\n  const failure = request.failure();\n  console.log(`请求失败: ${failure?.errorText}`);\n});\n```\n\n### 执行上下文销毁处理\n\n当执行上下文被销毁时（如页面导航），Puppeteer 会抛出明确的错误：\n\n```typescript\nif (\n  error.message.includes('ExecutionContext was destroyed') ||\n  error.message.includes('Inspected target navigated or closed')\n) {\n  throw new Error(\n    'Execution context was destroyed, most likely because of a navigation.',\n  );\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/utils.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/utils.ts)\n\n---\n\n## 调试支持\n\n### 调试日志配置\n\nPuppeteer 支持通过 `window.__PUPPETEER_DEBUG` 环境变量开启调试日志：\n\n```typescript\n// 开启所有调试日志\nwindow.__PUPPETEER_DEBUG = '*';\n\n// 只记录 Network 通道\nwindow.__PUPPETEER_DEBUG = 'Network';\n\n// 记录所有以 Net 开头的通道\nwindow.__PUPPETEER_DEBUG = 'Net*';\n```\n\n```typescript\nconst log = debug('Network');\nlog('new request intercepted');\n// 输出: \"Network: new request intercepted\"\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts)\n\n---\n\n## 完整使用示例\n\n### 示例 1：屏蔽图片请求\n\n```typescript\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\nawait page.setRequestInterception(true);\npage.on('request', request => {\n  if (request.resourceType() === 'image') {\n    request.abort();\n  } else {\n    request.continue();\n  }\n});\n\nawait page.goto('https://example.com');\nawait browser.close();\n```\n\n### 示例 2：模拟 API 响应\n\n```typescript\nawait page.setRequestInterception(true);\npage.on('request', async request => {\n  if (request.url().endsWith('/api/data')) {\n    await request.respond({\n      status: 200,\n      contentType: 'application/json',\n      body: JSON.stringify({message: 'Mocked response'}),\n    });\n  } else {\n    request.continue();\n  }\n});\n```\n\n### 示例 3：记录所有网络请求\n\n```typescript\npage.on('request', request => {\n  console.log(`>> ${request.method()} ${request.url()}`);\n});\n\npage.on('response', response => {\n  console.log(`<< ${response.status()} ${response.url()}`);\n});\n\npage.on('requestfailed', request => {\n  console.log(`!! FAILED: ${request.url()} - ${request.failure()?.errorText}`);\n});\n```\n\n资料来源：[examples/README.md](https://github.com/puppeteer/puppeteer/blob/main/examples/README.md)\n\n---\n\n## 配置选项\n\n### 启动配置\n\n| 选项 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `timeout` | `number` | 30000 | 浏览器启动超时（毫秒） |\n| `handleSIGINT` | `boolean` | true | Ctrl+C 时关闭浏览器 |\n| `handleSIGTERM` | `boolean` | true | SIGTERM 时关闭浏览器 |\n| `handleSIGHUP` | `boolean` | true | SIGHUP 时关闭浏览器 |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts)\n\n### 下载配置\n\n| 配置项 | 环境变量 | 说明 |\n|--------|----------|------|\n| `defaultBrowser` | - | 默认浏览器类型 |\n| `temporaryDirectory` | `PUPPETEER_TMP_DIR` | 临时文件目录 |\n| `skipDownload` | `PUPPETEER_SKIP_DOWNLOAD` | 跳过浏览器下载 |\n| `logLevel` | - | 日志级别 (silent/error/warn) |\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts)\n\n---\n\n## 最佳实践\n\n### 1. 及时关闭拦截\n\n```typescript\n// 拦截完成后及时关闭\nawait page.setRequestInterception(false);\npage.off('request', handler);\n```\n\n### 2. 避免在拦截回调中执行耗时操作\n\n拦截回调会阻塞请求，耗时操作应使用异步方式：\n\n```typescript\npage.on('request', async request => {\n  // 使用 async 处理\n  if (needMock) {\n    await request.respond({...});\n  } else {\n    request.continue();\n  }\n});\n```\n\n### 3. 处理导航场景\n\n导航请求可能触发上下文销毁，应在拦截逻辑中处理：\n\n```typescript\npage.on('request', request => {\n  try {\n    if (request.isNavigationRequest()) {\n      // 处理导航请求\n      request.continue({headers: {...}});\n    }\n  } catch (e) {\n    // 上下文可能已销毁\n  }\n});\n```\n\n---\n\n## 相关资源\n\n- [官方文档：网络拦截](https://pptr.dev/guides/network-interception)\n- [官方文档：网络日志](https://pptr.dev/guides/network-logging)\n- [示例代码库](../examples)\n\n---\n\n<a id='page-contexts-extensions'></a>\n\n## 浏览器上下文与扩展支持\n\n### 相关页面\n\n相关主题：[浏览器启动与管理](#page-browser-management), [覆盖率检测与调试功能](#page-coverage-debugging)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/node/LaunchOptions.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/node/LaunchOptions.ts) - 启动选项定义，包含扩展支持配置\n- [packages/puppeteer-core/src/api/Page.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/api/Page.ts) - Page 类抽象定义，exposeFunction 等方法\n- [packages/puppeteer-core/src/common/Configuration.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Configuration.ts) - 全局配置接口\n- [packages/puppeteer-core/src/common/Debug.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Debug.ts) - 调试日志系统\n- [packages/puppeteer-core/src/cdp/ExecutionContext.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/ExecutionContext.ts) - CDP 执行上下文实现\n- [packages/puppeteer-core/src/bidi/util.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/bidi/util.ts) - BiDi 协议工具函数\n- [README.md](https://github.com/puppeteer/puppeteer/blob/main/README.md) - 主项目文档\n</details>\n\n# 浏览器上下文与扩展支持\n\n## 概述\n\nPuppeteer 的浏览器上下文（Browser Context）与扩展支持功能为开发者提供了在同一浏览器实例中创建隔离环境的能力，并支持加载 Chrome 扩展程序。这些功能使得高级自动化场景（如多租户隔离、扩展辅助测试、隐私浏览模式等）成为可能。\n\n### 核心概念\n\n- **浏览器上下文（Browser Context）**：一个独立的浏览器会话环境，拥有独立的 Cookie 存储、缓存和本地存储。不同上下文之间的数据完全隔离。\n- **扩展支持（Extension Support）**：Puppeteer 允许将未打包的扩展程序加载到浏览器实例中，以辅助自动化测试或实现自定义功能。\n\n## 浏览器上下文架构\n\n### 抽象层设计\n\nPuppeteer 在 `packages/puppeteer-core/src/api/` 目录下定义了 BrowserContext 的抽象接口。具体实现分别针对 CDP（Chrome DevTools Protocol）和 BiDi（WebDriver BiDi）协议提供了独立的实现类。\n\n### CDP 实现\n\n在 CDP（Chrome DevTools Protocol）实现中，浏览器上下文通过创建独立的浏览器会话来实现隔离。CDP 协议原生支持上下文隔离，每个上下文拥有独立的 Target（目标），包括页面、服务工作者等。\n\n### BiDi 实现\n\n在 BiDi（WebDriver BiDi）协议实现中，浏览器上下文作为独立的会话存在。BiDi 协议的上下文管理机制与 CDP 类似，但提供了标准化的跨浏览器支持。\n\n## 扩展加载机制\n\n### 启动配置\n\nPuppeteer 通过 `LaunchOptions` 接口提供扩展支持配置。扩展可以在浏览器启动时加载：\n\n```typescript\ninterface LaunchOptions {\n  /**\n   * 如果为 true，则避免传递会阻止扩展启用的默认参数。\n   * 传递字符串数组将加载提供的路径作为未打包的扩展程序。\n   */\n  enableExtensions?: boolean | string[];\n}\n```\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:1-50]()\n\n### 配置选项说明\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enableExtensions` | `boolean \\| string[]` | `undefined` | 启用扩展支持。布尔值启用所有默认扩展行为；字符串数组指定要加载的扩展路径 |\n| `handleSIGINT` | `boolean` | `true` | 在 Ctrl+C 时关闭浏览器进程 |\n| `handleSIGTERM` | `boolean` | `true` | 在 SIGTERM 时关闭浏览器进程 |\n| `handleSIGHUP` | `boolean` | `true` | 在 SIGHUP 时关闭浏览器进程 |\n\n## 扩展上下文通信\n\n### exposeFunction 方法\n\n`exposeFunction` 是 Page 类提供的核心方法，允许从浏览器页面调用 Node.js 环境中的函数。这对于扩展辅助测试和双向通信至关重要：\n\n```typescript\nabstract exposeFunction(\n  name: string,\n  pptrFunction: Function | {default: Function},\n): Promise<void>;\n```\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:1-100]()\n\n### 使用模式\n\n#### 基本用法\n\n```typescript\nimport puppeteer from 'puppeteer';\nimport fs from 'node:fs';\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\npage.on('console', msg => console.log(msg.text()));\n\nawait page.exposeFunction('readfile', async filePath => {\n  return new Promise((resolve, reject) => {\n    fs.readFile(filePath, 'utf8', (err, text) => {\n      if (err) reject(err);\n      else resolve(text);\n    });\n  });\n});\n\nawait page.evaluate(async () => {\n  const content = await window.readfile('/etc/hosts');\n  console.log(content);\n});\n\nawait browser.close();\n```\n\n#### 与扩展配合使用\n\n通过 `exposeFunction`，开发者可以创建桥接函数，使扩展程序能够与 Node.js 环境交互：\n\n```typescript\nawait page.exposeFunction('md5', async (myString: string) => {\n  const hash = await window.md5(myString);\n  console.log(`md5 of ${myString} is ${hash}`);\n});\n```\n\n### 内部实现机制\n\n在 CDP 实现中，`exposeFunction` 通过以下步骤工作：\n\n1. 在页面的执行上下文中注册一个全局函数\n2. 监听页面中对该函数的调用\n3. 将调用参数从浏览器环境传递到 Node.js 环境\n4. 执行提供的 Node.js 回调函数\n5. 将结果返回到浏览器环境\n\n资料来源：[packages/puppeteer-core/src/cdp/ExecutionContext.ts:1-80]()\n\n## evaluateOnNewDocument 功能\n\n`evaluateOnNewDocument` 方法允许在每个新文档创建后、任何脚本运行前注入代码。这对于在页面加载前修改 JavaScript 环境非常有用：\n\n```typescript\nabstract evaluateOnNewDocument<\n  Params extends unknown[],\n  Func extends (...args: Params) => unknown = (...args: Params) => unknown,\n>(\n  pageFunction: Func | string,\n  ...args: Params\n): Promise<NewDocumentScriptEvaluation>;\n```\n\n### 应用场景\n\n#### 覆盖 navigator.languages\n\n```typescript\n// preload.js\nObject.defineProperty(navigator, 'languages', {\n  get: function () {\n    return ['en-US', 'en', 'bn'];\n  },\n});\n\n// 在 Puppeteer 脚本中使用\nconst preloadFile = fs.readFileSync('./preload.js', 'utf8');\nawait page.evaluateOnNewDocument(preloadFile);\n```\n\n## 配置系统\n\n### 全局配置接口\n\nPuppeteer 提供了 `Configuration` 接口用于全局配置：\n\n```typescript\nexport interface Configuration {\n  defaultBrowser?: SupportedBrowser;\n  temporaryDirectory?: string;\n  skipDownload?: boolean;\n  logLevel?: 'silent' | 'error' | 'warn';\n  experiments?: ExperimentsConfiguration;\n  chrome?: ChromeSettings;\n  ['chrome-headless-shell']?: ChromeHeadlessShellSettings;\n  firefox?: FirefoxSettings;\n}\n```\n\n资料来源：[packages/puppeteer-core/src/common/Configuration.ts:1-80]()\n\n### 环境变量覆盖\n\n| 环境变量 | 对应配置项 | 说明 |\n|----------|-----------|------|\n| `PUPPETEER_TMP_DIR` | `temporaryDirectory` | 临时文件目录 |\n| `PUPPETEER_SKIP_DOWNLOAD` | `skipDownload` | 跳过浏览器下载 |\n| `PUPPETEER_LOG_LEVEL` | `logLevel` | 日志级别 |\n| `PUPPETEER_CHROME_SKIP_DOWNLOAD` | `chrome.skipDownload` | 跳过 Chrome 下载 |\n| `PUPPETEER_CHROME_DOWNLOAD_BASE_URL` | `chrome.downloadBaseUrl` | Chrome 下载基础 URL |\n\n## 调试支持\n\nPuppeteer 提供了可配置的调试日志系统：\n\n```typescript\nexport const debug = (prefix: string): ((...args: unknown[]) => void) => {\n  if (isNode) {\n    return async (...logArgs: unknown[]) => {\n      if (captureLogs) {\n        capturedLogs.push(prefix + logArgs);\n      }\n      (await importDebug())(prefix)(logArgs);\n    };\n  }\n  // 浏览器环境实现...\n};\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:1-60]()\n\n### 调试通道\n\n| 通道前缀 | 说明 |\n|---------|------|\n| `Page` | 页面相关日志 |\n| `BrowserContext` | 浏览器上下文日志 |\n| `Extension` | 扩展相关日志 |\n| `Target` | 目标管理日志 |\n\n### 使用方法\n\n```javascript\n// 设置日志级别\nwindow.__PUPPETEER_DEBUG='Page';        // 仅记录 Page 通道\nwindow.__PUPPETEER_DEBUG='Page*';        // 记录所有 Page 开头的通道\nwindow.__PUPPETEER_DEBUG='*';           // 记录所有通道\n```\n\n## 错误处理\n\n### 执行上下文错误\n\nPuppeteer 提供了专门的错误重写函数用于处理常见错误场景：\n\n```typescript\nexport function rewriteEvaluationError(error: unknown): never {\n  if (error instanceof Error) {\n    if (\n      error.message.includes('ExecutionContext was destroyed') ||\n      error.message.includes('Inspected target navigated or closed')\n    ) {\n      throw new Error(\n        'Execution context was destroyed, most likely because of a navigation.',\n      );\n    }\n  }\n  throw error;\n}\n```\n\n资料来源：[packages/puppeteer-core/src/bidi/util.ts:1-80]()\n\n### 导航超时处理\n\n```typescript\nexport function rewriteNavigationError(\n  message: string,\n  ms: number,\n): (error: unknown) => never {\n  return error => {\n    if (error instanceof ProtocolError) {\n      error.message += ` at ${message}`;\n    } else if (error instanceof TimeoutError) {\n      error.message = `Navigation timeout of ${ms} ms exceeded`;\n    }\n    throw error;\n  };\n}\n```\n\n## 完整使用示例\n\n```typescript\nimport puppeteer from 'puppeteer';\n\nasync function main() {\n  // 启用扩展支持\n  const browser = await puppeteer.launch({\n    enableExtensions: ['/path/to/unpacked/extension'],\n    handleSIGINT: true,\n    handleSIGTERM: true,\n    timeout: 30000,\n  });\n\n  // 创建隔离上下文\n  const context = browser.createBrowserContext();\n  const page = await context.newPage();\n\n  // 设置调试日志\n  page.on('console', msg => console.log('PAGE LOG:', msg.text()));\n\n  // 暴露 Node.js 函数到页面\n  await page.exposeFunction('getNodeVersion', () => process.version);\n  await page.exposeFunction('readConfig', async () => {\n    return {apiKey: 'xxx', endpoint: 'https://api.example.com'};\n  });\n\n  // 在文档创建前注入代码\n  await page.evaluateOnNewDocument(() => {\n    console.log('Document about to be created');\n  });\n\n  await page.goto('https://example.com');\n  await browser.close();\n}\n\nmain().catch(console.error);\n```\n\n## 最佳实践\n\n1. **资源清理**：使用完毕后调用 `browser.close()` 或 `context.close()` 释放资源\n2. **超时配置**：根据网络状况和目标网站性能合理设置超时时间\n3. **扩展路径**：使用绝对路径确保扩展能够正确加载\n4. **错误处理**：实现健壮的错误处理逻辑，特别是导航超时和执行上下文销毁场景\n5. **调试日志**：在开发阶段启用调试日志便于排查问题\n\n## 相关资源\n\n- [Puppeteer 官方文档](https://pptr.dev/)\n- [Chrome Extensions 文档](https://developer.chrome.com/docs/extensions/mv3/)\n- [Chrome DevTools Protocol 文档](https://chromedevtools.github.io/devtools-protocol/)\n- [WebDriver BiDi 规范](https://w3c.github.io/webdriver-bidi/)\n\n---\n\n<a id='page-coverage-debugging'></a>\n\n## 覆盖率检测与调试功能\n\n### 相关页面\n\n相关主题：[Page页面操作API](#page-page-api), [浏览器上下文与扩展支持](#page-contexts-extensions)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [packages/puppeteer-core/src/cdp/Coverage.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Coverage.ts)\n- [packages/puppeteer-core/src/cdp/Accessibility.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Accessibility.ts)\n- [packages/puppeteer-core/src/cdp/Tracing.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/cdp/Tracing.ts)\n- [packages/puppeteer-core/src/common/ConsoleMessage.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/ConsoleMessage.ts)\n- [packages/puppeteer-core/src/common/Errors.ts](https://github.com/puppeteer/puppeteer/blob/main/packages/puppeteer-core/src/common/Errors.ts)\n- [docs/guides/debugging.md](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/debugging.md)\n</details>\n\n# 覆盖率检测与调试功能\n\n## 概述\n\nPuppeteer 提供了丰富的覆盖率检测与调试功能，使开发者能够在浏览器自动化过程中收集性能指标、追踪代码执行、分析控制台输出以及诊断运行时错误。这些功能对于优化网页性能、调试自动化脚本以及生成详细的测试报告至关重要。\n\n覆盖率检测功能主要通过 Chrome DevTools Protocol (CDP) 实现，支持 JavaScript 代码覆盖率统计、堆快照捕获以及性能指标采集。调试功能则涵盖控制台消息捕获、页面事件监听、调试日志输出以及详细的错误报告机制。\n\n## 核心架构\n\n### 模块关系\n\nPuppeteer 的覆盖率检测与调试系统由多个核心模块组成，各模块协同工作以提供完整的诊断能力。\n\n```mermaid\ngraph TD\n    A[Puppeteer 核心层] --> B[覆盖率模块]\n    A --> C[调试模块]\n    A --> D[追踪模块]\n    B --> E[CDP Coverage API]\n    C --> F[ConsoleMessage 处理]\n    C --> G[Errors 处理]\n    D --> H[CDP Tracing API]\n    E --> I[CoverageResult]\n    F --> J[控制台事件]\n    G --> K[错误类型定义]\n    H --> L[追踪数据]\n```\n\n### 关键组件\n\n| 组件名称 | 文件路径 | 职责说明 |\n|---------|---------|----------|\n| Coverage | `packages/puppeteer-core/src/cdp/Coverage.ts` | 提供 JavaScript 和 CSS 覆盖率统计功能 |\n| Tracing | `packages/puppeteer-core/src/cdp/Tracing.ts` | 管理性能追踪和事件流记录 |\n| ConsoleMessage | `packages/puppeteer-core/src/common/ConsoleMessage.ts` | 处理和解析控制台消息 |\n| Errors | `packages/puppeteer-core/src/common/Errors.ts` | 定义错误类型和错误处理机制 |\n| Accessibility | `packages/puppeteer-core/src/cdp/Accessibility.ts` | 提供无障碍访问相关诊断 |\n\n## 覆盖率检测功能\n\n### JavaScript 代码覆盖率\n\nPuppeteer 支持获取页面的性能指标数据，这些数据包括文档数量、帧数、JavaScript 事件监听器数量、DOM 节点数量以及布局和样式重算的统计信息。\n\n性能指标数据结构定义如下：\n\n| 属性名 | 类型 | 说明 |\n|-------|------|------|\n| Timestamp | number | 指标采样的时间戳（单调递增） |\n| Documents | number | 页面中的文档数量 |\n| Frames | number | 页面中的帧数量 |\n| JSEventListeners | number | 页面中的 JavaScript 事件监听器数量 |\n| Nodes | number | DOM 节点总数 |\n| LayoutCount | number | 完整或部分页面布局的总次数 |\n| RecalcStyleCount | number | 页面样式重算的总次数 |\n| LayoutDuration | number | 所有页面布局的累计时长 |\n| RecalcStyleDuration | number | 所有样式重算的累计时长 |\n| ScriptDuration | number | JavaScript 执行的总时长 |\n| TaskDuration | number | 浏览器执行的所有任务累计时长 |\n| JSHeapUsedSize | number | 已使用的 JavaScript 堆大小 |\n| JSHeapTotalSize | number | JavaScript 堆总大小 |\n\n资料来源：[packages/puppeteer-core/src/api/Page.ts:250-290]()\n\n### 堆快照捕获\n\nPuppeteer 提供了 `captureHeapSnapshot()` 方法用于捕获 JavaScript 堆的快照并写入文件。这对于内存泄漏排查和堆内存分析非常有价值。该方法为抽象方法，需要在具体的 Page 实现中由 CDP 或其他浏览器协议实现。\n\n```typescript\n// 捕获堆快照的典型用法\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\n// 执行页面操作后捕获堆快照\nawait page.captureHeapSnapshot({ path: 'heap-snapshot.json' });\n\nawait browser.close();\n```\n\n### CSS 覆盖率\n\n通过 CDP 的 Coverage API，Puppeteer 能够追踪 CSS 规则的使用情况，帮助开发者识别页面中未使用的 CSS 样式。\n\n## 调试功能\n\n### 调试日志系统\n\nPuppeteer 实现了灵活的调试日志系统，支持通过环境变量 `window.__PUPPETEER_DEBUG` 配置日志输出级别和通道。\n\n```javascript\n// 输出所有调试日志\nwindow.__PUPPETEER_DEBUG = '*';\n\n// 输出特定通道的日志\nwindow.__PUPPETEER_DEBUG = 'Page';\n\n// 输出以指定前缀开头的所有通道\nwindow.__PUPPETEER_DEBUG = 'Page*';\n```\n\n调试日志函数接受一个前缀参数，该前缀会被添加到每条日志消息的开头，便于区分不同模块的输出：\n\n```typescript\nconst log = debug('Page');\nlog('new page created');\n// 输出: \"Page: new page created\"\n```\n\n资料来源：[packages/puppeteer-core/src/common/Debug.ts:30-60]()\n\n### 日志输出流程\n\n```mermaid\ngraph LR\n    A[日志调用] --> B{运行环境检测}\n    B -->|Node.js| C[debug 模块]\n    B -->|浏览器| D[环境变量检查]\n    D --> E{匹配检查}\n    E -->|完全匹配| F[console.log 输出]\n    E -->|通配符匹配| F\n    E -->|不匹配| G[无输出]\n    C --> H[异步日志输出]\n```\n\n### 控制台消息处理\n\nConsoleMessage 模块负责解析和传递来自页面的控制台消息。该模块支持多种消息类型，包括日志、警告、错误、信息和调试消息。\n\n| 消息类型 | 说明 | 典型用途 |\n|---------|------|---------|\n| log | 日志消息 | 一般性信息输出 |\n| warn | 警告消息 | 潜在问题的提示 |\n| error | 错误消息 | 运行时错误的报告 |\n| info | 信息消息 | 提示性信息 |\n| debug | 调试消息 | 开发调试信息 |\n\n监听控制台消息的标准模式：\n\n```typescript\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\n\npage.on('console', msg => {\n  console.log(`[${msg.type()}] ${msg.text()}`);\n});\n\nawait page.goto('https://example.com');\n\nawait browser.close();\n```\n\n资料来源：[packages/puppeteer-core/src/common/ConsoleMessage.ts]()\n\n### 错误处理机制\n\nPuppeteer 定义了完整的错误类型体系，确保各种运行时异常能够被正确识别和处理。\n\n| 错误类型 | 错误码 | 说明 |\n|---------|-------|------|\n| UnsupportedOperationError | 错误码定义在 Errors.ts | 不支持的操作错误 |\n| EvaluationError | 错误码定义在 Errors.ts | JavaScript 评估错误 |\n| TimeoutError | 错误码定义在 Errors.ts | 操作超时错误 |\n| ProtocolError | 错误码定义在 Errors.ts | CDP 协议通信错误 |\n\n评估上下文中发生的异常会被捕获并转换为结构化的错误对象：\n\n```typescript\nconst {exceptionDetails, result: remoteObject} = await this.#client\n  .send('Runtime.evaluate', {\n    expression: expressionWithSourceUrl,\n    contextId,\n    returnByValue,\n    awaitPromise: true,\n    userGesture: true,\n  })\n  .catch(rewriteError);\n\nif (exceptionDetails) {\n  throw createEvaluationError(exceptionDetails);\n}\n```\n\n资料来源：[packages/puppeteer-core/src/cdp/ExecutionContext.ts:40-70]()\n\n## 性能追踪功能\n\n### Tracing 模块概述\n\nTracing 模块提供了强大的性能追踪能力，能够记录页面的各种事件流并生成详细的追踪报告。这对于分析页面加载性能、识别性能瓶颈以及生成 Chrome DevTools 兼容的追踪文件非常有用。\n\n### 追踪数据流\n\n```mermaid\ngraph TD\n    A[追踪开始] --> B[CDP Tracing.start]\n    B --> C[事件收集阶段]\n    C --> D[Page 事件]\n    C --> E[Network 事件]\n    C --> F[JavaScript 事件]\n    D --> G[缓冲区写入]\n    E --> G\n    F --> G\n    G --> H[CDP Tracing.end]\n    H --> I[追踪数据处理]\n    I --> J[结果输出]\n```\n\n## 无障碍功能诊断\n\nAccessibility 模块提供了页面无障碍访问相关的诊断能力，帮助开发者检查页面元素的可访问性属性。\n\n### ARIA 选择器支持\n\nPuppeteer 支持通过 ARIA 选择器查询页面元素，这依赖于 Accessibility 组件提供的基础能力：\n\n```typescript\n// 使用 ARIA 选择器定位元素\nawait page.locator('::-p-aria(Search)').fill('automate beyond recorder');\n```\n\n## 配置选项\n\n### 覆盖率相关配置\n\n| 配置项 | 类型 | 默认值 | 说明 |\n|-------|------|-------|------|\n| defaultBrowser | SupportedBrowser | 'chrome' | 默认浏览器类型 |\n| temporaryDirectory | string | os.tmpdir() | 临时文件目录 |\n| skipDownload | boolean | false | 是否跳过浏览器下载 |\n| logLevel | 'silent' \\| 'error' \\| 'warn' | 'warn' | 日志级别 |\n\n### 浏览器启动调试选项\n\n| 选项名称 | 类型 | 说明 |\n|---------|------|------|\n| executablePath | string | 浏览器可执行文件路径 |\n| ignoreDefaultArgs | boolean \\| string[] | 是否忽略默认参数 |\n| enableExtensions | boolean \\| string[] | 启用扩展支持 |\n| handleSIGINT | boolean | 是否处理 Ctrl+C 信号 |\n| handleSIGTERM | boolean | 是否处理 SIGTERM 信号 |\n| handleSIGHUP | boolean | 是否处理 SIGHUP 信号 |\n| timeout | number | 浏览器启动超时时间（毫秒） |\n\n资料来源：[packages/puppeteer-core/src/node/LaunchOptions.ts:40-80]()\n\n## 最佳实践\n\n### 调试模式启用\n\n在开发环境中启用完整调试日志：\n\n```bash\nPUPPETEER_DEBUG='*' node your-script.js\n```\n\n### 性能分析工作流\n\n1. **启动追踪**：使用 Tracing API 开始记录性能数据\n2. **执行操作**：在页面上执行待分析的操作\n3. **结束追踪**：停止数据收集并获取结果\n4. **分析结果**：使用 Chrome DevTools 或其他工具分析追踪数据\n\n### 覆盖率采集建议\n\n- 在关键测试场景中启用覆盖率统计\n- 定期检查未使用的 CSS 和 JavaScript 代码\n- 结合性能指标识别优化机会\n\n## 相关资源\n\n- [Puppeteer 官方文档](https://pptr.dev)\n- [Chrome DevTools Protocol 文档](https://chromedevtools.github.io/devtools-protocol/)\n- [调试功能指南](../guides/debugging.md)\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：puppeteer/puppeteer\n\n摘要：发现 21 个潜在踩坑项，其中 4 个为 high/blocking；最高优先级：安装坑 - 来源证据：Chrome Canary/Firefox Nightly test results。\n\n## 1. 安装坑 · 来源证据：Chrome Canary/Firefox Nightly test results\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Chrome Canary/Firefox Nightly test results\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1aabe120a9df47a2adbd293381b50a64 | https://github.com/puppeteer/puppeteer/issues/12379 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 2. 安装坑 · 来源证据：Puppeteer v25\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Puppeteer v25\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_050f65ceff2a455da4a3538895a7538b | https://github.com/puppeteer/puppeteer/issues/14342 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 3. 安全/权限坑 · 来源证据：[Bug]: GHSA issued a false malicious package alert for puppeteer\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: GHSA issued a false malicious package alert for puppeteer\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_55588dfbd41442fdb8a2f4f1be57e4c9 | https://github.com/puppeteer/puppeteer/issues/14986 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 4. 安全/权限坑 · 来源证据：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_9b1ef7c38ed14c41b3e4ce786adcdf26 | https://github.com/puppeteer/puppeteer/issues/14774 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。\n\n## 5. 安装坑 · 来源证据：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_5d1f448d8768460a806ab32e8d4f6997 | https://github.com/puppeteer/puppeteer/issues/14957 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 6. 安装坑 · 来源证据：[Bug]: `setViewport` crashes on Firefox if uncaught\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: `setViewport` crashes on Firefox if uncaught\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_75bddb8a74194cf7a8978853f19db23a | https://github.com/puppeteer/puppeteer/issues/14989 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 7. 安装坑 · 来源证据：[Bug]: chrome binary is not present when installing latest chrome\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: chrome binary is not present when installing latest chrome\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1e85cdab2b684dda8e5c83f55b8ff7b6 | https://github.com/puppeteer/puppeteer/issues/14988 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 8. 安装坑 · 来源证据：[Feature]: Make proxy-agent dependency optional\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Feature]: Make proxy-agent dependency optional\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_195c51e4a5e84edda14a2a79b456821c | https://github.com/puppeteer/puppeteer/issues/13775 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 9. 安装坑 · 来源证据：browsers: v3.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：browsers: v3.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_bf2d83568c54447fbfd3047d24be0c48 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 10. 能力坑 · 来源证据：browsers: v3.0.2\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：browsers: v3.0.2\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_c9f08632e7ee4e9485d27b864a21e462 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 11. 能力坑 · 来源证据：puppeteer-core: v25.0.2\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：puppeteer-core: v25.0.2\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3a8b10a5263e4d6488e16972c8249a38 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 12. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:90796663 | https://github.com/puppeteer/puppeteer | README/documentation is current enough for a first validation pass.\n\n## 13. 维护坑 · 来源证据：ng-schematics: v0.8.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：ng-schematics: v0.8.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_4e7ee6a70b1d4fb6879ab4670099d205 | https://github.com/puppeteer/puppeteer/releases/tag/ng-schematics-v0.8.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 14. 维护坑 · 来源证据：puppeteer-core: v25.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer-core: v25.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3e6a5770b15146ddab5249f1aa687cae | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 15. 维护坑 · 来源证据：puppeteer: v25.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer: v25.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_9294fdbab95d446887bdb54a11df66d2 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 16. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | last_activity_observed missing\n\n## 17. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium\n\n## 18. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium\n\n## 19. 安全/权限坑 · 来源证据：[Feature]: Reducing dependencies\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Feature]: Reducing dependencies\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_cb21a546ebb04ca39b334255b205c9da | https://github.com/puppeteer/puppeteer/issues/13552 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 20. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | issue_or_pr_quality=unknown\n\n## 21. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | release_recency=unknown\n\n<!-- canonical_name: puppeteer/puppeteer; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：puppeteer/puppeteer\n\n摘要：发现 21 个潜在踩坑项，其中 4 个为 high/blocking；最高优先级：安装坑 - 来源证据：Chrome Canary/Firefox Nightly test results。\n\n## 1. 安装坑 · 来源证据：Chrome Canary/Firefox Nightly test results\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Chrome Canary/Firefox Nightly test results\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1aabe120a9df47a2adbd293381b50a64 | https://github.com/puppeteer/puppeteer/issues/12379 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 2. 安装坑 · 来源证据：Puppeteer v25\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Puppeteer v25\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_050f65ceff2a455da4a3538895a7538b | https://github.com/puppeteer/puppeteer/issues/14342 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 3. 安全/权限坑 · 来源证据：[Bug]: GHSA issued a false malicious package alert for puppeteer\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: GHSA issued a false malicious package alert for puppeteer\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_55588dfbd41442fdb8a2f4f1be57e4c9 | https://github.com/puppeteer/puppeteer/issues/14986 | 来源讨论提到 npm 相关条件，需在安装/试用前复核。\n\n## 4. 安全/权限坑 · 来源证据：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n\n- 严重度：high\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Task]: Flaky `[fixtures.spec] Fixtures should dump browser process stderr`\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_9b1ef7c38ed14c41b3e4ce786adcdf26 | https://github.com/puppeteer/puppeteer/issues/14774 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。\n\n## 5. 安装坑 · 来源证据：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: @puppeteer/browsers silently corrupts Chrome cache on Node.js 26 (extract-zip 2.0.1)\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_5d1f448d8768460a806ab32e8d4f6997 | https://github.com/puppeteer/puppeteer/issues/14957 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 6. 安装坑 · 来源证据：[Bug]: `setViewport` crashes on Firefox if uncaught\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: `setViewport` crashes on Firefox if uncaught\n- 对用户的影响：可能阻塞安装或首次运行。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_75bddb8a74194cf7a8978853f19db23a | https://github.com/puppeteer/puppeteer/issues/14989 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 7. 安装坑 · 来源证据：[Bug]: chrome binary is not present when installing latest chrome\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: chrome binary is not present when installing latest chrome\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_1e85cdab2b684dda8e5c83f55b8ff7b6 | https://github.com/puppeteer/puppeteer/issues/14988 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 8. 安装坑 · 来源证据：[Feature]: Make proxy-agent dependency optional\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Feature]: Make proxy-agent dependency optional\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_195c51e4a5e84edda14a2a79b456821c | https://github.com/puppeteer/puppeteer/issues/13775 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 9. 安装坑 · 来源证据：browsers: v3.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：browsers: v3.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_bf2d83568c54447fbfd3047d24be0c48 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 10. 能力坑 · 来源证据：browsers: v3.0.2\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：browsers: v3.0.2\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_c9f08632e7ee4e9485d27b864a21e462 | https://github.com/puppeteer/puppeteer/releases/tag/browsers-v3.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 11. 能力坑 · 来源证据：puppeteer-core: v25.0.2\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：puppeteer-core: v25.0.2\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3a8b10a5263e4d6488e16972c8249a38 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.2 | 来源类型 github_release 暴露的待验证使用条件。\n\n## 12. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:90796663 | https://github.com/puppeteer/puppeteer | README/documentation is current enough for a first validation pass.\n\n## 13. 维护坑 · 来源证据：ng-schematics: v0.8.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：ng-schematics: v0.8.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_4e7ee6a70b1d4fb6879ab4670099d205 | https://github.com/puppeteer/puppeteer/releases/tag/ng-schematics-v0.8.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 14. 维护坑 · 来源证据：puppeteer-core: v25.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer-core: v25.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_3e6a5770b15146ddab5249f1aa687cae | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 15. 维护坑 · 来源证据：puppeteer: v25.0.0\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：puppeteer: v25.0.0\n- 对用户的影响：可能影响升级、迁移或版本选择。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_9294fdbab95d446887bdb54a11df66d2 | https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-v25.0.0 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 16. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | last_activity_observed missing\n\n## 17. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium\n\n## 18. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:90796663 | https://github.com/puppeteer/puppeteer | no_demo; severity=medium\n\n## 19. 安全/权限坑 · 来源证据：[Feature]: Reducing dependencies\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Feature]: Reducing dependencies\n- 对用户的影响：可能增加新用户试用和生产接入成本。\n- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_cb21a546ebb04ca39b334255b205c9da | https://github.com/puppeteer/puppeteer/issues/13552 | 来源讨论提到 node 相关条件，需在安装/试用前复核。\n\n## 20. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | issue_or_pr_quality=unknown\n\n## 21. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:90796663 | https://github.com/puppeteer/puppeteer | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# puppeteer - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 puppeteer 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: JavaScript API for Chrome and Firefox 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-overview：Puppeteer项目概览。围绕“Puppeteer项目概览”模拟一次用户任务，不展示安装或运行结果。\n2. page-installation：安装与入门指南。围绕“安装与入门指南”模拟一次用户任务，不展示安装或运行结果。\n3. page-architecture：Puppeteer系统架构。围绕“Puppeteer系统架构”模拟一次用户任务，不展示安装或运行结果。\n4. page-protocols：协议实现：CDP与WebDriver BiDi。围绕“协议实现：CDP与WebDriver BiDi”模拟一次用户任务，不展示安装或运行结果。\n5. page-browser-management：浏览器启动与管理。围绕“浏览器启动与管理”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-overview\n输入：用户提供的“Puppeteer项目概览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-installation\n输入：用户提供的“安装与入门指南”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-architecture\n输入：用户提供的“Puppeteer系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-protocols\n输入：用户提供的“协议实现：CDP与WebDriver BiDi”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-browser-management\n输入：用户提供的“浏览器启动与管理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-overview：Step 1 必须围绕“Puppeteer项目概览”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-installation：Step 2 必须围绕“安装与入门指南”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-architecture：Step 3 必须围绕“Puppeteer系统架构”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-protocols：Step 4 必须围绕“协议实现：CDP与WebDriver BiDi”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-browser-management：Step 5 必须围绕“浏览器启动与管理”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/puppeteer/puppeteer\n- https://github.com/puppeteer/puppeteer#readme\n- README.md\n- package.json\n- packages/puppeteer-core/package.json\n- docs/guides/what-is-puppeteer.md\n- packages/puppeteer-core/src/puppeteer-core.ts\n- packages/puppeteer/install.mjs\n- packages/puppeteer/src/install.ts\n- docs/guides/installation.md\n- docs/guides/getting-started.md\n- examples/README.md\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 puppeteer 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：puppeteer/puppeteer\n\n## 官方安装入口\n\n### Node.js / npm · 官方安装入口\n\n```bash\nnpm i puppeteer\n```\n\n来源：https://github.com/puppeteer/puppeteer#readme\n\n## 来源\n\n- repo: https://github.com/puppeteer/puppeteer\n- docs: https://github.com/puppeteer/puppeteer#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_25fd9b42e7524484a309f55c8d5afd29"
}
