Botasaurus 评测:4 MB 驱动、122 MB 安装包,以及你不该引用的 0.08 毫秒数据

最后更新于 August 14, 2026
Botasaurus 评测:4 MB 驱动、122 MB 安装包,以及你不该引用的 0.08 毫秒数据
AI 摘要

Botasaurus 是 Omkar Cloud 推出的一款 Python 网页爬取框架,它把自己包装成一套“开箱即用”的爬虫构建工具。你只需要写一个普通函数,再加上 @browser@request@task 装饰器,框架就会自动为你接上浏览器驱动、类浏览器 HTTP 客户端、缓存、并行处理以及多种格式的输出。它本质上是一个元包,这一点最值得关注:pip install botasaurus 并不是在你的环境里装进单一库,而是会拉起一整组官方 wheel,以及一大串传递依赖。也正因为这个机械层面的细节,才让我真正有东西可以客观测量。

Botasaurus 是 Omkar Cloud 推出的一款 Python 网页爬虫框架,它把自己包装成一套“开箱即用”的爬虫构建工具。你只要写一个普通函数,再加上 @browser@request@task 装饰器,框架就会自动替你接上浏览器驱动、类浏览器 HTTP 客户端、缓存、并行处理,以及多种格式的输出。它本质上是一个元包,这一点最值得注意:pip install botasaurus 并不是在你的环境里装进一个单一库,而是会拉起一整组官方 wheel,以及一大串传递依赖。也正因为这个很“机械”的细节,才让我真正有东西可以客观测量。

Botasaurus 的卖点之一是“反检测”,而这篇 botasaurus 评测恰好刻意不碰这个维度。我做的是对框架本身的盘点——装了什么、导入了什么、有哪些方法、体积多大、采用什么许可证——而不是把它拿去对抗任何真实防护。下面出现的所有体积和导入数据,都来自 pippython -c "import ...",以及对一些已经构造出来、但从未被要求抓取页面的类做的 introspection;这些测试里没有启动浏览器。后面我确实启动了浏览器,但只访问我自己写、自己托管在 127.0.0.1 上的页面,用来观察驱动会如何自我声明,以及它能否抓到由 JavaScript 动态生成的内容。整个过程都没有涉及真实网站,没有接触或测试任何反爬服务,也没有碰 CAPTCHA。它在真实网站上的有效性不在本文范围内——我宁愿一开始就说清楚,也不想暗示一个我根本没跑过的 benchmark。

有了这个边界之后,最核心的发现其实很朴素:它的安装占用不小,但原因并不是驱动本身很重,而是“全家桶”思路让它把很多东西一并带上了。一次干净安装会生成一个 122.3 MBsite-packages 目录,共 44 个包;而处于整套系统核心的浏览器驱动本身只有大约 4 MB。也就是说,框架之所以大,不是因为驱动大,而是因为它把 numpy、lxml、gevent 以及十几个别的依赖一股脑装进来,去完成一个“抓 HTML”的任务。第二个结论则是一个很容易被引用、但其实不该拿来当优点的数据:import botasaurus 只需 0.08 ms,看起来像极了一个轻量框架,实际上只是因为它的门面几乎是空的。

Botasaurus 到底是什么

Botasaurus —— GitHub 上的 omkarcloud/botasaurus,我在 2026 年 7 月 14 日抓取元数据时,它有 5,561 个 stars、486 个 forks 和 58 个 open issues —— 它是一个 Python 框架,而不是一个单点工具。我测试的版本是元包 botasaurus 4.0.97,以及底层引擎 botasaurus-driver 4.0.92。元包声明的 requires-python>=3.7(驱动则是 >=3.5),PyPI 分类器只写到 3.11。不过在我的机器上,它在 Python 3.14.2 下能够安装成功,并通过导入烟雾测试。这个结论只说明我的这次安装没问题,并不等于所有功能都能在所有环境里兼容。

先把类别说清楚很重要,因为它决定了“好不好”的判断标准。Botasaurus 属于 框架,和 Scrapy 以及 Crawlee 处在同一类:你采用它的结构、装饰器和约定,它则替你处理底层杂事。它和 nodriver 这种专注型驱动不一样,后者给你一个 Chrome DevTools Protocol 连接后就尽量不打扰你。Botasaurus 虽然也包含驱动(即 botasaurus-driver),但它外面还包了一层任务调度、缓存、输出序列化和请求客户端。你买的不是一个驱动,而是一套带驱动的、意见很明确的工作流。

