- 克隆 eze-is/web-access 完整源码 - 创建功能说明网页(架构、API、对比、评估) - 端口 4310 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
853 lines
27 KiB
HTML
853 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Web-Access Skill - 源码解析与功能说明</title>
|
||
<style>
|
||
:root {
|
||
--bg: #0a0a0f;
|
||
--surface: #12121a;
|
||
--surface2: #1a1a26;
|
||
--border: #2a2a3a;
|
||
--text: #e0e0e8;
|
||
--text2: #888899;
|
||
--accent: #6c5ce7;
|
||
--accent2: #a855f7;
|
||
--green: #10b981;
|
||
--orange: #f59e0b;
|
||
--red: #ef4444;
|
||
--blue: #3b82f6;
|
||
--cyan: #06b6d4;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
line-height: 1.7;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
/* Hero */
|
||
.hero {
|
||
position: relative;
|
||
min-height: 50vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
padding: 80px 24px 60px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.hero::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: -50%;
|
||
left: -50%;
|
||
width: 200%;
|
||
height: 200%;
|
||
background: radial-gradient(ellipse at 50% 50%, rgba(108,92,231,0.08) 0%, transparent 60%),
|
||
radial-gradient(ellipse at 20% 80%, rgba(168,85,247,0.06) 0%, transparent 50%);
|
||
animation: drift 20s ease-in-out infinite alternate;
|
||
}
|
||
|
||
@keyframes drift {
|
||
0% { transform: translate(0, 0) rotate(0deg); }
|
||
100% { transform: translate(-30px, 20px) rotate(2deg); }
|
||
}
|
||
|
||
.hero-content { position: relative; z-index: 1; }
|
||
|
||
.hero h1 {
|
||
font-size: clamp(2rem, 5vw, 3.5rem);
|
||
font-weight: 800;
|
||
letter-spacing: -0.03em;
|
||
background: linear-gradient(135deg, #e0e0e8, #a855f7, #6c5ce7);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.hero .subtitle {
|
||
font-size: 1.15rem;
|
||
color: var(--text2);
|
||
max-width: 600px;
|
||
margin: 0 auto 32px;
|
||
}
|
||
|
||
.badge-row {
|
||
display: flex;
|
||
gap: 12px;
|
||
justify-content: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 6px 14px;
|
||
border-radius: 20px;
|
||
font-size: 0.82rem;
|
||
font-weight: 600;
|
||
border: 1px solid var(--border);
|
||
background: var(--surface);
|
||
}
|
||
|
||
.badge .dot {
|
||
width: 8px;
|
||
height: 8px;
|
||
border-radius: 50%;
|
||
display: inline-block;
|
||
}
|
||
|
||
.badge .dot.green { background: var(--green); }
|
||
.badge .dot.orange { background: var(--orange); }
|
||
.badge .dot.blue { background: var(--blue); }
|
||
.badge .dot.purple { background: var(--accent2); }
|
||
|
||
/* Container */
|
||
.container {
|
||
max-width: 1100px;
|
||
margin: 0 auto;
|
||
padding: 0 24px;
|
||
}
|
||
|
||
/* Section */
|
||
section {
|
||
margin-bottom: 64px;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 1.5rem;
|
||
font-weight: 700;
|
||
margin-bottom: 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.section-title .icon {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 1rem;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* Cards */
|
||
.card-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 16px;
|
||
}
|
||
|
||
.card {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 24px;
|
||
transition: border-color 0.2s, transform 0.2s;
|
||
}
|
||
|
||
.card:hover {
|
||
border-color: var(--accent);
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
.card h3 {
|
||
font-size: 1.05rem;
|
||
font-weight: 700;
|
||
margin-bottom: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.card p, .card li {
|
||
font-size: 0.92rem;
|
||
color: var(--text2);
|
||
line-height: 1.7;
|
||
}
|
||
|
||
.card ul {
|
||
list-style: none;
|
||
padding-left: 0;
|
||
}
|
||
|
||
.card ul li::before {
|
||
content: '>';
|
||
color: var(--accent);
|
||
margin-right: 8px;
|
||
font-weight: bold;
|
||
font-family: monospace;
|
||
}
|
||
|
||
/* Architecture diagram */
|
||
.arch-box {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 32px;
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.arch-flow {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0;
|
||
flex-wrap: wrap;
|
||
padding: 16px 0;
|
||
}
|
||
|
||
.arch-node {
|
||
background: var(--surface2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
padding: 16px 20px;
|
||
text-align: center;
|
||
min-width: 140px;
|
||
transition: border-color 0.2s;
|
||
}
|
||
|
||
.arch-node:hover { border-color: var(--accent2); }
|
||
|
||
.arch-node .label {
|
||
font-size: 0.78rem;
|
||
color: var(--text2);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
margin-bottom: 6px;
|
||
}
|
||
|
||
.arch-node .name {
|
||
font-size: 1rem;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.arch-arrow {
|
||
color: var(--accent);
|
||
font-size: 1.3rem;
|
||
padding: 0 12px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* API Table */
|
||
.api-table-wrap {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.api-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.api-table th {
|
||
background: var(--surface2);
|
||
padding: 12px 16px;
|
||
text-align: left;
|
||
font-weight: 700;
|
||
font-size: 0.82rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.05em;
|
||
color: var(--text2);
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
.api-table td {
|
||
padding: 10px 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
vertical-align: top;
|
||
}
|
||
|
||
.api-table tr:last-child td { border-bottom: none; }
|
||
|
||
.api-table tr:hover td { background: rgba(108,92,231,0.04); }
|
||
|
||
.method-badge {
|
||
display: inline-block;
|
||
padding: 2px 8px;
|
||
border-radius: 4px;
|
||
font-size: 0.75rem;
|
||
font-weight: 700;
|
||
font-family: monospace;
|
||
}
|
||
|
||
.method-badge.get { background: rgba(16,185,129,0.15); color: var(--green); }
|
||
.method-badge.post { background: rgba(59,130,246,0.15); color: var(--blue); }
|
||
|
||
code, .mono {
|
||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||
font-size: 0.85em;
|
||
background: var(--surface2);
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
color: var(--cyan);
|
||
}
|
||
|
||
/* File tree */
|
||
.file-tree {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 24px;
|
||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||
font-size: 0.88rem;
|
||
line-height: 2;
|
||
}
|
||
|
||
.file-tree .dir { color: var(--accent2); }
|
||
.file-tree .file { color: var(--text2); }
|
||
.file-tree .comment { color: #555566; font-style: italic; }
|
||
|
||
/* Comparison */
|
||
.compare-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16px;
|
||
}
|
||
|
||
@media (max-width: 700px) {
|
||
.compare-grid { grid-template-columns: 1fr; }
|
||
}
|
||
|
||
.compare-card {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 24px;
|
||
}
|
||
|
||
.compare-card h3 {
|
||
font-size: 1rem;
|
||
font-weight: 700;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.compare-card.highlight {
|
||
border-color: var(--accent);
|
||
background: linear-gradient(135deg, var(--surface), rgba(108,92,231,0.05));
|
||
}
|
||
|
||
.tag {
|
||
display: inline-block;
|
||
padding: 3px 10px;
|
||
border-radius: 6px;
|
||
font-size: 0.78rem;
|
||
font-weight: 600;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.tag.green { background: rgba(16,185,129,0.15); color: var(--green); }
|
||
.tag.red { background: rgba(239,68,68,0.15); color: var(--red); }
|
||
.tag.purple { background: rgba(168,85,247,0.15); color: var(--accent2); }
|
||
|
||
.stat-row {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||
gap: 12px;
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.stat-card {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
padding: 18px;
|
||
text-align: center;
|
||
}
|
||
|
||
.stat-card .num {
|
||
font-size: 1.8rem;
|
||
font-weight: 800;
|
||
background: linear-gradient(135deg, var(--accent), var(--accent2));
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
|
||
.stat-card .label {
|
||
font-size: 0.82rem;
|
||
color: var(--text2);
|
||
margin-top: 4px;
|
||
}
|
||
|
||
/* Philosophy */
|
||
.philosophy-steps {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||
gap: 16px;
|
||
}
|
||
|
||
.step-card {
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 12px;
|
||
padding: 24px;
|
||
position: relative;
|
||
}
|
||
|
||
.step-num {
|
||
position: absolute;
|
||
top: -12px;
|
||
left: 20px;
|
||
background: var(--accent);
|
||
color: white;
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 0.82rem;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.step-card h4 {
|
||
margin-top: 8px;
|
||
margin-bottom: 8px;
|
||
font-size: 0.95rem;
|
||
}
|
||
|
||
.step-card p {
|
||
font-size: 0.85rem;
|
||
color: var(--text2);
|
||
}
|
||
|
||
/* Code block */
|
||
.code-block {
|
||
background: #0d0d15;
|
||
border: 1px solid var(--border);
|
||
border-radius: 10px;
|
||
padding: 20px;
|
||
overflow-x: auto;
|
||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||
font-size: 0.85rem;
|
||
line-height: 1.8;
|
||
color: var(--text2);
|
||
margin: 16px 0;
|
||
}
|
||
|
||
.code-block .kw { color: var(--accent2); }
|
||
.code-block .str { color: var(--green); }
|
||
.code-block .cmt { color: #555566; }
|
||
.code-block .fn { color: var(--cyan); }
|
||
|
||
/* Footer */
|
||
footer {
|
||
border-top: 1px solid var(--border);
|
||
padding: 32px 24px;
|
||
text-align: center;
|
||
color: var(--text2);
|
||
font-size: 0.85rem;
|
||
}
|
||
|
||
footer a {
|
||
color: var(--accent2);
|
||
text-decoration: none;
|
||
}
|
||
|
||
a { color: var(--accent2); text-decoration: none; }
|
||
a:hover { text-decoration: underline; }
|
||
|
||
/* Verdict */
|
||
.verdict-box {
|
||
background: linear-gradient(135deg, var(--surface), rgba(108,92,231,0.06));
|
||
border: 1px solid var(--accent);
|
||
border-radius: 12px;
|
||
padding: 28px;
|
||
}
|
||
|
||
.verdict-box h3 {
|
||
font-size: 1.15rem;
|
||
font-weight: 700;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.verdict-box p, .verdict-box li {
|
||
font-size: 0.92rem;
|
||
color: var(--text2);
|
||
line-height: 1.8;
|
||
}
|
||
|
||
.verdict-box ul {
|
||
padding-left: 20px;
|
||
margin: 8px 0;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- Hero -->
|
||
<header class="hero">
|
||
<div class="hero-content">
|
||
<h1>Web-Access Skill</h1>
|
||
<p class="subtitle">
|
||
Claude Code 联网增强 Skill — 三层通道调度 + CDP 浏览器自动化 + 站点经验积累
|
||
</p>
|
||
<div class="badge-row">
|
||
<span class="badge"><span class="dot green"></span> v2.4.1</span>
|
||
<span class="badge"><span class="dot orange"></span> 1,800+ Stars</span>
|
||
<span class="badge"><span class="dot blue"></span> MIT License</span>
|
||
<span class="badge"><span class="dot purple"></span> by 一泽 Eze</span>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="container">
|
||
|
||
<!-- Stats -->
|
||
<div class="stat-row">
|
||
<div class="stat-card">
|
||
<div class="num">5</div>
|
||
<div class="label">联网通道</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="num">14</div>
|
||
<div class="label">CDP API 端点</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="num">573</div>
|
||
<div class="label">行核心代码</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="num">29</div>
|
||
<div class="label">Commits</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="num">0</div>
|
||
<div class="label">外部依赖</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Architecture -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(108,92,231,0.15)">⚙</span>
|
||
架构总览
|
||
</h2>
|
||
<div class="arch-box">
|
||
<div class="arch-flow">
|
||
<div class="arch-node">
|
||
<div class="label">用户指令</div>
|
||
<div class="name">Claude Code</div>
|
||
</div>
|
||
<div class="arch-arrow">→</div>
|
||
<div class="arch-node" style="border-color:var(--accent)">
|
||
<div class="label">决策层</div>
|
||
<div class="name">SKILL.md</div>
|
||
</div>
|
||
<div class="arch-arrow">→</div>
|
||
<div class="arch-node">
|
||
<div class="label">通道选择</div>
|
||
<div class="name" style="font-size:0.85rem">WebSearch / WebFetch<br>curl / Jina / CDP</div>
|
||
</div>
|
||
<div class="arch-arrow">→</div>
|
||
<div class="arch-node">
|
||
<div class="label">浏览器层</div>
|
||
<div class="name">cdp-proxy.mjs</div>
|
||
</div>
|
||
<div class="arch-arrow">→</div>
|
||
<div class="arch-node" style="border-color:var(--green)">
|
||
<div class="label">目标</div>
|
||
<div class="name">用户 Chrome</div>
|
||
</div>
|
||
</div>
|
||
<p style="text-align:center;color:var(--text2);font-size:0.85rem;margin-top:16px;">
|
||
SKILL.md 提供策略哲学 → AI 自主推理选通道 → CDP Proxy 通过 WebSocket 直连 Chrome
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Core Capabilities -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(16,185,129,0.15)">★</span>
|
||
核心能力
|
||
</h2>
|
||
<div class="card-grid">
|
||
<div class="card">
|
||
<h3>🔌 智能通道调度</h3>
|
||
<p>根据任务场景自动选择最优联网方式:</p>
|
||
<ul>
|
||
<li><strong>WebSearch</strong> — 搜索摘要、关键词结果</li>
|
||
<li><strong>WebFetch</strong> — 已知 URL 定向提取信息</li>
|
||
<li><strong>curl</strong> — 需要原始 HTML/JSON-LD</li>
|
||
<li><strong>Jina</strong> — 网页转 Markdown,省 token</li>
|
||
<li><strong>CDP 浏览器</strong> — 动态页面、登录态</li>
|
||
</ul>
|
||
</div>
|
||
<div class="card">
|
||
<h3>🌐 CDP 浏览器操作</h3>
|
||
<p>直连用户日常 Chrome,天然携带所有登录态。通过 HTTP API 提供:</p>
|
||
<ul>
|
||
<li>新建/关闭 Tab,导航、后退</li>
|
||
<li>执行任意 JavaScript</li>
|
||
<li>JS 点击 + CDP 真实鼠标事件</li>
|
||
<li>文件上传(绕过文件对话框)</li>
|
||
<li>截图(含视频当前帧)</li>
|
||
<li>滚动触发懒加载</li>
|
||
</ul>
|
||
</div>
|
||
<div class="card">
|
||
<h3>⚡ 并行分治</h3>
|
||
<p>多目标任务自动分发子 Agent 并行执行:</p>
|
||
<ul>
|
||
<li>共享一个 Chrome + Proxy</li>
|
||
<li>Tab 级隔离,无竞态风险</li>
|
||
<li>抓取内容不进主 Agent 上下文</li>
|
||
<li>总耗时 ≈ 单任务时长</li>
|
||
</ul>
|
||
</div>
|
||
<div class="card">
|
||
<h3>📚 站点经验积累</h3>
|
||
<p>按域名存储操作经验,跨 session 复用:</p>
|
||
<ul>
|
||
<li>URL 模式、平台特征、已知陷阱</li>
|
||
<li>小红书 xsec_token 机制</li>
|
||
<li>自动匹配目标站点经验</li>
|
||
<li>操作成功后自动更新经验</li>
|
||
</ul>
|
||
</div>
|
||
<div class="card">
|
||
<h3>🎥 媒体提取</h3>
|
||
<p>从 DOM 直取图片/视频 URL,或对视频进行定点截帧分析:</p>
|
||
<ul>
|
||
<li>eval 操控 <video> 元素</li>
|
||
<li>seek 到任意时间点 + screenshot</li>
|
||
<li>图片 URL 直接提取,无需全页截图</li>
|
||
</ul>
|
||
</div>
|
||
<div class="card">
|
||
<h3>🔎 信息核实</h3>
|
||
<p>追溯一手来源而非二手报道:</p>
|
||
<ul>
|
||
<li>政策法规 → 发布机构官网</li>
|
||
<li>企业公告 → 公司官方页面</li>
|
||
<li>学术声明 → 原始论文</li>
|
||
<li>避免循环引证假象</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- File Structure -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(59,130,246,0.15)">📁</span>
|
||
源码结构
|
||
</h2>
|
||
<div class="file-tree">
|
||
<span class="dir">web-access/</span><br>
|
||
<span class="file">SKILL.md</span> <span class="comment">← 核心:联网策略 + 浏览哲学 + API 指引(371 行,AI 的"大脑")</span><br>
|
||
<span class="file">README.md</span> <span class="comment">← 项目说明 + 安装指南</span><br>
|
||
<span class="dir">scripts/</span><br>
|
||
<span class="file">cdp-proxy.mjs</span> <span class="comment">← CDP Proxy 服务器(573 行 JS,零外部依赖)</span><br>
|
||
<span class="file">check-deps.sh</span> <span class="comment">← 环境检查 + 自动启动 Proxy</span><br>
|
||
<span class="file">match-site.sh</span> <span class="comment">← 站点经验匹配脚本</span><br>
|
||
<span class="dir">references/</span><br>
|
||
<span class="file">cdp-api.md</span> <span class="comment">← CDP API 详细参考文档</span><br>
|
||
<span class="dir">site-patterns/</span> <span class="comment">← 站点经验文件(按域名存储)</span><br>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CDP Proxy API -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(6,182,212,0.15)">🚀</span>
|
||
CDP Proxy API — 14 个端点
|
||
</h2>
|
||
<p style="color:var(--text2);margin-bottom:16px;font-size:0.92rem">
|
||
Proxy 监听 <code>localhost:3456</code>,通过 WebSocket 直连 Chrome DevTools Protocol,所有操作通过 curl 调用。
|
||
</p>
|
||
<div class="api-table-wrap">
|
||
<table class="api-table">
|
||
<thead>
|
||
<tr><th>端点</th><th>方法</th><th>功能</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>/health</code></td><td><span class="method-badge get">GET</span></td><td>健康检查,返回连接状态</td></tr>
|
||
<tr><td><code>/targets</code></td><td><span class="method-badge get">GET</span></td><td>列出所有已打开的页面 Tab</td></tr>
|
||
<tr><td><code>/new?url=</code></td><td><span class="method-badge get">GET</span></td><td>创建新后台 Tab(自动等待加载完成)</td></tr>
|
||
<tr><td><code>/close?target=</code></td><td><span class="method-badge get">GET</span></td><td>关闭指定 Tab</td></tr>
|
||
<tr><td><code>/navigate?target=&url=</code></td><td><span class="method-badge get">GET</span></td><td>在已有 Tab 中导航(自动等待加载)</td></tr>
|
||
<tr><td><code>/back?target=</code></td><td><span class="method-badge get">GET</span></td><td>后退一页</td></tr>
|
||
<tr><td><code>/info?target=</code></td><td><span class="method-badge get">GET</span></td><td>获取页面 title / URL / readyState</td></tr>
|
||
<tr><td><code>/eval?target=</code></td><td><span class="method-badge post">POST</span></td><td>执行任意 JS 表达式,支持 async</td></tr>
|
||
<tr><td><code>/click?target=</code></td><td><span class="method-badge post">POST</span></td><td>JS 层面点击(el.click())</td></tr>
|
||
<tr><td><code>/clickAt?target=</code></td><td><span class="method-badge post">POST</span></td><td>CDP 真实鼠标事件(绕过反自动化)</td></tr>
|
||
<tr><td><code>/setFiles?target=</code></td><td><span class="method-badge post">POST</span></td><td>文件上传(绕过文件对话框)</td></tr>
|
||
<tr><td><code>/scroll?target=&y=</code></td><td><span class="method-badge get">GET</span></td><td>滚动页面(触发懒加载,等待 800ms)</td></tr>
|
||
<tr><td><code>/screenshot?target=&file=</code></td><td><span class="method-badge get">GET</span></td><td>截图保存到文件或返回二进制</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Design Philosophy -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(245,158,11,0.15)">💡</span>
|
||
设计哲学
|
||
</h2>
|
||
<p style="color:var(--text2);margin-bottom:20px;font-size:0.92rem">
|
||
<strong>"Skill = 哲学 + 技术事实,不是操作手册。"</strong> 讲清 tradeoff 让 AI 自己选,不替它推理。
|
||
</p>
|
||
<div class="philosophy-steps">
|
||
<div class="step-card">
|
||
<span class="step-num">1</span>
|
||
<h4>拿到请求</h4>
|
||
<p>明确用户要做什么,定义成功标准:什么算完成?需要获取什么信息、达到什么结果?这是后续所有判断的锚点。</p>
|
||
</div>
|
||
<div class="step-card">
|
||
<span class="step-num">2</span>
|
||
<h4>选择起点</h4>
|
||
<p>根据任务性质、平台特征,选最可能直达的方式作为第一步去验证。需要登录态/动态页面 → 直接 CDP。</p>
|
||
</div>
|
||
<div class="step-card">
|
||
<span class="step-num">3</span>
|
||
<h4>过程校验</h4>
|
||
<p>每一步结果都是证据。对照成功标准更新判断。方向错了立即调整,不在同一方式上反复重试。</p>
|
||
</div>
|
||
<div class="step-card">
|
||
<span class="step-num">4</span>
|
||
<h4>完成判断</h4>
|
||
<p>对照成功标准确认完成后才停止。不为了"完整"而浪费代价,也不因为"差不多"而提前放弃。</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Comparison -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(239,68,68,0.15)">⚖</span>
|
||
对比:web-access vs 现有工具
|
||
</h2>
|
||
<div class="compare-grid">
|
||
<div class="compare-card">
|
||
<span class="tag green">已有</span>
|
||
<h3>Claude Code 原生 + Playwright MCP + gptr</h3>
|
||
<ul style="list-style:none;padding:0;font-size:0.9rem;color:var(--text2)">
|
||
<li style="margin-bottom:6px">✓ WebSearch / WebFetch 基础联网</li>
|
||
<li style="margin-bottom:6px">✓ Playwright 完整浏览器自动化</li>
|
||
<li style="margin-bottom:6px">✓ gptr 深度调研出报告</li>
|
||
<li style="margin-bottom:6px">✗ 每次启动全新浏览器,无登录态</li>
|
||
<li style="margin-bottom:6px">✗ 需手动判断该用哪个工具</li>
|
||
<li>✗ 无站点经验积累</li>
|
||
</ul>
|
||
</div>
|
||
<div class="compare-card highlight">
|
||
<span class="tag purple">web-access 增量价值</span>
|
||
<h3>CDP 直连 + 策略调度 + 经验复用</h3>
|
||
<ul style="list-style:none;padding:0;font-size:0.9rem;color:var(--text2)">
|
||
<li style="margin-bottom:6px">★ <strong>直连用户 Chrome 登录态</strong>(核心差异)</li>
|
||
<li style="margin-bottom:6px">★ AI 自主选通道,无需手动指定</li>
|
||
<li style="margin-bottom:6px">★ 站点经验跨 session 复用</li>
|
||
<li style="margin-bottom:6px">★ 零外部依赖,573 行代码</li>
|
||
<li style="margin-bottom:6px">★ 子 Agent 并行分治</li>
|
||
<li>★ 视频截帧分析能力</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Code Highlight -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(168,85,247,0.15)"></></span>
|
||
技术亮点
|
||
</h2>
|
||
<div class="card-grid">
|
||
<div class="card">
|
||
<h3>🔌 零依赖设计</h3>
|
||
<p>整个 CDP Proxy 仅使用 Node.js 原生模块:<code>http</code>、<code>url</code>、<code>fs</code>、<code>net</code>、<code>os</code>。
|
||
Node 22+ 的原生 WebSocket 替代了 <code>ws</code> 模块,做到真正零 <code>npm install</code>。</p>
|
||
</div>
|
||
<div class="card">
|
||
<h3>🔎 自动发现 Chrome 端口</h3>
|
||
<p>不需要用户手动指定端口。自动读取 <code>DevToolsActivePort</code> 文件获取端口和 WebSocket 路径,
|
||
支持 macOS / Linux / Windows 三平台。回退扫描 9222、9229、9333 常用端口。</p>
|
||
</div>
|
||
<div class="card">
|
||
<h3>🛡 防重复启动</h3>
|
||
<p>启动时先用 TCP 探测端口是否被占用。若已有实例运行且健康(<code>/health</code> 返回 ok),静默退出。
|
||
避免多个 Proxy 实例冲突。</p>
|
||
</div>
|
||
<div class="card">
|
||
<h3>📈 站点经验匹配</h3>
|
||
<p><code>match-site.sh</code> 读取用户输入,遍历 <code>site-patterns/*.md</code> 文件,
|
||
用域名 + aliases 做模式匹配,自动输出相关站点经验。跨会话积累,越用越聪明。</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="code-block">
|
||
<span class="cmt">// cdp-proxy.mjs 核心连接逻辑(简化)</span><br>
|
||
<span class="kw">async function</span> <span class="fn">discoverChromePort</span>() {<br>
|
||
<span class="cmt">// 1. 读 DevToolsActivePort 文件获取端口</span><br>
|
||
<span class="kw">for</span> (<span class="kw">const</span> p <span class="kw">of</span> possiblePaths) {<br>
|
||
<span class="kw">const</span> port = <span class="fn">parseInt</span>(fs.<span class="fn">readFileSync</span>(p));<br>
|
||
<span class="kw">if</span> (<span class="kw">await</span> <span class="fn">checkPort</span>(port)) <span class="kw">return</span> { port, wsPath };<br>
|
||
}<br>
|
||
<span class="cmt">// 2. 回退扫描常用端口 [9222, 9229, 9333]</span><br>
|
||
}<br><br>
|
||
<span class="cmt">// HTTP API → CDP WebSocket → Chrome</span><br>
|
||
<span class="kw">function</span> <span class="fn">sendCDP</span>(method, params, sessionId) {<br>
|
||
ws.<span class="fn">send</span>(JSON.<span class="fn">stringify</span>({ id: ++cmdId, method, params, sessionId }));<br>
|
||
}
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Verdict -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<span class="icon" style="background:rgba(108,92,231,0.15)">📋</span>
|
||
评估结论
|
||
</h2>
|
||
<div class="verdict-box">
|
||
<h3>适合安装的场景</h3>
|
||
<ul>
|
||
<li>需要 Claude Code 操作<strong>已登录的网站</strong>(后台管理、社交平台、内部系统)</li>
|
||
<li>经常访问<strong>反爬严格的站点</strong>(小红书、微信公众号等)</li>
|
||
<li>希望联网操作<strong>更智能</strong>,不用手动选 WebFetch 还是 Playwright</li>
|
||
<li>需要<strong>视频截帧分析</strong>或复杂的浏览器交互</li>
|
||
</ul>
|
||
<h3 style="margin-top:16px">不需要安装的场景</h3>
|
||
<ul>
|
||
<li>现有 WebFetch + Playwright + gptr 已满足需求</li>
|
||
<li>不需要操作需登录的网站</li>
|
||
<li>主要做代码开发,联网需求少</li>
|
||
</ul>
|
||
<p style="margin-top:16px;padding:12px 16px;background:rgba(108,92,231,0.08);border-radius:8px;font-size:0.92rem">
|
||
<strong>核心价值:</strong>一句话总结 — web-access 的不可替代优势是<strong>直连用户 Chrome 登录态</strong>。
|
||
其余能力(搜索、抓取、浏览器操作)在现有工具链中已有覆盖,web-access 做的是<strong>更聪明的调度 + 更省心的体验</strong>。
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
</div>
|
||
|
||
<footer>
|
||
<p>
|
||
源码仓库:<a href="https://github.com/eze-is/web-access" target="_blank">eze-is/web-access</a>
|
||
· 作者:<a href="https://github.com/eze-is" target="_blank">一泽 Eze</a>
|
||
· 许可证:MIT
|
||
</p>
|
||
<p style="margin-top:8px;color:#555">研究存档 · 2026-03-27</p>
|
||
</footer>
|
||
|
||
</body>
|
||
</html>
|