爬虫被拦截:区分 DNS、TLS、HTTP 与页面错误
按最后有证据支持的阶段定位爬虫故障:DNS、TLS、HTTP 或页面执行。保留真实响应,不凭空推断反机器人规则。
BotBrowser Team
“爬虫被拦截”只是事件标签,不是诊断。名称解析失败、证书错误、HTTP 403 与空白数据面板分别证明不同的事实。BotBrowser 文档介绍配置文件驱动的浏览器表面和自动化配置,但不保证访问权限,也不会取消服务器策略。在改变浏览器、代理或负载之前,应先找到失败请求中最后有证据支持的阶段。能够定位故障、同时保留服务器原因未知,也可以是有效结果。跨运行状态指南区分新建上下文或进程之后的 cookie 保留、快照覆盖与服务器接受。 对于这些厂商相关的 HTTP 响应,Cloudflare 与 DataDome 响应信号区分文档规定的挑战标记与未知的服务器决策。
同一任务从可用数据转为挑战时,采集中途出现 CAPTCHA 的诊断 关联最后可用响应和首个挑战,不把先后顺序认定为原因。
摘要
- 先确定失败的具体请求,而不只看哪张页面像被拦截。文档与数据请求可能有不同结果。
- 区分没有 HTTP 响应和已经收到拒绝。HTTP 403 或 429 仍是响应。
- 分开记录 DNS、连接/TLS 与页面执行错误,任何一项都不能单独识别反机器人模型。
- 命令行请求是另一个客户端的观察,不是浏览器会话的副本。
- 遵守文档规定的访问边界。只有服务文档或获授权的服务器记录才能支持具体规则归因。
目录
- 确定请求与观察窗口
- DNS:名称与 HTTP 响应方不是一回事
- 连接与 TLS:保留真实错误
- HTTP:拒绝仍然是响应
- 页面执行与数据接受
- 五行诊断记录与归因边界
- BotBrowser 配置不是服务器判定
- 实践结论
确定请求与观察窗口
从一个获授权的事件开始,记录集成修订版、浏览器及框架版本、请求角色、时间和脱敏后的路由引用。为事件分配不含敏感信息的标识(如 requestId),方便将浏览器事件与自有服务器记录关联,同时避免泄露凭据。顶层文档、应用数据请求和图片不能互相替代。先说明哪一项失败、所需数据是否被接受,再判断整页结果。 SERP 排名跟踪模型将配置的位置、语言或设备与引擎实际结果上下文分开,并把来源定义的序号与 Search Console 平均排名分别保留。
例如,HTTP 200 文档可能加载应用外壳,而数据请求收到 403。外壳截图不能确定具体哪个请求被拒绝。反过来,装饰图片缺失也不一定使数据记录失效。这些是说明性示例,不是已捕获的交互。应预先定义必需字段或应用结果,再与具体请求及响应关联,不要只凭最终截图判断一次执行。
设定有限观察窗口,保留首次相关故障。不要让库的重试用后续成功或笼统超时覆盖原始事件。明确区分请求未派发、已派发但无响应、已收到响应、应用结果已接受。这些是建议的事件状态,不是新增 HTTP 状态码。lastEstablishedStage 这样的日志字段是本地分类,不能写成服务器提供的解释。
记录两次观察之间的变化。若代理、浏览器版本、应用状态和并发量同时改变,结果变化无法确定是哪一个因素造成的。先保留既有授权配置与故障,只调查一个有边界的问题。不要反复加大流量或更换账号来探查服务限制。证据不足应让原因继续保持未解,不能换成更自信的标签。
DNS:名称与 HTTP 响应方不是一回事
MDN 的 DNS 词条介绍将域名与 IP 地址等资源关联的命名系统。名称无法解析时,尚未确认来自该目的地的 HTTP 响应。单凭这一点不能证明应用拒绝浏览器。应一起保留主机名、解析器上下文和错误类别;输入错误、解析器不可用和策略响应是不同可能,需要各自的证据。
curl 错误参考区分错误 5,即代理名称无法解析,以及错误 6,即远端主机无法解析。使用代理的任务中,代理端点报错并不能证明目标主机名解析失败。保留实际客户端与配置。另一个终端查询成功,不代表失败请求中的浏览器或代理使用了同一个解析器。
本地缓存已有地址,也不同于观察到一次新的解析。记录诊断是否真的执行查询,不要假定每次连接成功都经过新的 DNS 解析。一个耗时数值无法说明解析器内部状态。对于自有服务,可以在同一窗口关联解析器或网关日志;对于外部服务,应保留客户端错误,不要声称观察到不可见的基础设施决策。
下一步可以在获授权环境内检查已配置名称和解析路径。修正明显拼写错误前,仍应保留原始输入。若浏览器外无法复现,应描述差异,而不是认定浏览器指纹负责。DNS 阶段事件还没有提供有关 HTTP 响应内容、状态或策略的证据。
连接与 TLS:保留真实错误
名称解析与连接建立是不同观察。地址已解析,不代表已成功连接配置中的目的地或代理。curl 错误 7 表示连接失败,错误 28 表示操作超时;后者本身不能定位到某一个协议阶段。应保留客户端错误类别和阶段记录,不要把所有连接故障都叫作网站拦截。
MDN 的 TLS 词条介绍通信保护。证书验证错误说明该客户端观察到信任问题,不是 HTTP 授权响应。curl 区分 TLS 连接错误 35 与对端证书验证错误 60。浏览器连接信任分析进一步区分证书与信任边界;不能把每种 TLS 错误都当作指纹检测证据。
对于自有或明确获授权的诊断端点,下面的命令记录一个独立客户端观察。先将 DIAGNOSTIC_URL 设为获许可的 URL。命令执行 GET、丢弃响应体、保留证书验证、限制总时间,不自动跟随重定向或重试。输出只是建议的记录格式,不是成功运行示例:
code=0
curl --disable --silent --show-error --max-time 20 --output /dev/null \
--write-out 'http_code=%{http_code}\ntime_namelookup=%{time_namelookup}\ntime_connect=%{time_connect}\ntime_appconnect=%{time_appconnect}\n' \
"${DIAGNOSTIC_URL:?Set an owned or authorized diagnostic URL}" || code=$?
printf 'curl_exit=%s\n' "$code"
耗时字段是诊断输入,不证明每个命名阶段都重新执行。连接复用和选定路由会影响解释。终端客户端的 cookies、解析器、代理配置及 TLS 行为可能不同于浏览器。因此,一致结果可以佐证共同症状,不一致可以指导调查,但两者都不能让这个命令成为浏览器会话复现。应使用同一声明窗口,并记录客户端身份。
不要添加不安全的证书选项,让诊断看起来成功。对于自有基础设施,应由负责人员检查证书有效性、预期主机名和配置的信任。对于第三方服务,保留故障并使用受支持的接入路径。TLS 连接完成,也不代表下一次 HTTP 请求会获授权或应用会接受数据。
HTTP:拒绝仍然是响应
MDN 的 HTTP 状态参考区分响应类别,包括客户端与服务器错误。观察到 HTTP 403,只说明某个响应方拒绝该请求;没有额外证据,不能识别检测器、指纹不匹配或账号规则。429 是速率限制响应,应单独分类。限流决策记录解释可选 Retry-After 与有限预算调度,不推断服务采用什么计数键。
Playwright 的 requestfailed 事件文档明确区分网络失败与 HTTP 错误响应。收到 404 或 503 仍是 HTTP 响应,单凭状态不会触发 requestfailed。同样的区分可以避免把 403 丢进误导性的网络错误分类。应在获授权动作开始前安装监听器,再分别保存响应状态和请求失败。
下面的记录器挂接到传入的 Playwright Page,不会启动浏览器、导航、重试或改变设置。调用方负责 emit,并应在留存前脱敏错误文本。pageerror 参考提供独立的页面未捕获异常事件:
export function attachDiagnosticListeners(page, emit) {
page.on('response', response =>
emit({
event: 'response',
status: response.status(),
role: response.request().resourceType(),
})
);
page.on('requestfailed', request =>
emit({
event: 'requestfailed',
role: request.resourceType(),
error: request.failure()?.errorText ?? null,
})
);
page.on('pageerror', error =>
emit({
event: 'pageerror',
name: error.name,
})
);
}
事件刻意不保留 URL 和凭据。外围工具仍需添加脱敏的请求关联和时间戳,才能将事件接回事件记录;单个资源类型无法区分多个数据调用。无关请求之间的事件顺序不构成一条因果链。响应事件也只证明响应到达,不证明内容全部接收完毕或应用接受结果。后续结果应另外保存。
页面执行与数据接受
文档响应不是页面执行结论。未捕获异常、资源请求失败、应用字段缺失,是不同观察。应使用独立的 pageerror、requestfailed 与响应记录定位证据,再检查预先声明的数据条件。异常可能中断相关操作,也可能与目标结果无关;单凭存在异常,不能证明反机器人脚本阻止了采集。
对于自有 fixture,应在观察前定义稳定的就绪条件和小型预期记录。对于外部集成,应采用其文档规定的结果契约,不要把可见标题当作成功。HTTP 200 文档可能包含登录界面、服务错误或其他应用状态。保留内容分类及 HTTP 状态,不要修改状态来表达应用结果。
保留足够上下文,将缺失字段与产生它的请求或脚本阶段关联。数据请求可能根本没有派发、收到拒绝,也可能返回了页面未应用的数据。这些情况需要不同调查。选择器超时不能当作已观察的服务器拒绝:它只说明指定窗口内条件未满足,不说明原因。应记录有界等待与实际等待条件。
比较需要相同的应用修订版、初始状态与许可请求顺序。若一次观察已登录,另一次没有该状态,差异并不是浏览器检测证据。将空面板归因于设备信号前,先检查是否具备所需授权会话或操作。不要把私人账号材料放入公开日志;可以用无敏感内容的引用关联受访问控制的操作记录。
五行诊断记录与归因边界
下表前四行描述客户端可观察阶段。第五行涉及服务策略归因,包括声称存在的行为规则;它不是每个请求都会暴露的第五次协议交互。只有服务文档、获授权的支持回复或自有服务器决策记录,才能确定该事件适用的规则。陌生挑战页面或结果变化不能代替这些证据。
| 诊断行 | 保留内容 | 有边界的下一步 |
|---|---|---|
| DNS | 客户端、配置名称、解析器上下文与错误 | 检查对应查询;尚无 HTTP 原因 |
| 连接/TLS | 路由引用、连接或信任错误 | 调查对应阶段,不关闭信任检查 |
| HTTP | 收到响应的请求、状态和选定响应头 | 按文档处理响应,不命名检测器 |
| 脚本/数据 | 异常、资源结果与所需字段 | 定位未满足条件,不重命名响应 |
| 服务策略 | 文档规则或 cause=unknown | 询问负责人员;无许可则停止 |
把观察和解释放在不同字段中。httpStatus=403 是观察值;即使已定位响应,cause=unknown 仍可能是正确原因。“可能是行为评分”是未确认假设,不是事实列。若后续服务器证据识别了访问规则,应补充引用与时间,不要改写原始浏览器记录。
自有服务器记录也必须匹配事件。应关联请求标识、时间窗口、资源和作答组件;网关拒绝与应用拒绝可能是不同决策。通用规则文档解释可能策略,匹配的决策记录解释某一次响应。若第三方集成没有该记录,应保持更窄结论,使用受支持的访问或支持渠道,不要探查不可见的决策逻辑。
BotBrowser 配置不是服务器判定
BotBrowser 自动化一致性文档介绍配置文件驱动的设置与框架配置。指纹概览介绍由配置文件系统控制的浏览器引擎表面。这些是配置能力,不是服务器拒绝请求的解释。应在事件中保留二进制、配置文件引用及框架设置,但不能把配置意图当作经过验证的远端结果。
仅改变浏览器表面,不能证明 DNS 已修复、证书已受信任或服务配额允许下一次请求。代理设置改变声明路由;改变之后结果不同,不能揭示原始拒绝原因。应保留原始观察,在已定位的层寻找证据。已配置的浏览器既不提供授权,也不承诺应用接受结果。
常见问题
403 能证明指纹检测吗?
不能。它是 HTTP 拒绝。识别规则需要服务端证据或与该请求相关的文档解释,不能靠猜测检测器名称。
HTTP 错误等于 Playwright 请求失败吗?
不能仅凭状态判断。Playwright 区分收到 HTTP 响应与无法获得响应。应保留两种事件及其对应请求。
curl 成功能证明浏览器应该工作吗?
不能。curl 是另一个具有独立状态和配置的客户端。结果可以佐证观察,但不能复现浏览器会话。
可见挑战足以识别行为规则吗?
不能。保留可见状态、响应与请求顺序。没有负责服务提供的证据,策略原因仍然未知。
来源
- MDN:HTTP 响应状态码
- MDN:DNS
- MDN:TLS
- curl:错误码
- curl:命令行选项
- Playwright:requestfailed 事件
- Playwright:pageerror 事件
- BotBrowser:自动化一致性
- BotBrowser:指纹概览
- 浏览器连接信任
- 采集限流决策
实践结论
先定位失败请求,保留最后有证据支持的阶段。改变设置前,区分 DNS 或 TLS 故障、HTTP 拒绝和页面数据条件未满足。没有负责来源支持时,服务策略归因应保持未知。下一步是保留响应或错误,在获授权集成内调查那个具体阶段,不要把笼统的拦截消息变成虚构的检测器结论。
本文属于指南: 代理配置总览:浏览器网络决策图