三个装饰器就是它设计的缩影,而且这三个入口都是真实存在的——我确认过 botasaurus.browser.browserbotasaurus.request.requestbotasaurus.task.task 都能正常导入。@browser 会把你的函数跑在浏览器驱动上。@request 则让它跑在一个看起来像浏览器的轻量 HTTP 客户端上。@task 是通用包装器,负责那些不属于前两类的任务。一旦加上装饰器,Botasaurus 就会帮你补上周边能力:并行执行、驱动复用、结果缓存,以及 JSON、CSV、Excel 和 HTML 的写出支持。这是一个连贯的设计。至于你是否需要一个这么完整的框架把爬虫包起来,那就是取舍问题,不是缺陷。

我的总体判断,以及它的边界

Botasaurus 是个能力在线、结构清晰的工具,做到了框架本该做的事:把常见路径缩短。装饰器模型也很干净。MIT 许可证确实友好。安装过程也没有什么幺蛾子。如果我只看 API 的手感,它是合格的,而且表现不错。

但我一直绕不开的一点是:它自己最主打的“反检测”能力,恰恰是一个负责任的评测不能随便下结论的地方,除非你把它拿去对着别人的生产防护系统做实测。这个驱动确实暴露了一些明确以反检测为名的 API;我确认过这些方法存在,但没有把它们拿去对真实目标做行为测试。除此之外,我不会再延伸任何结论。我没有把它指向受保护网站,没有测成功率,也没有逆向其机制,更不会用措辞去暗示这些事情。方法确实在类里。它们在真实环境里会怎样,是另一个评测,不是这篇。

接下来我能给出的,是一份能力、安装、资源和许可证的清单,再加上它在我自己控制的页面上的表现——这比大多数针对这类工具的评测都更窄,而这种“窄”正是重点。

它会向页面暴露什么

Measured results chart: Default browser disclosures by stack

有一个问题不需要接触任何真实防护也能回答:Botasaurus 驱动浏览器时,这个浏览器会向页面主动透露什么信息?我写了一个页面,读取最直观的字段——navigator.webdriver、user-agent、platform、languages、插件和硬件数量、window.chrome 的形态、Permissions API 的返回值、窗口与屏幕几何信息——把它部署在 127.0.0.1 上,然后拿四套栈去访问:Botasaurus、nodriver,以及原生 Playwright 和原生 Puppeteer 作为对照。四者都驱动了同一个 Chrome 构建(Chrome for Testing 151.0.7922.10),所以如果有差异,那就是库本身不同,而不是浏览器不同。分别做 headless 和有界面模式,每种三次。下面列出的所有值,在三次运行中都保持一致。

模式navigator.webdriverUser-agent 标记navigator.languages
Botasaurus 4.0.92headlessfalseHeadlessChrome/151.0.0.0["en-US"]
Botasaurus 4.0.92headedfalseChrome/151.0.0.0["en-US"]
nodriver 0.50.3headless / headedfalseHeadlessChrome/151 / Chrome/151["en-US"]
Playwright 1.56.0headless / headedtrueHeadlessChrome/151 / Chrome/151["en-US","en"]
Puppeteer 24.16.0headless / headedtrueHeadlessChrome/151 / Chrome/151["en-US"]

这些差异取决于你拿哪套控制组来比。和原生 Puppeteer 比,Botasaurus 改变了 navigator.webdriver;语言列表和零尺寸窗口几何保持一致,user-agent 也只是在版本格式上略有不同。和原生 Playwright 比,观测到的差异还包括语言列表和窗口几何。和 nodriver 比,这里展示的字段中,布尔值和语言项一致,只有 user-agent 格式不同。这些都是默认信息披露的观测,不是反检测评分。

有两个细节比单纯看到 false 更有意思。第一,值是怎么变成这样的。在四套栈里,这个属性依旧是浏览器自身 Navigator.prototype 上的原生 getter —— function get webdriver() { [native code] } —— 从来不是挂在实例上的自有属性,也没有被替换成别的函数。所以 Botasaurus 不是在页面加载后去改这个属性;它是在浏览器启动时就决定了这个值,而且属性本身没有被动过。

