知其然,知其所以然
爬虫工程 2026-10-12

页面里的内嵌 JSON:script 标签里的数据怎么提取

在 9 种页面上试提取内嵌 JSON 的方法:合法 JSON 的 script 标签用正则或 lxml 都行,有注释和末尾逗号的只有 json5;window.__STATE__ = {…}; 用非贪婪正则会被字符串里的 "};" 截断,raw_decode 或花括号配对才稳;JS 对象字面量里的 undefined 连 json5 也解析不了;字符串里没转义的 </script> 谁都救不了。

爬虫 内嵌JSON JSON-LD __NEXT_DATA__ json5 raw_decode script标签 Python 真实验证 动画演示
爬虫工程 2026-10-12

表单与 CSRF token:登录流程的完整请求序列

在本机登录页上完整走一遍并故意做错:要先 GET 表单拿会话 cookie 和 csrf_token,POST 时带上全部隐藏字段;没有 cookie 或 token 不对返回 403,缺 form_id 或填了隐藏输入框返回 400;登录失败后 token 轮换,旧 token 再提交 403;登录成功后会话 id 换了;AJAX 的 token 通过 X-CSRF-Token 头回传。

爬虫 CSRF 登录 表单 隐藏字段 Session Cookie requests Python 真实验证 动画演示
爬虫工程 2026-10-12

正则提取为什么在 HTML 上会坏

同一个提取目标在 12 种略有差异的 HTML 写法上:最直接的正则只答对 3 种,更宽松的正则 5 种,lxml 解析 12 种全对;正则会漏掉属性顺序/引号/空白差异,多取注释和 script 里的假标签,不解码实体不去标签;嵌套量词的正则 L=26 要 4.1 秒;而正则只比 lxml 快约 4.6 倍(1.39 对 6.43 ms)。

爬虫 正则表达式 HTML解析 lxml 灾难性回溯 正确性 Python 真实验证 动画演示
爬虫工程 2026-10-12

页面改版检测:提取结果校验与告警

模拟 8 个版本的改版:同一个提取器没有一个版本抛异常,但 v3 抓到 0 个商品、v5 价格悄悄 ×100;只看异常命中 0 / 5,字段空值率命中 4 / 5,价格中位数偏离命中 3 / 5,组合检查 5 / 5(1 个误报);灰度发布时整体平均失败率只有 22%,个别页面却是 100%。

爬虫 页面改版 数据校验 监控告警 XPath 静默失败 Python 真实验证 动画演示
爬虫工程 2026-10-12

找到真实数据接口:SPA 页面背后的请求

用 Chrome 的 CDP Network 事件记录一个单页应用加载时发的 7 个请求,找到真正含数据的 /api/products;直接用 requests 重放要补上 Cookie(缺了 401)和 X-Requested-With(缺了 403);3 次请求取到 25 条,2 ms,而浏览器渲染要 63 ms;API 还多返回页面没显示的字段。

爬虫 单页应用 XHR Fetch CDP Network 接口分析 requests Python 真实验证 动画演示
爬虫工程 2026-10-12

headless Chrome:启动耗时与内存占用

实测 headless Chrome 154 的开销:冷启动到调试端口可用中位 396 ms,新开标签页加载简单页面 24 ms;0 个标签页就有 9 个进程、RSS 之和约 1177 MiB,每多一个标签页多一个渲染进程、约 +109 MiB(同一站点与不同站点一样);用 CDP 拦截图片和样式让加载从 31 ms/2052 KiB 降到 13 ms/1 KiB。

爬虫 headless Chrome CDP 启动耗时 内存 标签页 资源拦截 Python 真实验证 动画演示
爬虫工程 2026-10-12

等待策略:固定等待、元素等待、网络空闲

在会随机延迟加载数据的本机页面上比较等待策略:固定等待 0.5 秒只有 5 / 12 成功,1.5 秒成功但多等 916 ms;轮询到期望的元素数量几乎不多等(约 45 ms);只等第一个元素在分两阶段加载的页面上 0 / 12;网络空闲在有长连接的页面上永远等不到(6035 ms 到上限)。

爬虫 等待策略 网络空闲 CDP headless Chrome 动态页面 Python 真实验证 动画演示
爬虫工程 2026-10-12

浏览器复用:每次新开与复用上下文的成本

30 次加载同一页面:每页启动新浏览器 46862 ms(452.1 ms/页),复用浏览器新标签页 2289 ms(38.0 ms/页),独立 context 5232 ms(114.1 ms/页),同一个标签页 1305 ms(5.7 ms/页);默认 context 与同一标签页共享 Cookie 和缓存(29/29 带 Cookie、图片只请求 1 次),独立 context 与新浏览器互相隔离;不关标签页 60 次后 69 个进程、7990 MiB。

爬虫 浏览器复用 browser context 标签页 Cookie隔离 内存 CDP Python 真实验证 动画演示
爬虫工程 2026-10-12

页面能观察到哪些自动化信号:navigator.webdriver 等

在本机 headless Chrome 154 里让页面自己的 JavaScript 读自动化相关的值:只开远程调试端口时 navigator.webdriver 是 false,加 --enable-automation 才是 true(同时视口矮 56 像素);User-Agent 里直接写着 HeadlessChrome;JS 与请求头读到的 UA 一致。本文只描述页面能看到什么,不涉及隐藏办法。

爬虫 浏览器自动化 navigator.webdriver HeadlessChrome CDP User-Agent Python 真实验证 动画演示
爬虫工程 2026-10-12

无限滚动:IntersectionObserver 触发的请求

在本机用 IntersectionObserver 做的无限滚动页面上实测:不滚动只有第 1 页(10 条);匀速滚动并用“连续 3 次没增长”判定到底会在第 40 条提前停下;每次滚到底部拿到全部 100 条(10 次请求);3000 px 的高视口下朴素写法卡在 10 条,加载后重新 observe 才能继续。

爬虫 无限滚动 IntersectionObserver CDP 动态加载 headless Chrome Python 真实验证 动画演示
爬虫工程 2026-10-12

WebSocket 数据源:怎么抓取推送的数据

在本机的 WebSocket 服务器上实测:Chrome 的 CDP Network 事件里能看到握手、发出的帧和收到的帧;websocket-client 直接连时握手头和浏览器的差别;服务器断开后不重连、重连不带 since、重连带 since 分别丢多少数据;不发心跳会被服务器关闭;Origin 校验对库和浏览器各是什么结果。

爬虫 WebSocket CDP Network 重连 心跳 Origin websocket-client Python 真实验证 动画演示
爬虫工程 2026-10-12

CDP 网络事件:不用解析页面直接拿响应体

在本机页面上实测 CDP Network 域:事件顺序、getResponseBody 返回的是解压后的文本(图片是 base64)、必须等到 loadingFinished 才能取、页面跳走后取不到、setBlockedURLs 能挡住图片请求、默认缓冲下 150 个 1 MiB 响应事后只取得到 142 个。

爬虫 CDP Network getResponseBody Chrome headless 屏蔽资源 Python 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号