当 AI 打开浏览器:一次 LinkedIn 抓取背后的 8 层协议栈

大家好,我是若风。

先说个刚发生的事。我让 Claude 帮我读一下 Docker 公司最近的 LinkedIn 动态,就这一句话。几秒之后,它把 Docker 最近 23 条动态整理成了中文摘要,哪条在讲 AI Agent 沙箱,哪条在预热 AI Engineer World's Fair,互动数据都带出来了。

说实话,我盯着屏幕愣了一下。不是结果多惊艳,是我突然意识到,这一句话背后的工程量。

你想想看,AI 怎么知道 LinkedIn 上有什么?它又不会上网。它调用了一个叫 mcp-server-linkedin 的工具。这个工具底层不是 LinkedIn 官方 API,是用浏览器去抓页面的程序。而这个浏览器,被一个叫 Patchright 的库控制着,Patchright 又是 Playwright 的反检测分支,Playwright 通过一套叫 CDP 的协议,真正指挥 Chromium 这个浏览器内核干活,最后把页面渲染出来的,是 Blink。

一层套一层,我数了数,整整 8 层。

这篇文章就沿着这一句话,一层层拆开。看看 AI 从「想看一下 LinkedIn」到「真的打开浏览器抓回数据」,中间穿过了什么。

第 1 层 AI 模型,听懂你说话的那个大脑

一切从你那句话开始。「读一下 Docker 公司最近的 LinkedIn 动态」。

这句话进到 AI 模型里,它得做两件事。先听懂你要什么,再去想怎么拿。它自己上不了网,但它知道自己手里有一堆工具,其中有个能查 LinkedIn。

这层是整条链的大脑。没有它对意图的理解和对工具的调度,后面 7 层再强也启动不了。

第 2 层 MCP,让 AI 知道有工具可以调

AI 本身不会上网,不会读文件,不会操作浏览器。它能做的只有读文本、写文本。那它怎么完成「读 LinkedIn」这种事?

靠工具。但工具怎么告诉 AI 自己存在、自己能接收什么参数?这就得有一套约定。MCP,Model Context Protocol,就是这套约定。

我对 MCP 的理解就一句话。它不是让 AI 变强的魔法,是让 AI 和外部世界说同一种语言的翻译协议。它解决的不是智能问题,是接口问题。

具体到这个场景。mcp-server-linkedin 通过 MCP 把自己注册成 17 个能力,查公司资料、刷动态、搜职位、读私信。AI 看到的是 17 个工具的说明书,它判断「读 Docker 动态」该调 get_company_posts,把 docker 这个参数传进去。

这一层,AI 还没碰到浏览器。它只是递出了一张工单。

第 3 层 mcp-server-linkedin,把抓 LinkedIn 包装成 17 个工具

工单递到了 mcp-server-linkedin 手里。它接到 docker 这个参数,要去拿 Docker 公司的动态。

你可能会问,为什么不直接调 LinkedIn 的 API?坦率的讲,LinkedIn 没有给普通人开放这种 API。它的数据锁在登录态后面,想拿,就得像一个真人用户那样,登录,打开页面,等加载,然后把页面内容抓下来。

所以这个工具的底层,不是 API 调用,是浏览器自动化。它启动一个真实的浏览器,用你登录过的 LinkedIn 会话,导航到 Docker 公司主页,把动态一条条抓回来。

这里就埋下了后面所有层的根源。因为「用浏览器抓页面」这件事,远比调一个 API 复杂。

第 4 层 Patchright,为什么不能直接用 Playwright

浏览器自动化,第一反应是用 Playwright 或者 Puppeteer。但 mcp-server-linkedin 用的是 Patchright,一个多数人没听过的库。

为什么换掉 Playwright?因为反爬。

LinkedIn 不是傻子。它知道有人在用程序抓它的页面,所以部署了 Cloudflare 这类反爬服务。这些服务检测的,就是「这个浏览器是不是被程序控制着」。

而 Playwright 控制浏览器时,会留下一堆指纹。最致命的一个叫 Runtime.enable。Playwright 调这个 CDP 命令在页面里执行 JavaScript,但这个动作本身会在页面留下可检测的痕迹,反爬服务一查一个准,挺让人崩溃的。