第二个细节则直接限制了它的营销说法。在 headless 模式下,Botasaurus 的 user-agent 仍然会直接暴露 HeadlessChrome/151.0.0.0 —— 和原生 Puppeteer 一样,和原生 Playwright 也一样。切到有界面模式后,它又会变成 Chrome/151.0.0.0,同样与对照组一致。Driver 构造函数确实提供了 user_agent 参数,所以你可以通过一个关键词参数去设置它,但默认配置并不会帮你遮住浏览器自动化里最著名的自我标识字符串。

其他几乎所有字段在四套栈里都一样,这一点需要直接说清楚,因为这会收窄故事范围——下面这些属性在 Botasaurus、nodriver、Playwright 和 Puppeteer 上读到的值都相同:

属性四套栈上的相同值
platformMacIntel
vendorGoogle Inc.
插件数5
MIME 类型数2
pdfViewerEnabledtrue
逻辑核心数12
报告的设备内存16 GB
触控点数0
window.chrome存在,且有 app/csi/loadTimes,但没有 runtime
WebGL renderer 字符串四者完全一致

Permissions API 和 Notification.permission 之间经典的不一致问题,在这里没有出现——四者都一致返回了 defaultprompt。我还检查了 documentwindow 中是否残留老式 WebDriver 常见的 cdc_ 前缀痕迹:四者都为空。

在部署之前还有一件事值得知道:尽管 Botasaurus 有 122 MB,它本身并不随包附带或自动下载浏览器。find_chrome_executable() 会解析到你机器上已经安装的 Chrome——我的机器上是 /Applications/Google Chrome.app,版本 150.0.7871.187——而这就是 user-agent 最终暴露出来的版本。你的环境里装着什么 Chrome,它就会“宣告”什么版本。对一个如此强调配置意见的框架来说,这个默认值反而出奇地不带偏向。

所以要说清楚:这只是一个自动化栈在没人要求它隐藏时会暴露什么的记录。它对防守方很有用,也能帮助你了解自己的工具到底在广播什么。但它不是某个服务是否会在意这些特征的判断。我没有测试这一点,所以上面的任何一行都不该被解读为某种结论。

在这个测试样本上,更宽容的默认读取结果

暴露自己是一回事;拿到正确 HTML 才是目标。我用 Botasaurus 跑了这套 benchmark 仓库里共用的三类内容 fixture,所以它的结果可以和这里测过的其他工具直接对齐。这个页面包含三种东西:A 是一条静态链接,标记直接写在响应字节里;B 是在解析过程中由内联脚本构建出来的节点,它的标记和 URL 都是由碎片拼接而成,只有真正执行 JavaScript 才能看到;C 是在 load 事件后 800 ms 才注入的节点,拼接方式相同。C 类是最“刁钻”的——如果只在 load 时读取页面,根本看不到它。

默认读取显式等待后
Botasaurus 4.0.923 项中的 2 项(A + B,漏掉 C)3 项中的 3 项
nodriver 0.50.33 项中的 2 项3 项中的 3 项
Playwright 1.56.03 项中的 2 项3 项中的 3 项
Puppeteer 24.16.03 项中的 2 项3 项中的 3 项

Botasaurus 的结果和这些重量级工具落在同一个位置。driver.get() 后直接读取 driver.page_html,得到的是“加载时快照”:它确实能正确执行 JavaScript——B 类就是证据,因为 B 的内容根本不在服务端字节里——但对于 800 ms 后才出现的内容,它会错过 C。加上 driver.wait_for_element("#delayed-injected"),就能拿到全部三项。这个结果在三次重复和整套测试的三次独立运行里都很稳定,没有出现 flaky。

更有意思的是,当你扫一遍注入延迟,看看各栈默认读取何时开始漏内容:

C 类在以下时间后注入BotasaurusnodriverPlaywrightPuppeteer
0 ms找到找到找到找到
100 ms找到
200 ms找到
300 ms找到
400 ms 及以上

其他所有栈在内容注入延迟达到 100 ms 或更晚时,都会立刻错过 C。Botasaurus 却能在 300 ms 时仍然抓到它,直到 400 ms 才放弃。这是框架化设计带来的结果,原因也写在构造函数里:wait_for_complete_page_load=True 是默认值,所以 get() 的返回时间明显晚于单纯的 load 事件。具体来说,在这些默认读取里,它每次导航要多花 401–431 ms 的墙钟时间,而 nodriver 只要 119–129 ms,Puppeteer 只要 125–171 ms。

