Files
universal-crawler/static/index.html
T

215 lines
9.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>通用爬虫系统</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="logo">🕷️ 通用爬虫系统 <span id="version" class="version"></span></div>
<div class="header-right">
<div class="search-box">
<input id="searchInput" placeholder="搜索网址 / 标题 / 任务名..." maxlength="100">
<button id="btnSearch" class="btn sm primary" title="搜索">🔍</button>
</div>
<span class="status-pill" id="statusPill">运行中任务: 0</span>
<button id="btnTheme" class="btn ghost" title="切换日间/夜间主题">☀️</button>
<button id="btnTrash" class="btn ghost" title="回收站">🗑️ 回收站 <span id="trashCount" class="trash-count">0</span></button>
<button id="btnRefresh" class="btn ghost">⟳ 刷新</button>
<button id="btnNew" class="btn primary"> 新建任务</button>
</div>
</header>
<main>
<div class="stats-bar" id="statsBar">
<div class="stat-card"><div class="stat-num" id="stTasks">0</div><div class="stat-label">📋 任务总数</div></div>
<div class="stat-card"><div class="stat-num num-run" id="stRunning">0</div><div class="stat-label">🔄 正在运行</div></div>
<div class="stat-card"><div class="stat-num" id="stRuns">0</div><div class="stat-label">📊 累计运行次数</div></div>
<div class="stat-card"><div class="stat-num num-ok" id="stOk">0</div><div class="stat-label">✅ 成功页面</div></div>
<div class="stat-card"><div class="stat-num num-fail" id="stFail">0</div><div class="stat-label">❌ 失败页面</div></div>
<div class="stat-card"><div class="stat-num" id="stImgs">0</div><div class="stat-label">🖼️ 已爬图片</div></div>
<div class="stat-card"><div class="stat-num" id="stDisk">0</div><div class="stat-label">💾 磁盘占用</div></div>
</div>
<div id="taskList" class="task-grid"></div>
<div id="emptyState" class="empty hidden">
<div class="empty-icon">🕸️</div>
<p>还没有爬取任务</p>
<button id="btnNew2" class="btn primary"> 创建第一个任务</button>
</div>
</main>
<!-- 新建 / 编辑任务弹窗 -->
<div id="taskModal" class="modal-overlay hidden">
<div class="modal">
<div class="modal-head">
<span id="modalTitle">新建爬取任务</span>
<button class="btn ghost sm" data-close></button>
</div>
<div class="tabs" id="modeTabs">
<button class="tab active" data-mode="batch">📄 批量爬取</button>
<button class="tab" data-mode="scheduled">⏰ 定时爬取</button>
<button class="tab" data-mode="auto">🤖 自动爬取</button>
</div>
<form id="taskForm">
<div class="form-body">
<div class="field"><label>项目名称 *</label><input name="name" required placeholder="例如: TPU 评测抓取"></div>
<div class="field"><label>输出目录</label><input name="out_dir" placeholder="留空自动: out/任务ID;可填绝对路径"></div>
<div class="row2">
<div class="field"><label>爬取间隔(秒) 最小</label><input name="delay_min" type="number" min="0.1" step="0.1" value="2"></div>
<div class="field"><label>最大</label><input name="delay_max" type="number" min="0.1" step="0.1" value="5"></div>
</div>
<div class="row2">
<div class="field"><label>单页超时(秒)</label><input name="timeout" type="number" value="60"></div>
<div class="field"><label>失败重试次数</label><input name="retry_count" type="number" value="2"></div>
</div>
<div class="row2">
<div class="field"><label>重试间隔(秒)</label><input name="retry_interval" type="number" value="3"></div>
<div class="field check"><label><input name="crawl_images" type="checkbox"> 爬取图片</label></div>
</div>
<div class="row2">
<div class="field check"><label><input name="notify" type="checkbox"> 完成后邮件通知</label></div>
<div class="field"><label>通知邮箱</label><input name="notify_email" value="wlq@tphai.com"></div>
</div>
<div class="field" id="urlsField">
<label>网址列表(每行一个,# 开头为注释)</label>
<div class="row2" style="align-items:center">
<button type="button" class="btn sm" id="btnImportUrls">📂 导入网址文件(.txt)</button>
<span class="card-line">支持 UTF-8 / GBK 编码,自动去重追加</span>
<input type="file" id="urlFileInput" accept=".txt,.csv,.urls,text/plain" hidden>
</div>
<textarea name="urls" rows="5" placeholder="https://www.example.com/&#10;https://www.example.com/page2"></textarea>
</div>
<div id="scheduleBox" class="hidden box">
<div class="field"><label>首次执行时间(可留空;留空 = 尽快执行;已过的时间将立即执行)</label>
<input name="first_run" type="datetime-local"></div>
<div class="row2">
<div class="field"><label>调度类型</label>
<select name="schedule_type">
<option value="interval">间隔调度(每 N 时间)</option>
<option value="cron">cron 表达式</option>
</select>
</div>
<div class="field check"><label><input name="schedule_enabled" type="checkbox" checked> 启用调度</label></div>
</div>
<div id="intervalBox" class="row2">
<div class="field"><label>每隔</label><input name="interval_value" type="number" value="24"></div>
<div class="field"><label>单位</label>
<select name="interval_unit">
<option value="minutes">分钟</option>
<option value="hours" selected>小时</option>
<option value="days"></option>
</select>
</div>
</div>
<div id="cronBox" class="field hidden">
<label>cron 表达式(分 时 日 月 周,周 0/7=周日)</label>
<input name="cron" placeholder="0 3 * * * 每天凌晨3点">
</div>
</div>
<div id="autoBox" class="hidden box">
<div class="field"><label>起始网址 *(系统将自动发现符合规则的链接并爬取)</label>
<div class="row2">
<input name="seed_url" placeholder="https://example.com/news" style="flex:1">
<button type="button" class="btn sm" id="btnProbe">🧪 试爬取</button>
</div>
</div>
<div class="row2">
<div class="field"><label>包含规则(每行一个,子串或正则)</label>
<textarea name="include" rows="3" placeholder="techpowerup.com/review&#10;/news/"></textarea></div>
<div class="field"><label>排除规则</label>
<textarea name="exclude" rows="3" placeholder="login, signup, /tag/, /forum/"></textarea></div>
</div>
<div class="row2">
<div class="field check"><label><input name="same_domain" type="checkbox" checked> 仅爬同域名</label></div>
<div class="field check"><label><input name="use_regex" type="checkbox"> 规则按正则匹配</label></div>
</div>
<div class="row2">
<div class="field"><label>最大页数</label><input name="max_pages" type="number" value="50"></div>
<div class="field"><label>最大爬取深度</label><input name="max_depth" type="number" value="2"></div>
</div>
</div>
</div>
<div class="modal-foot">
<span id="formHint" class="hint"></span>
<button type="button" class="btn ghost" data-close>取消</button>
<button type="submit" class="btn primary">保存</button>
</div>
</form>
</div>
</div>
<!-- 任务详情弹窗 -->
<div id="detailModal" class="modal-overlay hidden">
<div class="modal wide">
<div class="modal-head">
<span id="detailTitle">任务详情</span>
<button class="btn ghost sm" data-close-detail></button>
</div>
<div id="detailBody"></div>
</div>
</div>
<!-- 搜索结果弹窗 -->
<div id="searchModal" class="modal-overlay hidden">
<div class="modal wide">
<div class="modal-head">
<span>🔍 搜索结果</span>
<button class="btn ghost sm" data-close-search></button>
</div>
<div id="searchBody" class="detail-wrap"></div>
</div>
</div>
<!-- 回收站弹窗 -->
<div id="trashModal" class="modal-overlay hidden">
<div class="modal wide">
<div class="modal-head">
<span>🗑️ 回收站(删除的任务统一在这里,可恢复或彻底删除)</span>
<button class="btn ghost sm" data-close-trash></button>
</div>
<div id="trashBody" class="detail-wrap"></div>
</div>
</div>
<!-- 试爬取结果弹窗 -->
<div id="probeModal" class="modal-overlay hidden">
<div class="modal wide">
<div class="modal-head">
<span>🧪 试爬取结果(规则筛选预览)</span>
<button class="btn ghost sm" data-close-probe></button>
</div>
<div id="probeBody" class="detail-wrap"></div>
</div>
</div>
<!-- 元数据弹窗 -->
<div id="metaModal" class="modal-overlay hidden">
<div class="modal">
<div class="modal-head">
<span>📋 资源操作信息(元数据)</span>
<button class="btn ghost sm" data-close-meta></button>
</div>
<div id="metaBody" class="detail-wrap"></div>
</div>
</div>
<!-- 文件预览弹窗 -->
<div id="previewModal" class="modal-overlay hidden">
<div class="modal wide tall">
<div class="modal-head">
<span id="previewTitle">预览</span>
<button class="btn ghost sm" data-close-preview></button>
</div>
<iframe id="previewFrame" sandbox="allow-same-origin"></iframe>
</div>
</div>
<script src="app.js"></script>
</body>
</html>