Patchright 干的事就是把这些指纹抹掉。Runtime.enable 的泄漏,它改用隔离的执行上下文绕过。Console.enable 的泄漏,它直接把控制台 API 禁掉。命令行参数里那个会暴露自动化的 --enable-automation,它去掉。

讲到底,Patchright 就是 Playwright 的一个补丁版,API 完全一样,改个 import 就能用,但它在底层把所有「我是机器人」的标记都擦干净了。

这是整条链里我觉得最妙的一层。功能没变,能力没少,与其说它变强了,不如说它学会了伪装。

第 5 层 Playwright,这套 API 从哪来

Patchright 是 Playwright 的 fork,版本号都跟着 Playwright 走。那 Playwright 又是从哪来的?

往前追溯,2017 年 Google 发布了 Puppeteer,第一个把 CDP 封装成好用的 API 的库,迅速成了 Node.js 浏览器自动化的标配。三年后微软发布 Playwright,核心团队就是从 Puppeteer 那边过来的,早期代码直接 fork 自 Puppeteer。

Playwright 比 Puppeteer 走得更远。它不只支持 Chrome,还支持 Firefox 和 WebKit。不只 Node.js,还有 Python、.NET、Java。2026 年的 Playwright 甚至把 AI Agent 当成一等公民,专门提供了 CLI 和 MCP 两种形态给 AI 用。

所以这条链的框架层,其实是一部进化史。Puppeteer 是鼻祖,Playwright 是继任者,Patchright 是继任者的反检测分身。

第 6 层 CDP,真正控制浏览器的协议

不管是 Puppeteer、Playwright 还是 Patchright,它们那些花里胡哨的 API,page.goto、page.evaluate、page.screenshot,到底层全都翻译成同一种东西。CDP。

CDP 全称 Chrome DevTools Protocol,Chrome 的调试协议。你打开 Chrome 的开发者工具,那个面板背后跑的就是 CDP。它通过 WebSocket 和浏览器通信,用 JSON 格式传消息。

CDP 把浏览器的所有能力拆成了 58 个 domain。Page 管导航和截图,Runtime 管执行 JavaScript,Network 管网络请求,Target 管标签页。每个 domain 还得先 enable,浏览器才会给你推事件。

举几个真实的动词。想打开新标签页,调 Target.createTarget。想附着到这个标签页,调 Target.attachToTarget,传一个 flatten 等于 true,拿回一个 sessionId。想让页面跑一段 JavaScript,调 Runtime.evaluate。想截图,调 Page.captureScreenshot。

这才是浏览器自动化的底层语言。上面那些框架,不过是把这些动词包装成人话。

第 7 层 Chromium,CDP 控制的到底是个什么

CDP 控制的那个东西,是 Chromium。Google 的开源浏览器项目,Chrome 的基础,Edge、Brave、Opera 全家都建在它上面。

Chromium 最核心的设计是多进程。一个 Browser 进程管全局,多个 Renderer 进程各自渲染一个网页,还有 GPU 进程管图形加速。每个 Renderer 都被关在沙箱里,几乎没有系统权限,就算网页里有恶意代码,也难以逃出来影响你的电脑。

这个设计是为安全,但它也解释了为什么抓一个页面要等。你调 CDP 让页面导航,得等 Renderer 进程把 HTML 解析完,等 Page.loadEventFired 事件触发,还得等网络空闲,确定懒加载的内容都加载完了,才能动手抓。不然抓回来的就是半截页面。

所以 mcp-server-linkedin 抓 Docker 动态时,它在那等页面加载、等网络静默、还自动往下滚几下触发懒加载,都是有原因的。Chromium 的架构决定了,你得给它时间。

第 8 层 Blink,把 HTML 变成你能抓的 DOM

CDP 让浏览器导航、执行 JS,但页面最后长什么样,是一个叫 Blink 的渲染引擎决定的。Blink 在 Chromium 里,负责解析 HTML、排版、绘制,把一堆标签变成你眼睛看到的页面。

这里有个关键。mcp-server-linkedin 抓的,不是服务器返回的原始 HTML,是 Blink 渲染完之后的 DOM。