在这个本地延迟注入 fixture 上,代价大概是每次导航多出约 250 ms,从而换来更晚的默认快照。它能在这些运行里捕获到 load 后最多 300 ms 才出现的内容;但这并不说明 Botasaurus 在所有网站上都更“正确”。如果你写的是不带显式等待条件的快速爬虫,这个缓冲区确实能减少漏抓晚到节点的概率;但如果你的导航量很大,或者你本来就会等待精确条件,那这就是纯粹的额外开销。

再看两个量级上的时间。拉起浏览器时,Botasaurus 基本和 nodriver、Puppeteer 持平,但明显慢于 Playwright:

浏览器启动耗时(跨多次运行)
Botasaurus 4.0.92986–1151 ms
nodriver 0.50.3910–1583 ms
Puppeteer 24.16.0969–1008 ms
Playwright 1.56.0282–365 ms

wait_for_element() 在注入延迟 300 ms 以内几乎不增加额外成本——因为 get() 此时本来就已经等过了注入点——到了 400–800 ms 会升到约 1.42 s,1500 ms 时则约为 2.43 s。

122 MB 的问题:元包到底装了什么

Measured results chart: Heaviest installed dependencies

下面这组算术最有用,所以我直接给你结果。一份干净的 pip install botasaurus,在一个全新的虚拟环境里,生成了一个 122.3 MBsite-packages 树,包含 44 个 dist-info 包。把 pip 自己去掉(10.9 MB,这属于 venv 开销,不是 Botasaurus 主动要求的内容),剩下大约 111 MB 的就是框架与依赖。真正负责浏览器自动化的驱动组件只有大约 4 MB。也就是说,剩下大概 107 MB,都是这个元包自认为你需要的其它东西。

它们都去哪儿了?光是最重的五个传递依赖,就占了大头(每一行都是 install_footprint.heaviest_deps_mbartifacts/raw/runs/resource_baseline.run1.json 里的条目;总和是我自己加的,不是文件里的字段):

磁盘占用
numpy30.9 MB
lxml19.2 MB
botasaurus_requests12.6 MB
gevent11.3 MB
pygments8.4 MB
五个包合计82.4 MB(30.9 + 19.2 + 12.6 + 11.3 + 8.4)

numpy 竟然是单体最大的组件,这一点确实让我挑了下眉——这可是线性代数库,却被塞进了一个本职工作是抓取和解析网页的工具里。不能说它不合理;框架往往会不断累积工具型依赖,而依赖树里显然有东西需要数组运算。只是为了这点“跑腿活儿”,它带来的机器重量实在不轻。

作为对比,同样在这台机器上,专注型驱动 nodriver 的安装体积大约是 17.2 MB,共 6 个包,算下来大概比 Botasaurus 轻 7 倍 左右。(这个数字并不是来自本次安装包,而是 nodriver 自己的 artifacts/raw/runs/resource_baseline.run1.json 中的 install_footprint.site_packages_total_mb,是在同一台机器上另一次分阶段运行中测得的;122.3 ÷ 17.2 = 7.1。)这两个数都不是“缺陷”,也不是能力排名;它们只是“全家桶框架”和“专注驱动”之间的机械成本差异。放到容器里看,测得的 site-packages 体积会计入应用层,但这并不是完整镜像大小;这次测试也没有测构建时间或冷部署时间。

还有一个体积层面的细节:在 introspection 过程中,第一次调用 from botasaurus.request import request 会触发一次约 12.8 MB 的下载。由于这次记录并没有把下载对象和目标地址抓得足够完整,所以我不会把这个数当成稳定的已安装体积增量。不过它确实说明了,这条代码路径首次使用时可能需要网络访问;如果你准备把它放进离线环境,最好先在自己的镜像里复现一下。

那个会“骗人”的导入时间

冷启动导入时间正是很多人看数值会看偏的地方。以七次全新子进程导入的统计来看,顶层 import botasaurus 的中位数只有 0.08 ms。如果单独引用这个数字,它看起来像是同类里最轻的框架。

但事实并不是这样。它快,是因为顶层几乎什么都没做。botasaurus 这个顶层包没有暴露 __version__,公共命名空间也几乎是空的——它几乎不干活,因为里面几乎什么也没有。真正对 CLI 工具或 serverless 冷启动有意义的,是引擎的导入:from botasaurus_driver import Driver 大约需要 135 ms,而且在多次运行中基本稳定。那才是你在抓取任何页面之前必须支付的固定成本。并且一旦驱动模块导入完成,常驻内存大约会停在 29–30 MB——注意,这还是在 Chrome 进程尚未启动之前。等你真的拉起浏览器,内存会明显上涨;我没有测浏览器运行中的内存,所以这里不报具体数字。

