用浏览器渲染页面比 requests 重得多:启动要多久、每个标签页占多少内存、一个页面里的图片和样式要不要加载,这些决定了你的爬虫一台机器能同时开多少页面。这篇在本机量一量 headless Chrome 的启动耗时、进程与内存,以及资源拦截的收益。
调试端口可用:中位 396 ms(各次 [457, 556, 396, 366, 361]);新建标签页并加载简单页面:中位 24 ms(各次 [26, 45, 24, 24, 22])
从启动进程到调试端口可用约 396 ms,之后新开一页并加载简单页面只要约 24 ms。所以浏览器应当启动一次、反复开页。
标签页数 进程数 RSS 之和 进程构成
0 9 1177 MiB {'浏览器主进程': 1, 'GPU 进程': 1, '工具进程': 2, '渲染进程': 5}
1 10 1325 MiB {'浏览器主进程': 1, 'GPU 进程': 1, '工具进程': 2, '渲染进程': 6}
5 14 1778 MiB {'浏览器主进程': 1, 'GPU 进程': 1, '工具进程': 2, '渲染进程': 10}
10 19 2266 MiB {'浏览器主进程': 1, 'GPU 进程': 1, '工具进程': 2, '渲染进程': 15}刚启动就有 9 个进程(浏览器主进程、GPU 进程、工具进程和几个渲染进程),RSS 之和约 1177 MiB;每多一个标签页多一个渲染进程,多约 109 MiB。把各进程的 RSS 相加会重复计算共享内存,实际占用比这个数小,但趋势是线性增长。
打开的页面 进程数 渲染进程数 RSS 之和 1 个站点 × 1 页 10 6 1309 MiB 同一站点再开 4 页(共 5 页) 14 10 1841 MiB 4 个不同站点各 1 页(再加 4 页) 18 14 2360 MiB 再加 5 个不同站点各 1 页 23 19 3009 MiB
在这个实验里,新标签页不管是同一站点还是不同站点,渲染进程数都是每页 +1(通过 CDP 新建的标签页)。我没有测同一标签页内的 iframe 或 window.open 打开的页面是否共享渲染进程。
不拦截:加载 31 ms,传输 2052 KiB,被拦截的请求 0 个 拦截 *.png 和 *.css:加载 13 ms,传输 1 KiB,被拦截的请求 21 个
用 Network.setBlockedURLs 拦截图片和样式表,传输量从 2052 KiB 降到 1 KiB,加载从 31 ms 降到 13 ms。拦截样式和图片可能让依赖它们的页面逻辑(布局判断、懒加载)失效,这点没有测。