真正安全的做法只有一条:不在初始HTML里渲染敏感数据,必须通过fetch动态拉取且接口校验登录态和风控维度。

HTML里写死敏感字段等于直接送爬虫
只要邮箱、手机号、订单号、API路径这些字符串明文出现在 <body> 或 <script> 里,爬虫用 requests.get() + BeautifulSoup 就能秒提——根本不用执行 JS。这不是“可能被爬”,是“必然被爬”。
常见错误包括:
- 把 user_id=123456 硬编码在 <div data-id="123456"> 里
- 在 <script> 中塞内联 JSON:var price = 299.00;
- 用 HTML 注释藏关键信息:<!-- order_no: ABC789 -->
这些全是明文,静态扫描工具一扫就出。
真正安全的做法只有一条:不在初始 HTML 里渲染敏感数据。哪怕只是展示,也得走 fetch 动态拉取,且接口必须校验登录态和风控维度(如设备指纹、请求频率)。
CSS伪元素拼接只防正则,不防真爬虫
用 ::before/::after 把价格拆成几段再拼,确实能绕过 re.findall(r'\d+\.\d+', html) 这类基础正则提取,但对真实爬虫无效。
原因很直接:
- window.getComputedStyle(el, '::before').content 可直接读取伪元素内容
- Puppeteer/Playwright 能完整执行 JS 并获取渲染后 DOM
- 如果拼接逻辑写死在 CSS 里(比如 content: "¥" "2" "9" "9";),爬虫静态解析 CSS 文件就能还原
适用场景仅限于:
- 对抗低配规则爬虫
- 降低自动化采集 ROI
别把它当防线,更别用它处理 user_id、token 这类强敏感字段。
结构混淆(随机 class/id、空标签)对现代解析器基本无效
把 <div class="price">99.9</div> 改成 <div class="cls_8a3f9b2e"><span>9</span><i>9</i><u>.9</u></div>,只能拦住正则硬匹配,对 BeautifulSoup、Cheerio、Playwright 的 DOM API 毫无意义。
立即学习“前端免费学习笔记(深入)”;
现代解析器不依赖 class 名或嵌套深度:
- soup.find(attrs={"data-price": True})["data-price"] 直接命中
- //div[@data-price]/text() XPath 一样能提取
- 注释里的 <!-- price: 99.9 -->,BeautifulSoup 默认解析注释,照样可捕获
真正难防的不是混淆本身,而是混淆与渲染行为之间的耦合点——比如某个 data-* 属性既控制样式又参与 JS 逻辑,删掉它整个页面就错位。这种隐性依赖最容易被忽略,也最能拦住粗粒度解析。
JS动态加载不是保险箱,反而暴露更多线索
把价格改用 fetch('/api/product?id=123') 加载,看似安全,实则把请求路径、参数结构、甚至鉴权方式全摊在 JS 源码里。
容易踩的坑:
- fetch 的 URL 若含固定路径(如 /api/v1/orders),会被静态扫描工具直接发现
- 密钥、token 写在 JS 里(哪怕 base64 编码)= 公开广播;现代反编译工具几秒就能还原
- 没做 Referer / User-Agent 校验的服务端接口,Puppeteer 直接模拟登录后就能复用 session cookie 批量调用
- 前端拼接的完整下载链接(如 `/export?token=${token}&id=${id}`)会被爬虫截获并重放
真正有效的防线只有一条:服务端校验 + 动态生成。爬虫能拿到你所有前端代码,但拿不到数据库查询条件、风控规则、用户会话上下文。关键实操点:
- 敏感字段(如 user_id)不在响应体中明文返回,改用短期 token(如 u_abc123_xxx),服务端解密后查库
- 接口必须校验 Authorization header 或有效 session cookie,拒绝无 referer、高频、低停留的请求
- 导出类操作走服务端生成一次性链接(/download/<uuid>),链接 5 分钟失效且仅限单次访问



