这里的结论很简单,但很锋利:import botasaurus 之所以快,不是因为框架廉价,而是因为顶层入口几乎是空壳。如果你在算冷启动,应该测你真正要依赖的那个导入。

API 结构:近乎空壳门面后面藏着 99 个方法

System diagram: API shape: behind a near-empty front door

引擎里的 Driver 类公开了 99 个方法——覆盖范围很广,包括导航、元素查询、cookie 和 local storage、鼠标键盘操作、截图、标签页管理、CDP 转发以及文件上传。构造函数有 18 个参数,这也算把可调表面画得比较完整:headlessproxyprofiletiny_profileblock_imagesblock_images_and_csswait_for_complete_page_loadchrome_executable_pathextensionsargumentsuser_agentwindow_sizelang,以及其他一些参数。作为“创建时 API”,它基本覆盖了常见的浏览器封装控制项。

不过这个结构有一个顶层小陷阱,虽不致命,但确实存在。import botasaurus 得到的是一个几乎空的命名空间——没有 __version__,顶层公共名称也几乎没有。你真正会用到的功能都在子模块里:from botasaurus.browser import browser, Driverfrom botasaurus.request import requestfrom botasaurus.task import task。如果你想直接找 botasaurus.__version__ 记录当前构建版本,你是找不到的;得改用 importlib.metadata。这不会导致任何功能失效,只是这并不是大多数 Python 开发者下意识会期待的布局。知道这一点,能帮你在第一天少浪费五分钟。

关于我前面标记的那些方法,还有一个值得记录的文档层面观察:在那些以反检测命名的方法里,只有 2 个带有代码内 docstring。其余方法主要靠名称自解释,具体说明放在外部文档站里,而不是安装后的源码中。这只是一个“文档放在哪里”的说明,不是质量判断——很多优秀库都会把长篇说明写在代码外。但如果你的工作流是“直接读源码理解方法”,那这块 surface 大多数时候只会告诉你名字,不会告诉你行为。

许可证:从元包到驱动,全是 MIT

无论是元包还是 botasaurus-driver,都使用 MIT 许可证,并带有标准的 License :: OSI Approved :: MIT License 分类。MIT 非常宽松:没有 copyleft 义务,不要求你开源自己的代码,商业使用也几乎没有阻碍。这和相邻的反检测驱动 nodriver 形成了很真实的对比——后者采用的是 AGPL-3.0,一个带有网络使用条款的 copyleft 许可证,很多法务部门都会因此提高警惕。如果你的选型会被许可证卡住,Botasaurus 的 MIT 立场确实是一个加分项。

但这里还是要回到“元包”的老问题。这个宽松的 MIT 只覆盖 Omkar Cloud 自己发布的第一方 wheel,并不能自动覆盖安装时拉下来的那大约 40 个传递依赖;每个依赖都有自己的许可证。我确认了 Omkar Cloud 发布的顶层包是 MIT,但并没有逐个审计依赖树里的许可证。对于一个个人项目,这种区别通常不重要;但如果你准备在公司里整棵树引入,而且还要管 software bill of materials,那么这 40 包的依赖树就应该先过一遍你自己的 license 扫描器——不是因为我发现了问题,而是因为我没去查,而元包恰恰是最容易藏着意料之外许可证的地方。

优缺点

优点:

  • 三装饰器设计清晰(@browser / @request / @task),三个入口都已确认存在——框架把常见用法缩短了。
  • 元包和驱动均采用 MIT 许可证,与同类 AGPL-3.0 驱动相比更友好,适合商业使用,没有 copyleft 负担。
  • 驱动能力面很宽:99 个公开方法、18 个构造参数,覆盖常见浏览器自动化需求。
  • 在 Python 3.14.2 和 3.12.13 上都通过了安装和导入烟雾测试,超出了它分类器所写的 3.11 上限;但运行层面的完整兼容性并未证明。
  • 在我测过的所有栈里,它的默认读取窗口最宽:对注入于 load 后 300 ms 的内容仍能捕获,而 nodriver、Playwright、Puppeteer 在 100 ms 时就开始漏掉。wait_for_complete_page_load=True 确实在工作。
  • 默认情况下会把 navigator.webdriver 置为 false,而原生对照组都是 true,且没有通过补丁方式改写属性——descriptor 仍然是浏览器原生 getter。
  • 设计上自带“全家桶”能力——缓存、并行、驱动复用,以及 JSON/CSV/Excel/HTML 输出都内置,不需要额外拼装。

