关于 profile-website-bot-detection
用于检查目标网站的反机器人检测情况,识别供应商、产品和挑战类型。它通过隐身与普通浏览器模式的对照分析,帮助评估网站防护表现。
主要功能
- 01识别反机器人供应商与产品
- 02检测挑战类型和拦截情况
- 03分析首页及登录页
- 04对比隐身与普通浏览器
- 05生成 JSON 报告和截图
适用场景
- 01调查网站采用的反机器人服务
- 02比较不同浏览器模式的检测结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ kernel/ skills --skill profile-website-bot-detection安装后在 Claude Code 中输入/profile-website-bot-detection确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/.gitignorepackage.jsontest-kernel-bot-detection.ts详细介绍
Bot 检测供应商网站分析
分析目标网站,识别 Bot 检测供应商、其具体产品和挑战类型。支持比较隐身与非隐身浏览器模式。
前提条件
- 已安装并完成身份验证的 Kernel CLI
- 已安装 Bash、Node.js 22+ 和
jq - 已为分析脚本导出
KERNEL_API_KEY;切勿打印该密钥,也不要要求用户将其粘贴到聊天中
对比工作流(推荐)
在控制网络路径的同时,比较隐身与非隐身浏览器的 Bot 检测行为。在同一个 Bash 进程中运行步骤 1-7,以确保清理 trap 始终生效。不要将步骤 2 作为独立的非交互式 shell 运行:该 shell 返回时,其 EXIT trap 会删除会话。
步骤 1:准备分析器
在创建计费的浏览器会话之前安装依赖项:
cd scripts
npm install # first run only
export TARGET_URL='https://example.com'
test -n "${KERNEL_API_KEY:-}" || { echo "KERNEL_API_KEY is not set" >&2; exit 1; }
步骤 2:创建两种浏览器会话并启用清理
使用 JSON 输出获取准确的会话 ID。如果第二个会话创建失败或后续分析失败,EXIT trap 会清理第一个会话。
set -euo pipefail
STEALTH_ID=
NORMAL_ID=
cleanup() {
local ids=()
[[ -n "${STEALTH_ID:-}" ]] && ids+=("$STEALTH_ID")
[[ -n "${NORMAL_ID:-}" ]] && ids+=("$NORMAL_ID")
if ((${#ids[@]})); then
kernel browsers delete "${ids[@]}" || true
fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
STEALTH_ID=$(kernel browsers create --stealth --viewport 1920x1080@25 --timeout 300 --output json | jq -er '.session_id')
NORMAL_ID=$(kernel browsers create --viewport 1920x1080@25 --timeout 300 --output json | jq -er '.session_id')
# Isolate browser stealth behavior: route the stealth session directly, like the normal session.
kernel browsers update "$STEALTH_ID" --disable-default-proxy >/dev/null
否则,隐身会话将使用 Kernel 的默认隐身代理,而普通会话将直接连接。若不执行更新,测量结果反映的是隐身 + 代理与普通 + 直连的差异,而非单纯的隐身效果。仅对隐身会话应用 --disable-default-proxy;API 不允许对非隐身会话使用该选项。
导航前,选择一种网络设计:
- 浏览器模式对比(推荐): 保留上述更新,让两个会话都直接连接。
- 平台默认设置对比: 省略更新,并将隐身结果报告为
stealth + default proxy;不要将差异归因于隐身本身。 - 显式代理对比: 可选择使用
kernel proxies check "$PROXY_ID" --url https://example.com --output json验证已配置的代理,在两个创建命令中都添加--proxy-id "$PROXY_ID",并省略更新。这样可以控制代理配置,但代理提供商轮换仍可能导致出口 IP 不同。
步骤 3:在两种浏览器上运行分析
KERNEL_BROWSER_ID="$STEALTH_ID" TARGET_URL="$TARGET_URL" BROWSER_MODE=stealth npm run analyze
KERNEL_BROWSER_ID="$NORMAL_ID" TARGET_URL="$TARGET_URL" BROWSER_MODE=normal npm run analyze
每次分析器运行都会在写入报告后断开本地 CDP 客户端;Kernel 会话仍保持活动状态,以便进行对比和清理。
步骤 4:对比结果
对比每种模式下最新的报告,不要将多个 JSON 文档拼接在一起:
# Derive the same hostname folder used by the analyzer (e.g., chase.com -> chase-com).
HOST=$(node -e 'const host = new URL(process.env.TARGET_URL).hostname; console.log(host.replace(/^www\./, "").replace(/\./g, "-"))')
latest_report() {
local reports=("$1"/report-*.json)
[[ -e "${reports[0]}" ]] || return 1
printf '%s\n' "${reports[@]}" | sort | tail -n 1
}
STEALTH_REPORT=$(latest_report "output/$HOST/stealth")
NORMAL_REPORT=$(latest_report "output/$HOST/normal")
echo "=== STEALTH VERDICT ===" && jq '.summary.verdict' "$STEALTH_REPORT"
echo "=== NORMAL VERDICT ===" && jq '.summary.verdict' "$NORMAL_REPORT"
echo "=== STEALTH BLOCKED ===" && jq '.summary | {isBlocked, blockedPages, blockedVendors}' "$STEALTH_REPORT"
echo "=== NORMAL BLOCKED ===" && jq '.summary | {isBlocked, blockedPages, blockedVendors}' "$NORMAL_REPORT"
echo "=== STEALTH VENDORS ===" && jq '.summary.vendorNames' "$STEALTH_REPORT"
echo "=== NORMAL VENDORS ===" && jq '.summary.vendorNames' "$NORMAL_REPORT"
步骤 5:解读对比结果
| 场景 | 隐身 | 普通 | 含义 |
|---|---|---|---|
| 未检测到供应商 | 0 | 0 | 未观察到信号;不要据此认为网站没有 Bot 检测 |
| 检测到相同供应商,未拦截 | N | N | 存在 Bot 检测,两个会话均通过 |
| 普通浏览器被拦截,隐身通过 | 0 次拦截 | 已拦截 | 在网络受控的情况下,隐身模式有效 |
| 两者均被拦截 | 已拦截 | 已拦截 | 两种受测配置均被拦截 |
| 挑战类型不同 | 较轻 | 较难 | 在网络受控的情况下,隐身模式可能降低了可疑程度 |
步骤 6:提供摘要
完成对比分析后,明确说明网络设计。只有当两个会话使用相同网络类别时,才能声称隐身模式有效。
摘要报告模板:
## Bot Detection Comparative Analysis: [TARGET_URL]
### Verdict
- **Network Design**: [both direct / same explicit proxy config / platform defaults]
- **Stealth Browser**: [verdict from summary.verdict]
- **Normal Browser**: [verdict from summary.verdict]
- **Stealth Effectiveness**: [Effective/Ineffective/Inconclusive; use Inconclusive for mixed network paths]
### Block Status
| Browser | Blocked | Block Type | Evidence |
|---------|---------|------------|----------|
| Stealth | [Yes/No] | [blockType or N/A] | [first evidence item] |
| Normal | [Yes/No] | [blockType or N/A] | [first evidence item] |
### Detected Vendors
| Vendor | Stealth | Normal | Products |
|--------|---------|--------|----------|
| [vendor] | ✓/✗ | ✓/✗ | [product list] |
### Analysis
- [Explain what the results mean]
- [Note any differences between stealth and normal]
- [Recommend next steps if blocked]
### Key Findings
1. [Finding 1]
2. [Finding 2]
3. [Finding 3]
使用 JSON 报告填写此模板:
summary.verdict- 最终判定字符串summary.isBlocked- 浏览器是否被拦截summary.blockedPages- 被拦截页面的详细信息summary.vendorNames- 检测到的供应商列表vendorDetections- 供应商/产品详细信息
步骤 7:清理
收集报告后立即删除两个会话。browsers delete 是非交互式命令,支持多个 ID;它没有 -y 标志。
cleanup
trap - EXIT INT TERM
如果 shell 被中断或变量丢失,请使用 kernel browsers list 查找创建的会话,并使用 kernel browsers delete <session-id> 分别删除。
结果解读
分析会检测供应商及其特定产品:
| 供应商 | 检测到的产品 |
|---|---|
| Akamai | Bot Manager、Bot Manager Premier、mPulse RUM、Sensor Script、Edge DNS |
| Cloudflare | Bot Management、Turnstile、Challenge Platform、JS Challenge、Managed Challenge |
| DataDome | Interstitial Challenge、Slider Challenge、Device Check、Picasso Fingerprint |
| HUMAN/PerimeterX | Bot Defender、Sensor SDK、Press & Hold Challenge |
| Imperva/Incapsula | Advanced Bot Protection (utmvc)、Advanced Bot Protection (reese84)、WAF |
| Kasada | IPS (Initial Page Security)、FP (Fingerprint Endpoint)、Telemetry、POW Challenge |
| reCAPTCHA v2、reCAPTCHA v3、reCAPTCHA Enterprise | |
| hCaptcha | Widget、Enterprise |
| FingerprintJS | Fingerprint Pro、BotD |
| Arkose Labs | FunCaptcha |
检测方法:
- 根据供应商脚本和端点的 URL 模式进行匹配
- 分析 Cookie(例如,
_abck、__cf_bm、datadome、_px*) - 检测标头(例如,
cf-ray、x-kpsdk-*、x-d-token) - 根据响应状态码检测质询
供应商专属检查:
- DataDome:检测硬性 IP 封锁(
dd.t === 'bv') - Akamai:检查 Cookie 是否有效(
~0~指示符) - Kasada:检测流程类型(IPS 或 FP)
分析的页面
脚本会自动分析:
- 主页 - 初始页面加载和机器人检测脚本
- 登录页 - 通过链接检测或常见路径(
/login、/signin等)自动发现
登录页通常会采用更严格的机器人检测,以防止凭据填充攻击。
输出文件
结果按目标主机名整理,存放在 scripts/output/<hostname>/<mode>/ 中:
report-<timestamp>.json- 包含供应商检测结果的完整 JSON 报告screenshot-homepage-<timestamp>.png- 主页截图screenshot-login-<timestamp>.png- 登录页截图(如果找到)
以 chase.com 的对比测试为例:
output/chase-com/
├── stealth/
│ ├── report-*.json
│ ├── screenshot-homepage-*.png
│ └── screenshot-login-*.png
└── normal/
├── report-*.json
├── screenshot-homepage-*.png
└── screenshot-login-*.png
JSON 报告包含:
summary:快速查看判定结果、封锁状态和供应商名称verdict:易于理解的结果(例如,“已封锁 - 主页(错误页面)”)isBlocked:布尔值 - 如果任一页面被封锁,则为 truevendorNames:检测到的供应商名称数组blockedPages:包含证据的已封锁页面详情
vendorDetections:已检测供应商的映射,包含产品、URL、Cookie 和标头blockDetections:每个页面的详细封锁分析vendorScriptsDetected:检测到的供应商脚本 URL(未保存到磁盘)networkRequests/networkResponses:所有经过供应商匹配的请求cookies:所有 Cookie 及其对应的供应商
供应商专属检测说明
Akamai
- Cookie:
_abck(核心验证)、bm_sz、bm_sv _abck值中的 Cookie~0~= 会话有效
Cloudflare
- Cookie:
__cf_bm、cf_clearance - 质询:
/cdn-cgi/challenge-platform/ - Turnstile:
challenges.cloudflare.com/turnstile
DataDome
- Cookie:
datadome dd.t === 'bv'= 硬性 IP 封锁(需要更换 IP,解决验证码也无济于事)
HUMAN/PerimeterX
- Cookie:
_px2、_px3、_pxhd - Press & Hold 质询需要进行行为模拟
Imperva/Incapsula
- utmvc:通过
/_Incapsula_Resource提供的脚本 - reese84:Cookie 或
x-d-token标头
Kasada
- 标头:
x-kpsdk-ct、x-kpsdk-cd - 流程 1(IPS):初始页面加载时返回 429,必须先解决
ips.js - 流程 2(FP):后台
/fp指纹请求