现在的网页,尤其是 LinkedIn 这种,首屏 HTML 里往往啥都没有,内容是 JavaScript 跑起来之后动态塞进去的。所以你不等 Blink 把 JS 执行完、把内容渲染进 DOM,抓到的就是空壳。这也是为什么前面那层要等网络空闲、要滚动触发懒加载,都是在等 Blink 把活干完。

横切一下,四种路线怎么选

拆到这,整条链清楚了。但有意思的是,实现「用程序控制浏览器」这件事,不止一条路。我见过四种,各有各的取舍。

路线 代表 特点 适合场景
鼻祖框架 Puppeteer Node.js,功能全 常规自动化
继任框架 Playwright 多语言多浏览器 跨浏览器测试
反检测 fork Patchright 抹掉自动化指纹 抓有反爬的站点
自研裸 CDP baoyu-url-to-markdown 零依赖,几百行 轻量工具分发

这第四种是我最近拆一个 Skill 时发现的。那个叫 baoyu-url-to-markdown 的工具,作者压根没用 Puppeteer,自己用几百行代码写了个 CDP 客户端。理由很实在,Puppeteer 要下载一百多兆的浏览器,作为一个要分发的 Skill 太重了。而且他想复用你已经打开的 Chrome,这个能力 Puppeteer 也不直接给。

所以选型这事没有标准答案。看你是在做产品、做测试、做爬虫,还是做个轻量工具。

这条链还没定型

写到这里,8 层拆完了。但我想多说一句,这条链其实还在快速变化。

CDP 是 Chrome 专有的,功能最全但绑死 Chromium。W3C 在推一个叫 WebDriver BiDi 的标准,目标是让 Firefox、Safari 也能用同一套双向协议,跨浏览器自动化。Puppeteer 和 Playwright 都在跟进。

更值得盯的是 MCP 和浏览器的融合。Puppeteer 已经支持实验性的 WebMCP,CDP 协议里也冒出了一个叫 WebMCP 的 domain 条目,虽然还是空的。如果这事成了,浏览器可能原生就暴露 MCP 接口,AI 调用浏览器都不用中间再套一层框架。

那现在这 8 层,以后说不定能少几层。

写在最后

回头看这次抓 LinkedIn。一句「读下 Docker 的动态」,背后是 AI 模型听懂意图,MCP 递工单,mcp-server-linkedin 接活,Patchright 伪装成真人,Playwright 提供人话 API,CDP 发底层指令,Chromium 多进程调度,Blink 把页面渲染成 DOM。

AI 长出手脚这件事,不是一句 prompt 搞定的。它是一整条协议栈,一层层把「想」翻译成「做」。

理解这条栈有什么用?下次你的 AI Agent 上网抓数据被抓了、超时了、抓到半截了,你知道该去哪一层找问题。而不是只能盯着一句报错发呆。

这大概就是拆解的意义,把魔法还原成工程。

相关推荐
旗开得胜马到成功5 分钟前
AI编程智能体删库后,我把开发环境从每日备份换成中科热备CDP秒级回滚
大数据·elasticsearch·ai编程
ADRU21 分钟前
深度拆解DeepSeek Harness插件热更新实现原理
人工智能·ai·ai编程
AINative软件工程40 分钟前
LLM Token Budget 工程实践:给每个请求设上限,让成本和质量都在掌控中
后端·llm·ai编程
苏灿烤鱼1 小时前
上下文写成文件系统,为什么向量还能静默丢?
python·github·agent
怕浪猫9 小时前
DeepSeek Harness 源码实战 第4章:Session 会话日志——单一事实源
agent·产品·资讯
fthux9 小时前
招聘季实测:我用 TraeWork 搭了一套 AI 简历初筛系统
人工智能·ai编程·trae
用户479492835691511 小时前
字节Agent开发技术分享—旧会话越聊越笨,新会话又得重讲?我给 Matt Pocock Skill 炼了套《影分身之术》:本体想清楚,分身写代码,完事回来汇报
面试·agent
小虎AI生活11 小时前
WorkBuddy + Canva 可画 MCP 技术解析:从"图"到"活稿"的范式与实操
ai编程