缺点:

  • 磁盘占用大:122.3 MB、44 个包,体积大约是专注驱动的 7 倍;主要膨胀来自 numpy(30.9 MB)和 lxml(19.2 MB)等依赖,而不是约 4 MB 的驱动本体。
  • 看起来很香的 0.08 ms 顶层导入是误导性的;真正会花时间的是你实际依赖的引擎导入,大约 135 ms,而且导入后常驻内存约 29–30 MB,浏览器还没启动。
  • 更宽容的默认读取窗口不是免费的:在同一页面、同一 Chrome 上,每次 navigate-and-read 要比轻量驱动多出约 401–431 ms,而对照组只有 119–129 ms。
  • headless 运行时,user-agent 默认仍会暴露 HeadlessChrome,和原生控制组完全一样;构造函数虽有 user_agent 参数,但默认不会帮你改。
  • 尽管体积有 122 MB,它仍然不自带浏览器——它驱动的是宿主机上已经安装的 Chrome,所以你暴露出去的浏览器版本就是机器上现成的那个。
  • 本次运行中,第一次使用 @request 触发了约 12.8 MB 的一次性下载;由于对象和目标地址没有记录充分,不能把它视为稳定体积增量。
  • 顶层包几乎是空的,也没有 __version__;真正的 API 和版本信息都藏在不那么显眼的地方。
  • 大多数以反检测命名的方法没有内置 docstring,因此从源码里你通常只能看到名字,看不到行为说明。

超出这些数字覆盖范围、因此本文没有测试的内容包括:真实环境下的反爬有效性(按设计不测)、单页内存、代理和 profile 处理、规模化吞吐量,以及除 macOS arm64 之外的任何平台。这里的体积和导入数据都没有启动浏览器;而页面抓取和信息披露的数据,只来自只会和我托管在 127.0.0.1 上的 fixture 对话的浏览器。

适合谁,不适合谁

如果你想要的是一套框架而不是一个单独的部件,Botasaurus 会比较合适。假如你是从一个空文件开始做抓取项目,更愿意直接采用一套结构——入口靠装饰器、缓存和并行现成可用、输出写出能力内置——那它就是一个连贯、且采用 MIT 许可的选择。MIT 很宽松,但你的实际使用和分发方式仍然应该按常规做合规审查。习惯 Scrapy 或 Crawlee 思维的团队,会觉得这个框架形态很熟悉。

如果你的部署目标特别看重体积,那就该谨慎,甚至考虑跳过。一个 122 MB、依赖树里带着 numpy 和 gevent 的安装包,对于“我只是想驱动浏览器抓几个字段”的需求来说,确实太重了。专注型驱动能用更少的体积完成自动化,但代价是周边 plumbing 需要你自己写。要是你真正想要的是“反检测到底有多有效”的结论,那就更应该跳过,因为这正是我刻意没有测试的部分——你不能把一个我既没证实也没证伪的营销说法当作判断依据。

替代方案,以及 Thunderbit 在哪里

先把最诚实的话说在前面:Botasaurus 是免费、MIT 许可、且自托管的。你自己管理机器、更新、以及整棵依赖树——总共 44 个包——包括补丁、许可证合规,以及 numpy 将来某次发布可能带来的变化。对很多团队来说,自己掌控这些东西正是他们想要的;而且在原始成本上,没有任何托管服务能击败“你已经有一个框架”这件事。

在开源世界里,真正有意义的比较更多是看“形态”。如果你站在 Botasaurus 这类框架的一侧,Scrapy 和 Crawlee 是最自然的对照对象——成熟、观点明确,而且各自都需要适应它们自己的约定。要是你需要的不是一个爬虫框架,而是从页面里直接产出适合 LLM 使用的 Markdown,那么 Crawl4AI 和偏内容提取的 Trafilatura 就是更聚焦的选择。如果你喜欢 Python + 反检测这条路线,但又嫌元包太重,Scrapling 值得一看;如果你可以接受编译语言,那么 Go 里的 Colly 会用更高速度和更小体积,换掉 JavaScript 渲染。任何浏览器驱动方案,包括 Botasaurus 在内,都会继承我们在 Playwright 和 Puppeteer 对比 里总结过的成本画像——真浏览器本来就不便宜,这也是为什么它们外面的框架会这么重。

