
人工智能AI Agent浏览器控制GUI 自动化MCP 服务【免费下载链接】invisible_playwright_mcpPlaywright MCP server undetected by anti-bots and captchas: AI agent browses the web on anti-detect stealth Firefox, Python, undetected browser automation, scraping, computer use.项目地址https://gitcode.com/GitHub_Trending/jo/invisible_playwright_mcp点击查看免费下载一个浏览器 MCP server 向模型呈现页面的方式不止一种而这几种方式并不能互相替代在 invisible playwright MCP 中同一个页面既可以作为纯文本、作为清洗后的 HTML、作为可交互元素清单snapshot返回也可以作为一张截图进入上下文。它们的字节成本相差近九十倍而且这个比例会随页面类型翻转。本文以 2026-09-17 在本地对实际页面所做的逐工具实测为主线结合仓库源码读取工具实现、工具注册、HTML 清洗管线说明四种读法的成本结构、截断行为与适用场景读完你可以在自己的任务里按一条规则选对读取方式避免十次截图烧掉整个上下文窗口这类典型失败。同一个小页面四种读法的账单先把四种工具在同一个小页面上依次调用记录返回负载的字节数。该页面由 3,665 字节的 HTML 服务而来一个标题、一个段落、二十项导航列表、一个含五个控件的表单和一张四十行的表格没有图片每个工具跑三次取中位数页面如何返回字节数相对倍数browser_read_text1,0211xbrowser_read_html1,3421.3xbrowser_snapshot2,1862.1xbrowser_take_screenshot90,76889x表格里每一行都是同一个页面。最后一行是第一行的八十九倍原因在于一张文字的图片并不是文字。截图以 base64 形式此处 90,768 字节进入模型上下文并且在它到达的那一轮和之后每一轮都会持续占位——除非你的客户端主动裁剪它。对照源码可以确认这四种负载的生成方式actions.pyread_text通过document.querySelector(sel)取元素的innerText返回的是去掉了标记的可见文字actions.py#L122-L144read_html先在浏览器里对页面克隆求值再交给 Python 侧的清洗函数返回精简后的标记actions.py#L396-L414snapshot在浏览器里执行只读脚本枚举实际可见的交互元素序列化为 JSONactions.py#L378-L393screenshot_png直接调用session.page().screenshot()返回 PNG 原始字节再由工具层包装成 MCP Imageactions.py#L417-L423、server.py#L529-L533。也就是说文本行是字符截图行是像素编码。成本差异不是实现巧合而是四种表示形式本身的差异。同一个长页面排序反了过来不要把小页面上得到的比例照搬到长页面。同样的四个工具换到一个含400 个段落、服务端返回 37,538 字节 HTML的页面上重新测量页面如何返回字节数说明browser_read_text默认参数6,101被截断并且它自己说了browser_read_textmax_chars: 5000035,490完整文本browser_read_html37,531不截断browser_snapshot78该页面没有任何交互元素browser_take_screenshot123,940一个视口这里有三点变化每一处都推翻了你可能从小页面表格里得出的结论。文本默认截断而且会明确告诉你。默认读取的尾部原文是6000 of 35490 characters. Raise max_chars, or narrow the selector to the part you need.这是最好的行为因为替代方案是静默地返回一段残缺答案——模型会把断在句子中间的文字当成完整的页面来回答。换言之在一个小页面上看起来完整的读取在长页面上可能只是全文的十分之一除非你调高上限或把 selector 收窄到需要的部分。该上限在源码中定义为常量DEFAULT_MAX_CHARS 6000actions.py#L26并同时出现在工具签名与工具描述里截断标记的生成逻辑见 actions.py#L140-L144。HTML 不截断所以长页面上它才是贵的那一个。小页面上它只是文本的 1.3 倍长页面上它却是四种负载中最大的文本负载37,531 字节比完整文本还大。HTML 是便宜的升级这条经验只在小页面上成立。原因同样写在注册代码里browser_read_html明确声明Unlike browser_read_text this is NOT capped因为把标记从中间切断会留下毫无意义的残破标签所以宁可返回完整的数万字符server.py#L509-L526。snapshot 根本不是文本。这个页面返回 78 字节因为它没有任何交互元素。snapshot 列出的是你可以施加动作的东西所以它的大小跟随控件的数量而不是内容的多少。在表单密集的页面上它相当可观在文章页上它近乎为空——这恰恰是正确的行为与文本的 2.1 倍给人的印象完全不是一回事。这一关系随后又在仅交互控件数量不同、其余完全相同的四个页面上做过测量结果约为每个交互元素一百字节详见 what a page snapshot costs, per control。该文档同时给出了四页对照表交互元素为 0、5、20、60 时snapshot 分别为 96、574、2,065、6,081 字节而纯文本始终在 8179 字节之间——两条线一条随控件陡增、一条几乎平直快照的成本与页面说了什么无关只与页面能做什么有关。一条规则定取舍先要能装下答案的最便宜表示装不下再升级。browser_read_text——当你要的是页面说了什么。价格、地址、确认号、一篇文章。它是 snapshot 的十分之一、截图的一百分之一。browser_snapshot——当你要对页面做点什么。四种读法里只有它把每个元素的selector 和坐标一并交还而这正是点击或填写所需的输入。它花的是页面控件的钱不是页面内容的钱。browser_read_html——当结构本身就是内容要逐行读的表格、属性、藏在 data 属性里的真实值。在文本失败之后再去拿它而不是之前在长页面上要知道它是四种文本负载里最大的而不是便宜的升级。browser_take_screenshot——当答案本质上是视觉的、其他方式都做不到没有底层表格的图表、布局问题、canvas、意义在于什么叠在什么上面的页面。仓库里如何驱动页面的说明把这套顺序落实成了一个行动阶梯server.py#L160-L190具名工具 selectorbrowser_click、browser_type、browser_select_option、browser_press_key。browser_snapshot给每个元素生成一个保证无歧义的 selector照抄即可坐标snapshot 为每个元素报告at: [x, y]视口像素browser_click_at直接吃这组数。这一级服务于 selector 描述不了的东西——canvas、slider、地图、用 div 拼出来的自定义控件你的眼睛browser_take_screenshot看画面再用browser_click_at点坐标用于 snapshot 根本没有列出的元素browser_evaluate只用于读取以上都看不到的东西。注意第 4 级在执行方向上被刻意加了护栏browser_evaluate拒绝通过赋值value、调用click()、dispatchEvent()等脚本方式操作页面因为那些路径绕过了真实键盘与指针事件到达时isTrusted为 false——这正是有东西在冒充人的最清晰信号而这个浏览器的存在意义就是不产生它。读随你写走前三级。昂贵的那个也有公道截图该用就用只盯着字节数就否定截图是错的。截图是唯一能展示实际呈现出来的是什么的表示被浮层盖住的是什么、折叠线以下是什么、视觉上被禁用的是什么、两个一模一样的标签里人眼会去点哪一个。一个模型在推理总计旁边那个按钮时它推理的对象就是一张图片——这时候递给它页面文本等于递给它另一个问题。所以规则不是永远不要截图而是当视觉排布本身就是问题所在时刻意地、一次性截图其余时间读文本。要避免的失败模式是那种出于谨慎、每步操作后都截一张图的循环——在那里八十九倍的乘数会直接吃掉整个上下文窗口。这一点在工具描述里也有印证browser_take_screenshot的定位是on demand按需一次server.py#L529-L533而专用于看 Agent 干活的browser_watch走的是另一条路径——持续抓取浏览器窗口画面供界面实时预览其描述明确警告窗口像素不能喂给browser_click_at要行动还得用browser_take_screenshotserver.py#L536-L553。看归看、动归动工具之间职责不混。snapshot 到底买了什么这是最容易被跳过的一种读法值得单独说。snapshot 不是加了额外重量的文本。它逐元素报告一次工具调用所需的身份信息一个被构造为无歧义的 selector以及该元素在视口像素中的位置。正是这一点让上面的三级阶梯成立先是有名字的工具 selector当没有 selector 能描述目标时canvas、slider、地图用 snapshot 提供的坐标只有 snapshot 连元素都不列时才动用截图。该排序背后的设计推理见 How the tools are shaped, and why。实现上snapshot 脚本只做读取注释明确给它编号就意味着往页面里写属性而这是一个以不留检测痕迹为存在理由的产品不能有这种表面见 actions.py#L156-L160。可见的判断用offsetParent ! null这样被 CSS 藏起来的元素不会混进清单并且它不是无障碍树——原因是实测出来的一个真实的注册页面上单个国家select会贡献约两百个option节点足以在字符上限耗尽之前把调用者要找的表单挤出画面actions.py#L378-L388。快照只关心能被操作的元素这一取舍同时得到测试的保护tests/mcp_server/test_snapshot_visibility.py守护可见性过滤tests/mcp_server/test_snapshot_handles.py与tests/mcp_server/test_snapshot_capping.py守护元素句柄与上限行为。HTML 读法的三种模式browser_read_html不是把原始 HTML 原样丢给模型。它分两步走而两步必须分开因为什么真的被画出来了计算样式与布局只存在于浏览器里——它在一个克隆上做这件事绝不写回活动页面随后字符串回到 Python 侧做结构化清洗这一步不依赖浏览器、可以纯测试。入口是 clean_page支持三种模式modeform默认交互表面 解释它的文本modetext纯正文标记全部去掉modefull去掉噪声、精简属性保留结构。清洗管线依次做解析Lexbor HTML parser、丢噪声、丢内联隐藏、按模式分流text 直接转纯文本、精简属性、合并折叠的option、按 form 模式裁剪到骨架、解包无意义包装器、丢空节点clean.py#L599-L622。不认识的 mode 会抛CleanError。清洗的实际收益记录在read_html的 docstring 里actions.py#L405-L407在真实页面的语料上测量9.6 MB 的标记被压到 293 KB缩小 97%而 1,453 个交互元素全部保留每页中位耗时 48 ms。这是仓库注释中的实测数字也是HTML 值得读的前提——它读的是被清洗过的结构不是原始 soup。相关行为由tests/mcp_server/test_read_html_in_a_browser.py与tests/mcp_server/test_clean.py覆盖。这不是在讲什么有一个形状相似、容易混为一谈的问题读 DOM 的 Agent 和点像素的 Agent在被检测这件事上是否不同。那是关于网站能看到什么的问题不是关于你的上下文花多少钱的问题它有自己独立的答案。本文只谈账单不谈检测面——这两个话题的混淆会导致你修错方向以为省上下文能解决被检测或以为换检测策略能解决烧上下文。常见问题速答我的 Agent 该用截图还是 DOM论成本用 DOM小页面上相差约九十倍。凡视觉排布本身即问题所在的场景用截图而且刻意地、只用一次。一张截图占多少上下文以本文测量的页面为例90,768 字节 base64对 1,021 字节文本。它随视口缩放不随页面内容多少缩放一个几乎空白的页面照样花费一整张图。为什么短任务也会耗尽上下文数一数截图。同一页面截十张就是九十万字节而任务本身可能只有一千字节。read_text和snapshot有什么区别文本是页面说的快照是页面提供的元素、selector、位置。前者用来读后者用来动。HTML 什么时候才是正确答案当结构携带文本会丢失的含义时表格单元格、属性、存在标记里而非展示出来的值。小页面上它是文本的 1.3 倍长页面上它是四种文本负载里最大的所以便宜的升级只在页面短时成立。为什么我的读取回来是截断的文本读取有默认上限。本文的长页面上它返回了 35,490 字符中的 6,000 字符并附带一行话把这件事说明白。调高max_chars或收窄 selector。要点是长页面上的短答案不代表页面本身短。仓库侧的测试也守住了这条承诺——tests/mcp_server/test_json_capped.py验证被截断的 JSON 会如实报告truncated与字符数而不是静默截短。延伸阅读how many MCP tools is too many——统计另一种常驻上下文成本无论你是否读取页面每轮都要付出的那一份how long an AI browser agent takes per step——四种读法在墙上时钟上都是免费的它们只在上下文上不同what a page snapshot costs, per control——快照成本约每交互元素一百字节的完整测量。方法一分钟在你的页面上重测本文两张表格故意互相矛盾而这正是结论在一张页面上量出的比例只是关于那张页面的事实。要在自己的任务上验证方法只需要一分钟把四种工具各调用一次比较返回负载的长度。字节数是工具返回的文本或图片负载的长度截断行为看返回文本的尾部是否带标记实测环境是经 stdio 连接的 MCP server页面由127.0.0.1本地服务小页面数字为中位数三次运行、长页面每种工具各跑一次。在任何新页面上重跑这个实验比把八十九倍或2.1 倍当普适常数带进新项目要可靠得多——成本结构随页面类型翻转唯一稳的规则是先要最便宜的装不下再升级。赞分享人工智能AI Agent浏览器控制GUI 自动化MCP 服务【免费下载链接】invisible_playwright_mcpPlaywright MCP server undetected by anti-bots and captchas: AI agent browses the web on anti-detect stealth Firefox, Python, undetected browser automation, scraping, computer use.项目地址https://gitcode.com/GitHub_Trending/jo/invisible_playwright_mcp点击查看免费下载相关推荐用 AI Agent 总结长页面Invisible Playwright MCP 的展开、读取与可核查摘要方案用 AI Agent 总结长页面Invisible Playwright MCP 的展开、读取与可核查摘要方案 本文是 Invisible Playwrigh人工智能AI Agent浏览器控制GUI 自动化MCP 服务WarcraftHelper免费实测魔兽争霸3的30帧锁帧、4MB地图限制、宽屏拉伸一个插件全搞定WarcraftHelper免费实测魔兽争霸3的30帧锁帧、4MB地图限制、宽屏拉伸一个插件全搞定 周六晚上十一点老周翻出大学时代的移动硬盘里面躺着一张人工智能AI Agent浏览器控制GUI 自动化MCP 服务Chromeless HTML获取方法提取页面源代码的两种方式Chromeless HTML获取方法提取页面源代码的两种方式 你是否曾为获取网页源代码而烦恼是否尝试过各种工具却找不到简单高效的解决方案本文将介绍如何使开发工具测试上一篇3个维度重塑QQ空间记忆GetQzonehistory如何帮你找回消失的青春印记下一篇三步找回QQ空间全部历史说说的完整指南用Python永久保存你的青春记忆创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考