而托管 API 是同一条流程上的另一个环节。Botasaurus 是你自己托管的开发者栈;Thunderbit 则面向同样的开发者,提供托管方案。它的 Open API 只有两个端点:POST /distill(1 credit)会把页面整理成干净、适合 LLM 使用的 Markdown,渲染和反爬都在服务端处理,所以你根本不用自己配置浏览器或依赖树;POST /extract(20 credits)则会基于你定义的 JSON Schema 返回结构化 JSON,并通过 renderMode 选择 nonebasicfull,取决于页面到底需要多少浏览器能力。两个端点都支持批量版本,一次最多可处理一百个 URL。它还提供给 agents 和编程助手使用的 MCP server——thunderbit_suggest_fields 是免费的,会在你花钱之前先告诉你页面暴露了什么——以及一个可以通过 npx @thunderbit/thunderbit-cli 调用的 CLI,适合 cron 和 CI。对于不想碰这些开发者工具的非开发人员,Chrome 扩展 也能用无代码方式运行同一套引擎,而 Thunderbit 的 YouTube 频道 则提供了常见工作流的操作演示。

真正的取舍并不在于谁“更好”,而在于工作落在谁身上。Botasaurus 把框架、浏览器 fleet、依赖、基础设施和维护都留在你这边,不按请求收取厂商费用;但计算、带宽、代理和运维仍然要花钱。托管 API 则把渲染和结构化输出从你手里拿走,按调用计费——你可以去 定价页面 里和自建方案做个对比。

试用 Thunderbit 进行网页数据提取

结论

如果你需要一套一体化的 Python 框架,而且接受它的依赖体积,Botasaurus 算是一个合理候选。它的三装饰器设计很干净,驱动能力面也很宽,而且在比它分类器声明更新的 Python 版本上通过了安装和导入烟雾测试。在我本地的 fixture 上,它的默认快照还能捕获 load 后 300 ms 才注入的内容,而其他被测栈在 100 ms 时就漏掉了;不过这只是 fixture 结果,不是通用排名。

但请把这些说法按正确尺度理解。它是一个 122 MB、44 包的安装体,真正的驱动大约只占 4 MB,剩下的是 numpy、lxml、gevent 等等——总体大约是专注驱动的 7 倍,而这部分重量最终都会反映在容器镜像和冷部署时间上。0.08 ms 的顶层导入只是一个空门面,不代表框架轻;真正要付费的,是大约 135 ms 的引擎导入。那个更宽容的默认读取会让每次导航多出大约 250 ms。而在我真正能回答的默认披露问题上,结论其实比营销说得更窄:只有一个布尔值和原生 Puppeteer 不同,headless 的 user-agent 仍然会说 HeadlessChrome,其余我测到的所有字段在四套栈里都一模一样。最能卖货的反检测卖点,恰好是这篇评测没有打分的部分——我确认了那些方法确实存在,也把驱动跑在自己机器上的一个页面上,仅此而已,且这是有意为之。知道它的体积,别被好看的导入时间误导,并把“隐身能力”当成一个还没回答的问题,那么 Botasaurus 就是一个称职的框架,做的也正是框架该做的事。只是如果你期待的是一个轻若鸿毛的驱动,docker build 的时间可能会让你有点意外。

试用 Thunderbit 进行网页数据提取 Get Started Free

常见问题

Botasaurus 是免费的吗?它用的是什么许可证? 它是免费的,而且采用 MIT 许可证——botasaurus 元包和 botasaurus-driver 引擎都带有 OSI 认可的 MIT 分类。MIT 非常宽松,没有 copyleft 义务,也适合商业使用,这一点和某些采用 AGPL-3.0 的同类反检测驱动形成了明显对比。不过要注意:MIT 只覆盖 Omkar Cloud 自己的包,不会自动覆盖安装时带下来的那大约 40 个传递依赖;如果你要整棵树引入公司环境,还是应该先跑一遍自己的许可证扫描。

Botasaurus 安装后占多大空间?为什么 import botasaurus 看起来却很快? 在我的机器上,一次干净的 pip install botasaurus 生成了一个 122.3 MB 的 site-packages 树,共 44 个包。浏览器驱动本身只有约 4 MB——体积主要来自元包拉进来的大依赖树,头号成员是 numpy(30.9 MB)、lxml(19.2 MB)、botasaurus_requests(12.6 MB)、gevent(11.3 MB)和 pygments(8.4 MB)。这大约是同机上专注驱动 nodriver 的 7 倍体积。这里没有什么“缺陷”,这就是“全家桶”的成本,而且在容器镜像大小上最明显。导入时间则把这个体积藏起来了:import botasaurus 大约只要 0.08 ms,但原因只是顶层包几乎是空的——没有 __version__,公共名称也几乎没有,所以导入时几乎不做事。真正耗时的是引擎,from botasaurus_driver import Driver 约 135 ms,导入后、浏览器启动前的常驻内存约为 29–30 MB。如果你在算 serverless 冷启动,应该测引擎导入,而不是那个空壳顶层包。

Botasaurus 会暴露哪些信息?它有没有在真实反爬系统上测试过? 前一半我测了,后一半我刻意没测。在我自己通过 127.0.0.1 提供的页面上,并使用与对照组相同的 Chrome 构建时:navigator.webdriver 返回 false,而原生 Playwright 和原生 Puppeteer 都是 true。这个值是在浏览器启动时设定的,不是靠补丁改属性——descriptor 仍然是 Chrome 自己的原生 getter。除此之外,几乎所有字段都和控制组一致:platform 字符串相同、插件数 5、核心数 12、报告的设备内存 16 GB、window.chrome 形态一致、Permissions API 没有矛盾,documentwindow 上也没有 cdc_ 风格的残留。headless 模式下,user-agent 仍会显示 HeadlessChrome/151.0.0.0,和两个原生控制组一模一样——Driver 构造函数虽然有 user_agent 参数,但默认不会替你改。至于有效性:我从未把这个驱动指向真实网站,也没有接触任何反爬服务或 CAPTCHA。驱动确实有一组以反检测命名的方法,我也确认它们存在,但我没有调用它们、没有把它们对准任何目标、没有测成功率,也没有描述其机制。上面的披露表告诉你的是“栈会说什么”,而不是“谁在听、听了会做什么”。

Botasaurus 能正确处理 JavaScript 渲染内容吗? 可以,而且它的默认行为比大多数工具更宽容。在一个包含三类内容的 fixture 上,driver.get()driver.page_html 在 800 ms 注入延迟下只能拿到 3 项中的 2 项——说明它确实能执行 JavaScript,但默认读取仍会早于非常晚到的内容;而 driver.wait_for_element() 则能拿到 3 项中的 3 项。它最特别的地方在于默认读取会等到多晚:Botasaurus 仍能抓到 load 后 300 ms 才注入的内容,而 nodriver、Playwright 和 Puppeteer 在 100 ms 时就已经开始漏掉了。这正是构造函数里的 wait_for_complete_page_load=True 在起作用,但代价是每次导航大约多花 250 ms。

安装后我该怎么导入并使用 Botasaurus? 它的用法并不是你直觉里最先想到的那种。顶层 botasaurus 命名空间几乎是空的,所以真正的 API 都在子模块里:from botasaurus.browser import browser, Driverfrom botasaurus.request import request,以及 from botasaurus.task import task。你把普通函数加上 @browser@request@task 装饰器,框架就会帮你处理驱动、缓存和输出。因为没有 botasaurus.__version__,如果你要记录当前运行的构建版本,记得改用 importlib.metadata

Ke
Ke
Thunderbit 首席技术官 | 高级数据科学家与机器学习专家 Ke Shen 拥有近十年的机器学习和数据科学经验,毕业于哥伦比亚大学,曾任 Walmart Labs 高级数据科学家。他在 Python、R、Java 和统计学方面拥有深厚且备受同行认可的专业能力,并分享如何将复杂的 AI 算法从理论落地到生产级架构的实战经验。
目录
Thunderbit · AI 网页数据代理

一键 内提取任意页面数据

深受 250,000+ 用户信赖
提供免费方案
从网页到表格
描述你的需求——Thunderbit 的 AI 代理会帮你抓取并导出到 Excel、Google Sheets、Airtable 或 Notion。可免费开始。
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week