Files
tvboxzt/spider_validation.html
T
2026-05-19 09:56:47 +08:00

563 lines
95 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Spider 校验 HTML 报告</title>
<style>
:root {
color-scheme: light;
--bg: #eef3f1;
--panel: #ffffff;
--text: #102027;
--muted: #57707d;
--accent: #0f766e;
--accent-soft: #d7f3ee;
--danger: #b42318;
--danger-soft: #fde7e4;
--border: #d8e3df;
--shadow: 0 16px 40px rgba(16, 32, 39, 0.08);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Segoe UI", "PingFang SC", "Noto Sans SC", sans-serif;
background:
radial-gradient(circle at top left, rgba(15, 118, 110, 0.12), transparent 28%),
linear-gradient(180deg, #f7faf9 0%, var(--bg) 100%);
color: var(--text);
}
a {
color: var(--accent);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.page {
width: min(1600px, calc(100vw - 32px));
margin: 0 auto;
padding: 24px 0 40px;
}
.hero {
display: grid;
gap: 18px;
margin-bottom: 18px;
padding: 24px;
border: 1px solid rgba(15, 118, 110, 0.16);
border-radius: 20px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.96), rgba(231, 245, 241, 0.96));
box-shadow: var(--shadow);
}
.hero h1 {
margin: 0;
font-size: clamp(30px, 5vw, 42px);
line-height: 1.05;
letter-spacing: -0.03em;
}
.hero p {
margin: 0;
color: var(--muted);
font-size: 15px;
}
.summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px;
}
.summary-card {
padding: 14px 16px;
border: 1px solid var(--border);
border-radius: 16px;
background: rgba(255, 255, 255, 0.84);
}
.summary-card span {
display: block;
font-size: 12px;
color: var(--muted);
margin-bottom: 6px;
}
.summary-card strong {
font-size: 24px;
letter-spacing: -0.03em;
}
.panel {
margin-top: 18px;
padding: 20px;
border: 1px solid var(--border);
border-radius: 20px;
background: var(--panel);
box-shadow: var(--shadow);
}
.panel h2 {
margin: 0 0 12px;
font-size: 18px;
}
.filters {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
align-items: end;
}
.filter {
display: grid;
gap: 6px;
}
.filter label {
font-size: 12px;
font-weight: 600;
color: var(--muted);
}
.filter input,
.filter select,
.filter button {
width: 100%;
min-height: 42px;
padding: 10px 12px;
border: 1px solid var(--border);
border-radius: 12px;
background: #fff;
color: var(--text);
font: inherit;
}
.filter button {
background: var(--accent);
color: #fff;
border-color: var(--accent);
cursor: pointer;
font-weight: 600;
}
.filter button:hover {
filter: brightness(0.97);
}
#summary-line {
margin: 14px 0 0;
color: var(--muted);
font-size: 14px;
}
.table-wrap {
overflow: auto;
border: 1px solid var(--border);
border-radius: 16px;
}
table {
width: 100%;
min-width: 1300px;
border-collapse: collapse;
background: #fff;
}
thead {
background: #f4faf8;
}
th,
td {
padding: 12px 14px;
border-bottom: 1px solid var(--border);
vertical-align: top;
text-align: left;
font-size: 13px;
}
td {
line-height: 1.45;
word-break: break-word;
}
th button {
all: unset;
display: inline-flex;
align-items: center;
gap: 6px;
cursor: pointer;
font-weight: 700;
color: var(--text);
}
th button .sort-indicator {
color: var(--muted);
font-size: 11px;
}
.status {
display: inline-flex;
align-items: center;
padding: 4px 10px;
border-radius: 999px;
font-weight: 700;
font-size: 12px;
white-space: nowrap;
}
.status.success {
color: var(--accent);
background: var(--accent-soft);
}
.status.failed {
color: var(--danger);
background: var(--danger-soft);
}
.empty {
padding: 28px 14px;
text-align: center;
color: var(--muted);
}
@media (max-width: 768px) {
.page {
width: min(100vw - 20px, 1600px);
padding-top: 16px;
}
.hero,
.panel {
padding: 16px;
border-radius: 16px;
}
}
</style>
</head>
<body>
<div class="page">
<section class="hero">
<div>
<h1>Spider 校验 HTML 报告</h1>
<p>本地静态报告,支持前端即时筛选与表头排序。</p>
</div>
<div class="summary-grid">
<div class="summary-card"><span>生成时间</span><strong id="generated-at"></strong></div>
<div class="summary-card"><span>并发线程</span><strong id="max-workers"></strong></div>
<div class="summary-card"><span>总数</span><strong id="total-count"></strong></div>
<div class="summary-card"><span>成功</span><strong id="success-count"></strong></div>
<div class="summary-card"><span>失败</span><strong id="failed-count"></strong></div>
<div class="summary-card"><span>总耗时</span><strong id="total-duration"></strong></div>
</div>
</section>
<section class="panel">
<h2>筛选</h2>
<div class="filters">
<div class="filter">
<label for="status-filter">状态</label>
<select id="status-filter"></select>
</div>
<div class="filter">
<label for="stage-filter">失败阶段</label>
<select id="stage-filter"></select>
</div>
<div class="filter">
<label for="keyword-filter">爬虫名 / 文件名关键字</label>
<input id="keyword-filter" type="search" placeholder="例如 alpha / 4K指南" />
</div>
<div class="filter">
<label for="duration-min-filter">最小耗时(ms)</label>
<input id="duration-min-filter" type="number" min="0" />
</div>
<div class="filter">
<label for="duration-max-filter">最大耗时(ms)</label>
<input id="duration-max-filter" type="number" min="0" />
</div>
<div class="filter">
<label for="reset-filters">操作</label>
<button id="reset-filters" type="button">重置筛选</button>
</div>
</div>
<p id="summary-line">当前显示 0 / 0 条</p>
</section>
<section class="panel">
<h2>明细结果</h2>
<div class="table-wrap">
<table>
<thead>
<tr>
<th><button type="button" data-sort-key="spider">爬虫 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="status">状态 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="failed_stage">失败阶段 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="total">总耗时 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="module_load">模块加载 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="init">初始化 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="home">首页分类 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="category">分类列表 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="detail">视频详情 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="player">播放地址 <span class="sort-indicator"></span></button></th>
<th><button type="button" data-sort-key="url_check">地址校验 <span class="sort-indicator"></span></button></th>
<th>返回地址</th>
<th>错误信息</th>
</tr>
</thead>
<tbody id="results-body"></tbody>
</table>
</div>
</section>
</div>
<script>
const report = {"generated_at": "2026-05-19T09:28:09+08:00", "max_workers": 16, "total_duration_ms": 25855.309, "summary": {"total": 77, "success": 65, "failed": 12, "success_rate": 0.8442, "stage_failures": {"module_load": 0, "init": 0, "home": 1, "category": 3, "detail": 1, "player": 1, "url_check": 1, "unexpected": 5}}, "results": [{"spider": "4K指南", "file": "4K指南.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 214.326, "init": 0.001, "home": 0.001, "category": 1097.52, "detail": 532.871, "player": 0.007, "url_check": 166.702, "total": 2014.09}, "counts": {"classes": 5, "category_videos": 50, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "zuixin", "vod_id": "20143", "flag": "夸克网盘", "play_id": "push://https://pan.quark.cn/s/e31f935ac678"}, "player": {"parse": 0, "url": "https://pan.quark.cn/s/e31f935ac678", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.quark.cn/s/e31f935ac678", "reason": null}}, {"spider": "6V磁力", "file": "6V磁力.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 221.618, "init": 0.003, "home": 0.001, "category": 952.405, "detail": 711.12, "player": 0.002, "url_check": 0.06, "total": 1895.311}, "counts": {"classes": 12, "category_videos": 18, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "dianshiju/guoju", "vod_id": "/dianshiju/guoju/28782.html", "flag": "01-06.1080p.HD国语中字无水印.mkv", "play_id": "magnet:?xt=urn:btih:043850fa85bd56c572dabbb0351e63086a471b37&dn=%E5%AE%B6%E4%B8%9A01-06"}, "player": {"parse": 0, "url": "magnet:?xt=urn:btih:043850fa85bd56c572dabbb0351e63086a471b37&dn=%E5%AE%B6%E4%B8%9A01-06", "valid": true, "reachable": null, "status_code": null, "final_url": "magnet:?xt=urn:btih:043850fa85bd56c572dabbb0351e63086a471b37&dn=%E5%AE%B6%E4%B8%9A01-06", "reason": "非 HTTP 地址,按协议格式通过"}}, {"spider": "AAZ音乐", "file": "AAZ音乐.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 218.749, "init": 0.001, "home": 813.711, "category": 205.489, "detail": 222.977, "player": 207.71, "url_check": 921.717, "total": 2600.948}, "counts": {"classes": 6, "category_videos": 60, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "new", "vod_id": "song:e0f3c77fa564632f924f77fc5943ba7e", "flag": "AAZ音乐", "play_id": "song:e0f3c77fa564632f924f77fc5943ba7e"}, "player": {"parse": 0, "url": "https://s.5bb3.com/m4a/3374e5b4a4d9d8e8f967976747b5c2ca.m4a", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://lv-sycdn.kuwo.cn/045f53f6f4ce5a176a9ffdffb156b393/6a0bbcab/resource/1307392909/trackmedia/C200000W91kQ0efKLA.m4a?from=vip", "reason": null}}, {"spider": "PPnix", "file": "PPnix.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 259.271, "init": 0.001, "home": 0.001, "category": 818.066, "detail": 641.786, "player": 0.017, "url_check": 401.582, "total": 2121.364}, "counts": {"classes": 2, "category_videos": 24, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "1", "vod_id": "movie/8187.html", "flag": "PPnix", "play_id": "8187|1080P"}, "player": {"parse": 0, "url": "https://www.ppnix.com/info/m3u8/8187/1080P.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://www.ppnix.com/info/m3u8/8187/1080P.m3u8", "reason": null}}, {"spider": "QQ音乐", "file": "QQ音乐.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 214.026, "init": 0.011, "home": 0.007, "category": 1108.124, "detail": 1261.027, "player": 333.581, "url_check": 131.032, "total": 3064.742}, "counts": {"classes": 6, "category_videos": 30, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "playlist", "vod_id": "playlist:9634517813", "flag": "QQ音乐", "play_id": "qqmusic:0014qLXa1JrJ11:618693022|偏向 (摇滚版) - 孟维来"}, "player": {"parse": 0, "url": "https://isure.stream.qqmusic.qq.com/F0000014qLXa1JrJ11.flac?guid=e1159a1922bee56fec2e33e4d08e7f78&vkey=68DC18C4F122FBB690D01411EB5DB1923DD748056550E8D7A8D42CC7EE712D11F1A4E44142F410EB3AFAB919321491542979F800E3741285__v2ba83db9&uin=896389745&fromtag=119114&redirect=1", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://isure.stream.qqmusic.qq.com/F0000014qLXa1JrJ11.flac?guid=e1159a1922bee56fec2e33e4d08e7f78&vkey=68DC18C4F122FBB690D01411EB5DB1923DD748056550E8D7A8D42CC7EE712D11F1A4E44142F410EB3AFAB919321491542979F800E3741285__v2ba83db9&uin=896389745&fromtag=119114&redirect=1", "reason": null}}, {"spider": "YouTube", "file": "YouTube.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 214.287, "init": 0.003, "home": 0.044, "category": 728.505, "detail": 1555.566, "player": 0.004, "url_check": 802.218, "total": 3302.967}, "counts": {"classes": 29, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "cat_recommend", "vod_id": "yt:video:E3jcQgR3TNE", "flag": "YouTube", "play_id": "yt:video:E3jcQgR3TNE"}, "player": {"parse": 0, "url": "https://www.youtube.com/watch?v=E3jcQgR3TNE", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://www.youtube.com/watch?v=E3jcQgR3TNE", "reason": null}}, {"spider": "libvio", "file": "libvio.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 214.416, "init": 0.001, "home": 0.001, "category": 405.342, "detail": 243.352, "player": 0.004, "url_check": 203.944, "total": 1081.409}, "counts": {"classes": 6, "category_videos": 48, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "index", "vod_id": "714893455", "flag": "夸克", "play_id": "https://pan.quark.cn/s/8002c3155d07"}, "player": {"parse": 0, "url": "https://pan.quark.cn/s/8002c3155d07", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.quark.cn/s/8002c3155d07", "reason": null}}, {"spider": "youknow", "file": "youknow.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 218.15, "init": 0.001, "home": 0.001, "category": 2107.696, "detail": 1506.195, "player": 1511.148, "url_check": 1247.948, "total": 6618.376}, "counts": {"classes": 7, "category_videos": 222, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "index", "vod_id": "201640", "flag": "YouKnowTV", "play_id": "eyJ2b2RfaWQiOiIyMDE2NDAiLCJlcGlzb2RlX2luZGV4IjoxLCJ0aXRsZSI6IuesrDAx6ZuGIiwiY2FuZGlkYXRlcyI6W3sic291cmNlIjoi57q_6LevMSIsInNvdXJjZV9pZCI6IjEiLCJlcGlzb2RlX3VybCI6Imh0dHBzOi8vd3d3LnlvdWtub3cudHYvcC8yMDE2NDAtMS0xLyJ9LHsic291cmNlIjoi57q_6LevMiIsInNvdXJjZV9pZCI6IjEiLCJlcGlzb2RlX3VybCI6Imh0dHBzOi8vd3d3LnlvdWtub3cudHYvcC8yMDE2NDAtMS0xLyJ9LHsic291cmNlIjoi57q_6LevMjEiLCJzb3VyY2VfaWQiOiIzIiwiZXBpc29kZV91cmwiOiJodHRwczovL3d3dy55b3Vrbm93LnR2L3AvMjAxNjQwLTMtMS8ifSx7InNvdXJjZSI6Iue6v-i3rzIyIiwic291cmNlX2lkIjoiMyIsImVwaXNvZGVfdXJsIjoiaHR0cHM6Ly93d3cueW91a25vdy50di9wLzIwMTY0MC0zLTEvIn0seyJzb3VyY2UiOiLnur_ot68zOSIsInNvdXJjZV9pZCI6IjIiLCJlcGlzb2RlX3VybCI6Imh0dHBzOi8vd3d3LnlvdWtub3cudHYvcC8yMDE2NDAtMi0xLyJ9LHsic291cmNlIjoi57q_6LevNDAiLCJzb3VyY2VfaWQiOiIyIiwiZXBpc29kZV91cmwiOiJodHRwczovL3d3dy55b3Vrbm93LnR2L3AvMjAxNjQwLTItMS8ifV19"}, "player": {"parse": 0, "url": "https://vip.dytt-cinema.com/20260203/47632_dea5d272/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vip.dytt-cinema.com/20260203/47632_dea5d272/index.m3u8", "reason": null}}, {"spider": "七味", "file": "七味.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 218.18, "init": 0.006, "home": 0.011, "category": 973.428, "detail": 1065.784, "player": 0.003, "url_check": 959.693, "total": 3244.359}, "counts": {"classes": 5, "category_videos": 42, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "492461", "flag": "百度1", "play_id": "https://pan.baidu.com/s/1MZa4NhXR02WdMOXlmINHCA?pwd=Yu66"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1MZa4NhXR02WdMOXlmINHCA?pwd=Yu66", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=MZa4NhXR02WdMOXlmINHCA&pwd=Yu66", "reason": null}}, {"spider": "不太灵", "file": "不太灵.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 215.452, "init": 0.0, "home": 675.564, "category": 1015.779, "detail": 615.758, "player": 0.008, "url_check": 210.771, "total": 4139.44}, "counts": {"classes": 5, "category_videos": 25, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "2", "vod_id": "37517110", "flag": "夸克", "play_id": "https://pan.quark.cn/s/42496bdc1e22"}, "player": {"parse": 0, "url": "https://pan.quark.cn/s/42496bdc1e22", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.quark.cn/s/42496bdc1e22", "reason": null}}, {"spider": "世纪音乐", "file": "世纪音乐.txt", "success": false, "failed_stage": "detail", "error": "详情缺少播放源或播放列表", "traceback": null, "timings_ms": {"module_load": 215.776, "init": 0.001, "home": 289.376, "category": 0.006, "detail": 136.734, "player": 0.0, "url_check": 0.0, "total": 781.787}, "counts": {"classes": 5, "category_videos": 3, "detail_videos": 1, "episodes": 0}, "samples": {"tid": "rank_list", "vod_id": "rank:rise", "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "两个BT", "file": "两个BT.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 220.11, "init": 0.0, "home": 0.001, "category": 584.875, "detail": 353.89, "player": 1453.317, "url_check": 557.734, "total": 3191.92}, "counts": {"classes": 14, "category_videos": 24, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "zgjun", "vod_id": "ch45ofqjh", "flag": "两个BT", "play_id": "eyJwaWQiOiIvcGxheS9jaDQ1b2ZxamgiLCJzaWQiOiJjaDQ1b2ZxamgiLCJuYW1lIjoiMSJ9"}, "player": {"parse": 0, "url": "https://zijieapi.douyinbyte.com/m3u8/72bb913953a8f347623ae8efd4cdba07.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://zijieapi.douyinbyte.com/m3u8/72bb913953a8f347623ae8efd4cdba07.m3u8", "reason": null}}, {"spider": "乌云影视", "file": "乌云影视.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 214.693, "init": 0.001, "home": 746.415, "category": 1124.314, "detail": 1192.849, "player": 0.062, "url_check": 778.474, "total": 10948.25}, "counts": {"classes": 7, "category_videos": 24, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "tv_series", "vod_id": "41042", "flag": "乌云影视", "play_id": "eyJtZWRpYUlkIjogIjQxMDQyIiwgInNlYXNvbk5vIjogMSwgImVwTm8iOiAxLCAidmlkZW9JZCI6IDc2MjEyLCAicGxheVVybCI6ICJodHRwczovL2QxamRubWtjMW41Y240LmNsb3VkZnJvbnQubmV0L2dlbl9vdmVyc2Vhcy9odHRwczovL2MxLnJyY2RuYmYyLmNvbS92aWRlby9zaG91d2FuZy_nrKwwMembhi9pbmRleC5tM3U4IiwgIm5hbWUiOiAi56ysMembhiDnrKwwMembhiJ9"}, "player": {"parse": 0, "url": "https://d1jdnmkc1n5cn4.cloudfront.net/gen_overseas/https://c1.rrcdnbf2.com/video/shouwang/第01集/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://d1jdnmkc1n5cn4.cloudfront.net/hls_overseas/6adaa6110de8cabe312451a50055602af6cfe012.m3u8", "reason": null}}, {"spider": "乐兔", "file": "乐兔.txt", "success": false, "failed_stage": "category", "error": "分类视频列表为空", "traceback": null, "timings_ms": {"module_load": 213.814, "init": 0.001, "home": 0.001, "category": 395.265, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 1257.605}, "counts": {"classes": 5, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "2", "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "二小", "file": "二小.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 213.655, "init": 0.001, "home": 0.001, "category": 728.801, "detail": 449.175, "player": 0.003, "url_check": 1133.037, "total": 2534.885}, "counts": {"classes": 4, "category_videos": 72, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "12226", "flag": "百度#二小", "play_id": "https://pan.baidu.com/s/1nuKDps3ixTI-stgxEWmp0A?pwd=uvie"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1nuKDps3ixTI-stgxEWmp0A?pwd=uvie", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=nuKDps3ixTI-stgxEWmp0A&pwd=uvie", "reason": null}}, {"spider": "人人电影", "file": "人人电影.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 211.695, "init": 0.001, "home": 0.001, "category": 680.614, "detail": 443.454, "player": 0.008, "url_check": 1150.728, "total": 2495.01}, "counts": {"classes": 4, "category_videos": 10, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "movie/list_2", "vod_id": "/movie/2026/0519/59249.html", "flag": "baidu", "play_id": "https://pan.baidu.com/s/1-ogwcHCbBFqXVxAfM3L1OQ?pwd=mb2t"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1-ogwcHCbBFqXVxAfM3L1OQ?pwd=mb2t", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=-ogwcHCbBFqXVxAfM3L1OQ&pwd=mb2t", "reason": null}}, {"spider": "人人视频", "file": "人人视频.txt", "success": false, "failed_stage": "url_check", "error": "HTTP 403", "traceback": null, "timings_ms": {"module_load": 7.321, "init": 0.001, "home": 232.675, "category": 295.78, "detail": 251.783, "player": 462.624, "url_check": 191.995, "total": 11457.995}, "counts": {"classes": 4, "category_videos": 30, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "MOVIE", "vod_id": "57211", "flag": "人人专线", "play_id": "57211@382620"}, "player": {"parse": 0, "url": "https://tfw01gr3demttga51hctt8rzdkpy.ourdvsssvip.com:20443/ws-302.bwcgee.cn/b094c6a436ee71f180c25017f1f80402/27056b4bf10d471aa8e51fc2aaf0d9ca-73d47d4ebafc028edeb6d2ade7663231-ld.mp4?key=b2ac062193da121283e27ca1bb41b82d&time=1779168501861&clientType=web_pc&clientVersion=1.0.0&parseUsage=PLAY&uid=0&rk=4eecd5f6647749d7926eb4e6270c2da1&hevc=false&seasonId=57211&wsiphost=ipdbme&wsrid_tag=6a0bbcb6_PS-CTU-01tJO23_25092-22269-s1t1779154102052&x-mamba-business-label=13551&redirect_cnt=0&ip_type=0&wshc=C&requery=0", "valid": false, "reachable": false, "status_code": 403, "final_url": "https://tfw01gr3demttga51hctt8rzdkpy.ourdvsssvip.com:20443/ws-302.bwcgee.cn/b094c6a436ee71f180c25017f1f80402/27056b4bf10d471aa8e51fc2aaf0d9ca-73d47d4ebafc028edeb6d2ade7663231-ld.mp4?key=b2ac062193da121283e27ca1bb41b82d&time=1779168501861&clientType=web_pc&clientVersion=1.0.0&parseUsage=PLAY&uid=0&rk=4eecd5f6647749d7926eb4e6270c2da1&hevc=false&seasonId=57211&wsiphost=ipdbme&wsrid_tag=6a0bbcb6_PS-CTU-01tJO23_25092-22269-s1t1779154102052&x-mamba-business-label=13551&redirect_cnt=0&ip_type=0&wshc=C&requery=0", "reason": "HTTP 403"}}, {"spider": "优酷", "file": "优酷.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 8.13, "init": 0.001, "home": 0.001, "category": 329.733, "detail": 636.719, "player": 0.003, "url_check": 271.401, "total": 1246.518}, "counts": {"classes": 6, "category_videos": 23, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "电视剧", "vod_id": "show:afcb2d65c6a34b798d77", "flag": "优酷", "play_id": "https://v.youku.com/v_show/id_XNjUzNDA5NDEwNA==.html"}, "player": {"parse": 1, "url": "https://v.youku.com/v_show/id_XNjUzNDA5NDEwNA==.html", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://v.youku.com/v_show/id_XNjUzNDA5NDEwNA==.html", "reason": null}}, {"spider": "低端影视", "file": "低端影视.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 10.005, "init": 0.001, "home": 0.001, "category": 1101.455, "detail": 1402.943, "player": 0.008, "url_check": 521.691, "total": 3036.575}, "counts": {"classes": 4, "category_videos": 24, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "series", "vod_id": "movie/outlander-season-8", "flag": "播放源 1 (1080P)", "play_id": "https://v.lzcdn27.com/20260307/6382_5f68feb7/index.m3u8"}, "player": {"parse": 0, "url": "https://v.lzcdn27.com/20260307/6382_5f68feb7/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://v.lzcdn27.com/20260307/6382_5f68feb7/index.m3u8", "reason": null}}, {"spider": "修罗", "file": "修罗.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 8.033, "init": 0.001, "home": 0.001, "category": 807.979, "detail": 981.093, "player": 2015.242, "url_check": 1059.681, "total": 4873.003}, "counts": {"classes": 4, "category_videos": 24, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "movie", "vod_id": "kongbu/3777", "flag": "修罗直连", "play_id": "play/3777-0"}, "player": {"parse": 0, "url": "https://v.xlys.ltd.ua/obj/3DD45AD47B814F9565ED03A910C91EA6F2C7C12A23980340754AFFA5CA460066", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://lf26-imcloud-file-sign.bytetos.com/ad-penny-bucket/o0EEIAAAt4uBCWDq8FAdfNTiQIzRVEAgCeOhCd?x-expires=1779159238&x-signature=JfxmnhpesRFgcYl6gFcT7n0VQwU%3D", "reason": null}}, {"spider": "凡客TV", "file": "凡客TV.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.756, "init": 0.001, "home": 0.001, "category": 1373.096, "detail": 1257.915, "player": 1930.617, "url_check": 3844.816, "total": 8412.59}, "counts": {"classes": 8, "category_videos": 32, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "e5097aa6ea2b5ab4", "flag": "高速线路", "play_id": "{\"movie_id\":\"e5097aa6ea2b5ab4\",\"link_id\":\"12ffd07b10b25943ad7c7c5fb6bb3147\",\"line_id\":\"line1\",\"line_name\":\"高速线路\",\"episode_name\":\"1080p\",\"type\":\"switch\",\"page\":\"https://fktv.me/movie/detail/e5097aa6ea2b5ab4\"}"}, "player": {"parse": 0, "url": "https://fktv.me/ysapi/m3u8/p/a2265a51ffeb9f84d656c1568f866839.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://fktv.me/ysapi/m3u8/p/a2265a51ffeb9f84d656c1568f866839.m3u8", "reason": null}}, {"spider": "剧圈圈", "file": "剧圈圈.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.225, "init": 0.001, "home": 0.001, "category": 1455.027, "detail": 748.063, "player": 2128.041, "url_check": 669.808, "total": 5006.663}, "counts": {"classes": 5, "category_videos": 16, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "dianying", "vod_id": "61813", "flag": "BF备用", "play_id": "play/61813-3-1"}, "player": {"parse": 1, "url": "https://www.jqqzx.cc/play/61813-3-1.html", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://www.jqqzx.one/play/61813-3-1.html", "reason": null}}, {"spider": "剧迷", "file": "剧迷.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 16.109, "init": 0.001, "home": 0.001, "category": 265.387, "detail": 437.247, "player": 441.881, "url_check": 1217.994, "total": 2379.122}, "counts": {"classes": 6, "category_videos": 150, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "443094", "flag": "高清线路 ᴴᴰ", "play_id": "443094-11-1"}, "player": {"parse": 0, "url": "https://play.phimgood.com/20260511/26651_2f4d94b1/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://play.phimgood.com/20260511/26651_2f4d94b1/index.m3u8", "reason": null}}, {"spider": "博看听书", "file": "博看听书.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 6.63, "init": 0.001, "home": 3231.695, "category": 281.893, "detail": 803.362, "player": 0.004, "url_check": 296.781, "total": 4620.916}, "counts": {"classes": 11, "category_videos": 24, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "1319", "vod_id": "902849", "flag": "博看听书", "play_id": "http://audio.bookan.com.cn/video1/audio/20200706001/aache64_133068a2.m4a"}, "player": {"parse": 0, "url": "http://audio.bookan.com.cn/video1/audio/20200706001/aache64_133068a2.m4a", "valid": true, "reachable": true, "status_code": 200, "final_url": "http://audio.bookan.com.cn/video1/audio/20200706001/aache64_133068a2.m4a", "reason": null}}, {"spider": "双星", "file": "双星.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.498, "init": 376.84, "home": 0.003, "category": 194.653, "detail": 193.251, "player": 0.002, "url_check": 183.281, "total": 953.22}, "counts": {"classes": 7, "category_videos": 15, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "ju", "vod_id": "/ju/10461.html", "flag": "夸克", "play_id": "https://pan.quark.cn/s/f5c012103055"}, "player": {"parse": 0, "url": "https://pan.quark.cn/s/f5c012103055", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.quark.cn/s/f5c012103055", "reason": null}}, {"spider": "听书", "file": "听书.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 13.465, "init": 81.353, "home": 0.001, "category": 225.385, "detail": 2559.581, "player": 323.634, "url_check": 173.026, "total": 3377.021}, "counts": {"classes": 11, "category_videos": 10, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "6", "vod_id": "63", "flag": "直链", "play_id": "2926931|||63"}, "player": {"parse": 0, "url": "http://audiopay.cos.tx.xmcdn.com/download/1.0.0/storages/b817-audiopay/16/AA/GKwRIaIGGaRGADgE-gEx_hMS-aacv2-48K.m4a?sign=f1e83b11258f0bc7f9d9600e67fd8202&buy_key=FM&token=8627&timestamp=1779154095&duration=453", "valid": true, "reachable": true, "status_code": 200, "final_url": "http://audiopay.cos.tx.xmcdn.com/download/1.0.0/storages/b817-audiopay/16/AA/GKwRIaIGGaRGADgE-gEx_hMS-aacv2-48K.m4a?sign=f1e83b11258f0bc7f9d9600e67fd8202&buy_key=FM&token=8627&timestamp=1779154095&duration=453", "reason": null}}, {"spider": "听友FM", "file": "听友FM.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 8.186, "init": 0.001, "home": 502.876, "category": 316.224, "detail": 812.804, "player": 540.072, "url_check": 235.596, "total": 2416.98}, "counts": {"classes": 8, "category_videos": 20, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "46", "vod_id": "9783312385", "flag": "听友FM", "play_id": "9783312385|1"}, "player": {"parse": 0, "url": "https://file.hgeuz.cn/stream/eJwANwDI_wJVZgVKIIrU0ECux-GJ1PSt38ahythCqsH-r9TAQ4rj5F94rOjbQKjk063xyIX2z3hfeGcIHF4BAAD__5DtISY.?ts=1779152004&sign=ed8cddf1847280d8b0db94df8a14c688", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://file.hgeuz.cn/stream/eJwANwDI_wJVZgVKIIrU0ECux-GJ1PSt38ahythCqsH-r9TAQ4rj5F94rOjbQKjk063xyIX2z3hfeGcIHF4BAAD__5DtISY.?ts=1779152004&sign=ed8cddf1847280d8b0db94df8a14c688", "reason": null}}, {"spider": "咕咕动漫", "file": "咕咕动漫.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 8.929, "init": 0.006, "home": 606.822, "category": 552.163, "detail": 426.109, "player": 1480.361, "url_check": 295.73, "total": 3370.736}, "counts": {"classes": 3, "category_videos": 30, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "6", "vod_id": "4993", "flag": "咕咕新线(国内高速)", "play_id": "parse_api=a2796a09189261bcaf3cc4542d7c5ac2&url=vC3JvwfizISFocml/iaZMgd1trHAYekCw+0xsYBueVGqQACTAukjD3I2F/niiuEK&token=|木头风纪委员和迷你裙JK的故事|1"}, "player": {"parse": 0, "url": "https://p3-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/dba4cb7929b54de1a195e5b3cc139e3c~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1810258095&x-signature=xiOrvNbfcmPhRwFDp78FYwX3fAs%3D", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://p3-bot-workflow-sign.byteimg.com/tos-cn-i-mdko3gqilj/dba4cb7929b54de1a195e5b3cc139e3c~tplv-mdko3gqilj-image.image?rk3s=81d4c505&x-expires=1810258095&x-signature=xiOrvNbfcmPhRwFDp78FYwX3fAs%3D", "reason": null}}, {"spider": "四万影视", "file": "四万影视.txt", "success": false, "failed_stage": "unexpected", "error": "HTTPSConnectionPool(host='40000.me', port=443): Max retries exceeded with url: /api/maccms?ac=detail&t=20&pg=1&by=time (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1081)')))", "traceback": "Traceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 464, in _make_request\n self._validate_conn(conn)\n ~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 1093, in _validate_conn\n conn.connect()\n ~~~~~~~~~~~~^^\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connection.py\", line 796, in connect\n sock_and_verified = _ssl_wrap_socket_and_match_hostname(\n sock=sock,\n ...<14 lines>...\n assert_fingerprint=self.assert_fingerprint,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connection.py\", line 975, in _ssl_wrap_socket_and_match_hostname\n ssl_sock = ssl_wrap_socket(\n sock=sock,\n ...<8 lines>...\n tls_in_tls=tls_in_tls,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/ssl_.py\", line 483, in ssl_wrap_socket\n ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)\nssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1081)\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 787, in urlopen\n response = self._make_request(\n conn,\n ...<10 lines>...\n **response_kw,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 488, in _make_request\n raise new_e\nurllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1081)\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/requests/adapters.py\", line 645, in send\n resp = conn.urlopen(\n method=request.method,\n ...<9 lines>...\n chunked=chunked,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 841, in urlopen\n retries = retries.increment(\n method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/retry.py\", line 535, in increment\n raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nurllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='40000.me', port=443): Max retries exceeded with url: /api/maccms?ac=detail&t=20&pg=1&by=time (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1081)')))\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 716, in validate_spider_file\n _validate_from_tid(\n ~~~~~~~~~~~~~~~~~~^\n spider=spider,\n ^^^^^^^^^^^^^^\n ...<6 lines>...\n logger=logger,\n ^^^^^^^^^^^^^^\n )\n ^\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 412, in _validate_from_tid\n category_result = _run_timed(result[\"timings_ms\"], \"category\", spider.categoryContent, clock, tid, \"1\", False, {})\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 291, in _run_timed\n return func(*args, **kwargs)\n File \"/home/harold/workspace/tvbox-resources/py/四万影视.txt\", line 238, in categoryContent\n File \"/home/harold/workspace/tvbox-resources/py/四万影视.txt\", line 212, in _api_get\nrequests.exceptions.SSLError: HTTPSConnectionPool(host='40000.me', port=443): Max retries exceeded with url: /api/maccms?ac=detail&t=20&pg=1&by=time (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1081)')))\n", "timings_ms": {"module_load": 4.918, "init": 0.001, "home": 0.001, "category": 727.196, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 737.406}, "counts": {"classes": 5, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "20", "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "在线之家", "file": "在线之家.txt", "success": false, "failed_stage": "unexpected", "error": "Exceeded 30 redirects.", "traceback": "Traceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 716, in validate_spider_file\n _validate_from_tid(\n ~~~~~~~~~~~~~~~~~~^\n spider=spider,\n ^^^^^^^^^^^^^^\n ...<6 lines>...\n logger=logger,\n ^^^^^^^^^^^^^^\n )\n ^\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 412, in _validate_from_tid\n category_result = _run_timed(result[\"timings_ms\"], \"category\", spider.categoryContent, clock, tid, \"1\", False, {})\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 291, in _run_timed\n return func(*args, **kwargs)\n File \"/home/harold/workspace/tvbox-resources/py/在线之家.txt\", line 301, in categoryContent\n File \"/home/harold/workspace/tvbox-resources/py/在线之家.txt\", line 245, in _request_html\nrequests.exceptions.TooManyRedirects: Exceeded 30 redirects.\n", "timings_ms": {"module_load": 5.418, "init": 0.001, "home": 0.0, "category": 7229.505, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 7236.714}, "counts": {"classes": 6, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "1", "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "多多", "file": "多多.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.072, "init": 0.001, "home": 0.001, "category": 500.987, "detail": 411.345, "player": 0.006, "url_check": 1120.508, "total": 2038.492}, "counts": {"classes": 6, "category_videos": 72, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "9461", "flag": "百度#多多", "play_id": "https://pan.baidu.com/s/1pwIj24HVw6lpAUcUrJE-QQ?pwd=yyds"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1pwIj24HVw6lpAUcUrJE-QQ?pwd=yyds", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=pwIj24HVw6lpAUcUrJE-QQ&pwd=yyds", "reason": null}}, {"spider": "如意资源", "file": "如意资源.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.803, "init": 0.001, "home": 0.007, "category": 840.615, "detail": 799.898, "player": 0.004, "url_check": 2008.28, "total": 3653.427}, "counts": {"classes": 6, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "77518", "flag": "rym3u8", "play_id": "https://svip.ryiplay18.com/20260518/6539_d4527565/index.m3u8"}, "player": {"parse": 0, "url": "https://svip.ryiplay18.com/20260518/6539_d4527565/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://svip.ryiplay18.com/20260518/6539_d4527565/index.m3u8", "reason": null}}, {"spider": "寻川4K", "file": "寻川4K.txt", "success": false, "failed_stage": "unexpected", "error": "'NoneType' object is not iterable", "traceback": "Traceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 716, in validate_spider_file\n _validate_from_tid(\n ~~~~~~~~~~~~~~~~~~^\n spider=spider,\n ^^^^^^^^^^^^^^\n ...<6 lines>...\n logger=logger,\n ^^^^^^^^^^^^^^\n )\n ^\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 428, in _validate_from_tid\n detail_result = _run_timed(result[\"timings_ms\"], \"detail\", spider.detailContent, clock, [vod_id])\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 291, in _run_timed\n return func(*args, **kwargs)\n File \"/home/harold/workspace/tvbox-resources/py/寻川4K.txt\", line 810, in detailContent\nTypeError: 'NoneType' object is not iterable\n", "timings_ms": {"module_load": 10.62, "init": 485.872, "home": 971.846, "category": 487.875, "detail": 513.499, "player": 0.0, "url_check": 0.0, "total": 2470.574}, "counts": {"classes": 9, "category_videos": 20, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "1", "vod_id": "581873", "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "布布影视", "file": "布布影视.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 8.169, "init": 0.001, "home": 0.001, "category": 963.309, "detail": 736.988, "player": 1274.638, "url_check": 459.5, "total": 3443.255}, "counts": {"classes": 4, "category_videos": 24, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "69765", "flag": "JD蓝光(1)", "play_id": "JD4K@1@JD-5f4f247d6dfbc0b5d5cb1efeaa2303790"}, "player": {"parse": 0, "url": "https://c167-obsdaz-ykj-01.obs.dualstack.cidc-rp-2006.joint.cmecloud.cn/1810c8ff2a78456b9348fadfe7ab0fd0086?response-content-disposition=attachment%3B%20filename%2A%3DUTF-8%27%274K.mp4&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20260519T012817Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Credential=AH4RWOMWLEL7ROYSF2S5%2F20260519%2Fcidc-rp-2006%2Fs3%2Faws4_request&t=2&u=1261698636582652615&ot=family&oi=1263000283947275586&f=FibTFWRt8ncqZsYDWQP5LF5BI3oB5_LXK&ext=eyJ1dCI6MX0%3D&X-Amz-Signature=498b99c57b64e7a8415f8a2392ddeba51932be6e369b4be78dcd5dae896e5aab", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://c167-obsdaz-ykj-01.obs.dualstack.cidc-rp-2006.joint.cmecloud.cn/1810c8ff2a78456b9348fadfe7ab0fd0086?response-content-disposition=attachment%3B%20filename%2A%3DUTF-8%27%274K.mp4&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20260519T012817Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Credential=AH4RWOMWLEL7ROYSF2S5%2F20260519%2Fcidc-rp-2006%2Fs3%2Faws4_request&t=2&u=1261698636582652615&ot=family&oi=1263000283947275586&f=FibTFWRt8ncqZsYDWQP5LF5BI3oB5_LXK&ext=eyJ1dCI6MX0%3D&X-Amz-Signature=498b99c57b64e7a8415f8a2392ddeba51932be6e369b4be78dcd5dae896e5aab", "reason": null}}, {"spider": "微观短剧", "file": "微观短剧.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.518, "init": 0.014, "home": 280.057, "category": 256.433, "detail": 915.07, "player": 0.002, "url_check": 369.876, "total": 1828.129}, "counts": {"classes": 30, "category_videos": 30, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "都市", "vod_id": "110000044555935694", "flag": "1080P", "play_id": "https://tv-video.cdn.drama.9ddm.com/22/A0/22A0BFFF46651CC23355B115F6307653.mp4?timestamp=1779154095&sign=7668f7011e99cb8c8813554330c48abc"}, "player": {"parse": 0, "url": "https://tv-video.cdn.drama.9ddm.com/22/A0/22A0BFFF46651CC23355B115F6307653.mp4?timestamp=1779154095&sign=7668f7011e99cb8c8813554330c48abc", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://tv-video.cdn.drama.9ddm.com/22/A0/22A0BFFF46651CC23355B115F6307653.mp4?timestamp=1779154095&sign=7668f7011e99cb8c8813554330c48abc", "reason": null}}, {"spider": "新韩剧网", "file": "新韩剧网.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.332, "init": 0.001, "home": 0.0, "category": 605.268, "detail": 411.287, "player": 389.075, "url_check": 1973.175, "total": 3384.036}, "counts": {"classes": 5, "category_videos": 16, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "1", "vod_id": "3613", "flag": "在线云播", "play_id": "3613_1_1"}, "player": {"parse": 0, "url": "https://player.yzzyvip-35.com/20260331/3348_333cb763/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://player.yzzyvip-35.com/20260331/3348_333cb763/index.m3u8", "reason": null}}, {"spider": "星星短剧", "file": "星星短剧.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.832, "init": 0.0, "home": 0.001, "category": 565.933, "detail": 656.099, "player": 0.002, "url_check": 226.656, "total": 1453.304}, "counts": {"classes": 5, "category_videos": 10, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "1287", "vod_id": "422599939194881@@穿越诡计爱上你@@苏清韵为了给妹妹治病,卖身富豪被卓熙辰所救,答应卓熙辰的契约婚姻。苏清韵受到了爱慕卓熙辰的上官溪玲的疯狂攻击与算计,导致妹妹离世。苏清韵误会记恨卓熙辰因此拿刀伤了他,自己也被判入狱五年。", "flag": "星星短剧", "play_id": "https://img.novel.wsljf.xyz/shortPlay-mp4/420424102051841/EvnIm1746774634078/abc6208e-390b-4533-a1a4-b9e5741cc384/540x960/output.m3u8"}, "player": {"parse": 0, "url": "https://img.novel.wsljf.xyz/shortPlay-mp4/420424102051841/EvnIm1746774634078/abc6208e-390b-4533-a1a4-b9e5741cc384/540x960/output.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://img.novel.wsljf.xyz/shortPlay-mp4/420424102051841/EvnIm1746774634078/abc6208e-390b-4533-a1a4-b9e5741cc384/540x960/output.m3u8", "reason": null}}, {"spider": "木偶", "file": "木偶.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.825, "init": 0.001, "home": 0.001, "category": 411.324, "detail": 225.487, "player": 0.016, "url_check": 339.172, "total": 981.399}, "counts": {"classes": 7, "category_videos": 72, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "25", "vod_id": "7940", "flag": "115#木偶", "play_id": "https://115cdn.com/s/swf2juc36dh?password=p8e4"}, "player": {"parse": 0, "url": "https://115cdn.com/s/swf2juc36dh?password=p8e4", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://115cdn.com/s/swf2juc36dh?password=p8e4", "reason": null}}, {"spider": "樱花动漫", "file": "樱花动漫.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.724, "init": 0.001, "home": 0.0, "category": 2368.505, "detail": 1395.876, "player": 1370.006, "url_check": 1108.823, "total": 6248.651}, "counts": {"classes": 4, "category_videos": 36, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "guoman", "vod_id": "17950", "flag": "高清", "play_id": "/play/17950-1-1/"}, "player": {"parse": 0, "url": "https://cdn.vvvip-plays33.cc/20251122/49_f457c545/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://cdn.vvvip-plays33.cc/20251122/49_f457c545/index.m3u8", "reason": null}}, {"spider": "橘子TV", "file": "橘子TV.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.159, "init": 726.174, "home": 474.669, "category": 367.127, "detail": 540.44, "player": 1311.579, "url_check": 1171.178, "total": 4599.926}, "counts": {"classes": 8, "category_videos": 18, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "50", "vod_id": "399092", "flag": "一起看APP", "play_id": "25430680"}, "player": {"parse": 0, "url": "https://usaydd.5gwcft9h.com/m3u87/share/7434749/7628489/20260514/154832/1080/index.m3u8?sign=79c463f6e039c8b287258ab0fc342b69&t=1779154099", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://usaydd.5gwcft9h.com/m3u87/share/7434749/7628489/20260514/154832/1080/index.m3u8?sign=79c463f6e039c8b287258ab0fc342b69&t=1779154099", "reason": null}}, {"spider": "欧歌", "file": "欧歌.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.771, "init": 0.0, "home": 0.001, "category": 476.109, "detail": 383.807, "player": 0.011, "url_check": 193.53, "total": 1058.589}, "counts": {"classes": 6, "category_videos": 72, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "1", "vod_id": "30028", "flag": "夸克", "play_id": "https://pan.quark.cn/s/624b1470bf6a"}, "player": {"parse": 0, "url": "https://pan.quark.cn/s/624b1470bf6a", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.quark.cn/s/624b1470bf6a", "reason": null}}, {"spider": "沐辞4K", "file": "沐辞4K.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 7.327, "init": 146.8, "home": 193.164, "category": 129.37, "detail": 137.806, "player": 136.913, "url_check": 216.972, "total": 968.82}, "counts": {"classes": 7, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "398492", "flag": "🔥蓝光🔥", "play_id": "YYNB-03d250f5f587db3cd9229d2024013ef9@@@YYNB"}, "player": {"parse": 0, "url": "https://fffan.wki8.com/hls/5e9ef89222f83d8521eeb57faad58e65.m3u8?token=3204395f1cbf61c1712a107cfcbc2646&time=1779154097&YYNB.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://fffan.wki8.com/hls/5e9ef89222f83d8521eeb57faad58e65.m3u8?token=3204395f1cbf61c1712a107cfcbc2646&time=1779154097&YYNB.m3u8", "reason": null}}, {"spider": "河马短剧", "file": "河马短剧.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.618, "init": 0.001, "home": 424.777, "category": 742.658, "detail": 1007.999, "player": 0.031, "url_check": 99.587, "total": 2281.67}, "counts": {"classes": 10, "category_videos": 10, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "462", "vod_id": "41000194161", "flag": "河马剧场", "play_id": "https://dzzt-video.cbread.cn/2ec25863cc840803bc445d3a69836110/6a0cf980/90/1x6/16x1/161x4/16149100014/612735109_1/612735109.720p.narrowv3.mp4"}, "player": {"parse": 0, "url": "https://dzzt-video.cbread.cn/2ec25863cc840803bc445d3a69836110/6a0cf980/90/1x6/16x1/161x4/16149100014/612735109_1/612735109.720p.narrowv3.mp4", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://dzzt-video.cbread.cn/2ec25863cc840803bc445d3a69836110/6a0cf980/90/1x6/16x1/161x4/16149100014/612735109_1/612735109.720p.narrowv3.mp4", "reason": null}}, {"spider": "清沅4K", "file": "清沅4K.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 7.153, "init": 361.305, "home": 686.33, "category": 283.419, "detail": 272.911, "player": 484.118, "url_check": 687.957, "total": 6046.925}, "counts": {"classes": 7, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "53304", "flag": "优酷", "play_id": "https://v.youku.com/v_show/id_XNDQzMjk0Njc3Mg==.html@@@youku"}, "player": {"parse": 0, "url": "https://img.ruyijx.com/m3u8/v482P8V86Ghs7A.m3u8?mFbqAXUvRfwnDw5rzu", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://img.ruyijx.com/m3u8/v482P8V86Ghs7A.m3u8?mFbqAXUvRfwnDw5rzu", "reason": null}}, {"spider": "滴答影视", "file": "滴答影视.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.564, "init": 0.001, "home": 0.001, "category": 581.273, "detail": 225.135, "player": 0.004, "url_check": 1158.226, "total": 1970.931}, "counts": {"classes": 5, "category_videos": 48, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "3051", "flag": "百度", "play_id": "https://pan.baidu.com/s/17AVcGqyaHkf7ilUO_VfWAQ?pwd=2xj8"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/17AVcGqyaHkf7ilUO_VfWAQ?pwd=2xj8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=7AVcGqyaHkf7ilUO_VfWAQ&pwd=2xj8", "reason": null}}, {"spider": "潮流APP", "file": "潮流APP.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.881, "init": 0.002, "home": 157.05, "category": 153.054, "detail": 167.575, "player": 283.133, "url_check": 93.641, "total": 859.181}, "counts": {"classes": 10, "category_videos": 12, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "10", "vod_id": "75722", "flag": "线路二 (点击换线)", "play_id": "75722@@0@@0"}, "player": {"parse": 0, "url": "http://43.248.100.143:9090/nby/m3u8/getM3u8?name=jx.91by.top&time=1779154097887&url=NBY-e84585334a25c5b49078dfac81549a0b.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "http://43.248.100.143:9090/nby/m3u8/getM3u8?name=jx.91by.top&time=1779154097887&url=NBY-e84585334a25c5b49078dfac81549a0b.m3u8", "reason": null}}, {"spider": "爱奇艺", "file": "爱奇艺.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 13.586, "init": 0.034, "home": 4689.735, "category": 766.78, "detail": 224.342, "player": 0.001, "url_check": 190.613, "total": 5885.695}, "counts": {"classes": 11, "category_videos": 60, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "pcw:1", "vod_id": "pcw:1$6003108394876300", "flag": "爱奇艺", "play_id": "http://www.iqiyi.com/v_1mmd1991kgw.html"}, "player": {"parse": 1, "url": "http://www.iqiyi.com/v_1mmd1991kgw.html", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://www.iqiyi.com/v_1mmd1991kgw.html", "reason": null}}, {"spider": "独播库", "file": "独播库.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.677, "init": 0.001, "home": 0.001, "category": 532.795, "detail": 520.874, "player": 463.08, "url_check": 317.482, "total": 1839.422}, "counts": {"classes": 6, "category_videos": 48, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "index", "vod_id": "143500", "flag": "独播库", "play_id": "143500-1-1"}, "player": {"parse": 0, "url": "https://vid.dbokutv.com/20260414/ppotb62-S71lT2yliZApDBSvkYzBsrmD3fpCJ4nBsTsRsGlR7XgBMntBJ0nBJ0mE48rE4OpHIvjS34/chunklist.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vid.dbokutv.com/20260414/ppotb62-S71lT2yliZApDBSvkYzBsrmD3fpCJ4nBsTsRsGlR7XgBMntBJ0nBJ0mE48rE4OpHIvjS34/chunklist.m3u8", "reason": null}}, {"spider": "猫猫4K", "file": "猫猫4K.txt", "success": false, "failed_stage": "player", "error": "playerContent 未返回播放地址", "traceback": null, "timings_ms": {"module_load": 7.32, "init": 307.319, "home": 465.243, "category": 405.182, "detail": 182.381, "player": 396.027, "url_check": 0.0, "total": 3441.957}, "counts": {"classes": 5, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "2", "vod_id": "136", "flag": "火猫⚡2K", "play_id": "NSYS-VR4o4PvWcbPvdUAlYmZD00D_ucGjhayldvUTl4xr2yx2aOXpybS9lFi9yu8HfuY-0etlLaAaY4JUEmH4kXT3HLZDuKAdelTuJ4406LJVeeODVPx_sVDpZ54tPY9Sg1nr|363655@@@NSYS"}, "player": {"parse": 0, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "玩偶哥哥", "file": "玩偶哥哥.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.909, "init": 0.001, "home": 0.001, "category": 236.359, "detail": 387.248, "player": 0.006, "url_check": 185.385, "total": 813.415}, "counts": {"classes": 8, "category_videos": 70, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "/voddetail/118711.html", "flag": "夸克#玩偶哥哥", "play_id": "https://pan.quark.cn/s/5fffede3e67d"}, "player": {"parse": 0, "url": "https://pan.quark.cn/s/5fffede3e67d", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.quark.cn/s/5fffede3e67d", "reason": null}}, {"spider": "玩偶聚合", "file": "玩偶聚合.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 25.309, "init": 0.001, "home": 1.732, "category": 282.744, "detail": 372.245, "player": 0.012, "url_check": 262.579, "total": 950.985}, "counts": {"classes": 10, "category_videos": 72, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "site_muou", "vod_id": "site:muou:/index.php/vod/detail/id/7940.html", "flag": "115#木偶", "play_id": "https://115cdn.com/s/swf2juc36dh?password=p8e4"}, "player": {"parse": 0, "url": "https://115cdn.com/s/swf2juc36dh?password=p8e4", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://115cdn.com/s/swf2juc36dh?password=p8e4", "reason": null}}, {"spider": "瓜子", "file": "瓜子.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 7.094, "init": 0.001, "home": 0.021, "category": 895.479, "detail": 808.781, "player": 389.064, "url_check": 159.999, "total": 2261.864}, "counts": {"classes": 5, "category_videos": 30, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "128782", "flag": "1080", "play_id": "vod_d_id=128782&vurl_id=3323715&domain_type=8&resolution=1080&type=play"}, "player": {"parse": 0, "url": "https://vd.hxcztech.com/5abf90de450ee880e00c4a7bc2251074/20260519092820/decry/vd/20260311/MjYwZjE1YTRkO/172631/1998_1080/aac/h264/hls/decrypt/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vd.hxcztech.com/5abf90de450ee880e00c4a7bc2251074/20260519092820/decry/vd/20260311/MjYwZjE1YTRkO/172631/1998_1080/aac/h264/hls/decrypt/index.m3u8", "reason": null}}, {"spider": "百度短剧", "file": "百度短剧.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.257, "init": 0.001, "home": 463.85, "category": 272.96, "detail": 599.3, "player": 272.273, "url_check": 96.478, "total": 1710.676}, "counts": {"classes": 29, "category_videos": 9, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "3", "vod_id": "10284595040762396431", "flag": "百度短剧", "play_id": "4723147730512611191|||10284595040762396431"}, "player": {"parse": 0, "url": "http://vd3.bdstatic.com/mda-rgu31fx13xnschwc/1080p/mv_cae264_backtrack_1080p_normal/1753858859061604699/mda-rgu31fx13xnschwc.mp4?v_from_s=haokan-ui-video-hnb", "valid": true, "reachable": true, "status_code": 200, "final_url": "http://vd3.bdstatic.com/mda-rgu31fx13xnschwc/1080p/mv_cae264_backtrack_1080p_normal/1753858859061604699/mda-rgu31fx13xnschwc.mp4?v_from_s=haokan-ui-video-hnb", "reason": null}}, {"spider": "盘Ta", "file": "盘Ta.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.338, "init": 0.001, "home": 520.025, "category": 270.346, "detail": 286.574, "player": 0.022, "url_check": 167.482, "total": 1249.648}, "counts": {"classes": 8, "category_videos": 30, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "?tagId=39765285016165", "vod_id": "264430", "flag": "移动", "play_id": "https://yun.139.com/shareweb/%23/w/i/2sUfBKpu5QBqz"}, "player": {"parse": 0, "url": "https://yun.139.com/shareweb/#/w/i/2sUfBKpu5QBqz", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://yun.139.com/shareweb/#/w/i/2sUfBKpu5QBqz", "reason": null}}, {"spider": "盘聚", "file": "盘聚.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 9.91, "init": 0.001, "home": 0.001, "category": 217.298, "detail": 214.858, "player": 217.875, "url_check": 1207.223, "total": 1867.871}, "counts": {"classes": 4, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "/", "vod_id": "117684", "flag": "百度1", "play_id": "push://https://www.seedhub.cc/link_start/?redirect_to=pan_id_576185&movie_title=▶️▶️▶️【挽救计划】【4K 1080P】更新于 ✅ 今天"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1e6bRvilOqU11I0aregqndA?pwd=ojmk", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=e6bRvilOqU11I0aregqndA&pwd=ojmk", "reason": null}}, {"spider": "盘链", "file": "盘链.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 7.676, "init": 0.022, "home": 0.001, "category": 1598.203, "detail": 358.976, "player": 0.002, "url_check": 1225.588, "total": 3190.978}, "counts": {"classes": 5, "category_videos": 30, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "0", "vod_id": "75716", "flag": "百度", "play_id": "push://https://pan.baidu.com/s/1rbhXV3rLNKd1wVta_hMYnw?pwd=8888"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1rbhXV3rLNKd1wVta_hMYnw?pwd=8888", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=rbhXV3rLNKd1wVta_hMYnw&pwd=8888", "reason": null}}, {"spider": "短剧优选", "file": "短剧优选.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 20.874, "init": 589.888, "home": 0.144, "category": 475.42, "detail": 739.65, "player": 0.002, "url_check": 182.141, "total": 2021.144}, "counts": {"classes": 11, "category_videos": 78, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "七猫", "vod_id": "七猫@24333", "flag": "七猫短剧", "play_id": "https://cdn-vod-playlet.wtzw.com/asset/b936eac78f199fd865afbe3c5b707e7f/play_multi_video/6f7310c287644b7c813ab8e2eb7a4a0c/f1223068052dd7f1bc88718af4b2c0e4.m3u8"}, "player": {"parse": 0, "url": "https://cdn-vod-playlet.wtzw.com/asset/b936eac78f199fd865afbe3c5b707e7f/play_multi_video/6f7310c287644b7c813ab8e2eb7a4a0c/f1223068052dd7f1bc88718af4b2c0e4.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://cdn-vod-playlet.wtzw.com/asset/b936eac78f199fd865afbe3c5b707e7f/play_multi_video/6f7310c287644b7c813ab8e2eb7a4a0c/f1223068052dd7f1bc88718af4b2c0e4.m3u8", "reason": null}}, {"spider": "短剧网", "file": "短剧网.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.7, "init": 0.001, "home": 0.001, "category": 476.589, "detail": 265.354, "player": 0.008, "url_check": 1192.978, "total": 1939.929}, "counts": {"classes": 2, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "https://sm3.cc/?id=51213", "flag": "百度", "play_id": "https://pan.baidu.com/s/1h4CcF1t7D13_PdpZIXQ1ZA?pwd=6666"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1h4CcF1t7D13_PdpZIXQ1ZA?pwd=6666", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=h4CcF1t7D13_PdpZIXQ1ZA&pwd=6666", "reason": null}}, {"spider": "糯米", "file": "糯米.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 8.198, "init": 0.001, "home": 467.858, "category": 741.788, "detail": 185.483, "player": 336.4, "url_check": 315.32, "total": 2055.766}, "counts": {"classes": 7, "category_videos": 81, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "/vod-type-id-1-pg-1.html", "vod_id": "90063", "flag": "uvw", "play_id": "/vod-play-id-90063-src-1-num-1.html"}, "player": {"parse": 0, "url": "https://vip.123pan.cn/1853039965/dy/东北往事极恶不赦.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vip.123pan.cn/1853039965/dy/%E4%B8%9C%E5%8C%97%E5%BE%80%E4%BA%8B%E6%9E%81%E6%81%B6%E4%B8%8D%E8%B5%A6.m3u8", "reason": null}}, {"spider": "网易云音乐", "file": "网易云音乐.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 3.073, "init": 0.0, "home": 437.725, "category": 510.6, "detail": 0.018, "player": 9907.366, "url_check": 135.401, "total": 11000.842}, "counts": {"classes": 62, "category_videos": 100, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "/discover/toplist?id=19723756", "vod_id": "3378778218@네가 나의 세상이라면@SAM KIM👉MV", "flag": "网易云音乐", "play_id": "3378778218"}, "player": {"parse": 0, "url": "https://vodkgeyttp8.vod.126.net/cloudmusic/3985/core/8a37/e1e1b6cf41b2047845f3fe844bf99ad9.mp4?wsSecret=877f55f2352aadb655bcb2b2f3fe56af&wsTime=1779154111", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vodkgeyttp8.vod.126.net/cloudmusic/3985/core/8a37/e1e1b6cf41b2047845f3fe844bf99ad9.mp4?wsSecret=877f55f2352aadb655bcb2b2f3fe56af&wsTime=1779154111", "reason": null}}, {"spider": "耐视点播", "file": "耐视点播.txt", "success": false, "failed_stage": "category", "error": "分类视频列表为空", "traceback": null, "timings_ms": {"module_load": 6.229, "init": 0.001, "home": 0.0, "category": 1481.916, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 3622.273}, "counts": {"classes": 6, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "2", "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "腾讯视频", "file": "腾讯视频.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 7.163, "init": 0.001, "home": 165.813, "category": 318.745, "detail": 1011.913, "player": 0.002, "url_check": 290.976, "total": 1795.276}, "counts": {"classes": 7, "category_videos": 12, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "choice", "vod_id": "choice$mzc002009g0nh88", "flag": "腾讯视频", "play_id": "https://v.qq.com/x/cover/mzc002009g0nh88/w4102d4f4ur.html"}, "player": {"parse": 1, "url": "https://v.qq.com/x/cover/mzc002009g0nh88/w4102d4f4ur.html", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://v.qq.com/x/cover/mzc002009g0nh88/w4102d4f4ur.html", "reason": null}}, {"spider": "至臻", "file": "至臻.txt", "success": false, "failed_stage": "unexpected", "error": "HTTPConnectionPool(host='www.miqk.cc', port=80): Read timed out. (read timeout=10)", "traceback": "Traceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 534, in _make_request\n response = conn.getresponse()\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connection.py\", line 571, in getresponse\n httplib_response = super().getresponse()\n File \"/home/harold/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/http/client.py\", line 1450, in getresponse\n response.begin()\n ~~~~~~~~~~~~~~^^\n File \"/home/harold/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/http/client.py\", line 336, in begin\n version, status, reason = self._read_status()\n ~~~~~~~~~~~~~~~~~^^\n File \"/home/harold/.local/share/uv/python/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/http/client.py\", line 297, in _read_status\n line = str(self.fp.readline(_MAXLINE + 1), \"iso-8859-1\")\n ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^\nTimeoutError: timed out\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/requests/adapters.py\", line 645, in send\n resp = conn.urlopen(\n method=request.method,\n ...<9 lines>...\n chunked=chunked,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 841, in urlopen\n retries = retries.increment(\n method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/retry.py\", line 490, in increment\n raise reraise(type(error), error, _stacktrace)\n ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/util.py\", line 39, in reraise\n raise value\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 787, in urlopen\n response = self._make_request(\n conn,\n ...<10 lines>...\n **response_kw,\n )\nurllib3.exceptions.ReadTimeoutError: HTTPConnectionPool(host='www.miqk.cc', port=80): Read timed out. (read timeout=10)\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 716, in validate_spider_file\n _validate_from_tid(\n ~~~~~~~~~~~~~~~~~~^\n spider=spider,\n ^^^^^^^^^^^^^^\n ...<6 lines>...\n logger=logger,\n ^^^^^^^^^^^^^^\n )\n ^\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 412, in _validate_from_tid\n category_result = _run_timed(result[\"timings_ms\"], \"category\", spider.categoryContent, clock, tid, \"1\", False, {})\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 291, in _run_timed\n return func(*args, **kwargs)\n File \"/home/harold/workspace/tvbox-resources/py/至臻.txt\", line 146, in categoryContent\n File \"/home/harold/workspace/tvbox-resources/py/至臻.txt\", line 102, in _request_html\nrequests.exceptions.ReadTimeout: HTTPConnectionPool(host='www.miqk.cc', port=80): Read timed out. (read timeout=10)\n", "timings_ms": {"module_load": 4.701, "init": 0.001, "home": 0.0, "category": 10013.208, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 10021.75}, "counts": {"classes": 7, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "1", "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "茶杯狐", "file": "茶杯狐.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.803, "init": 0.0, "home": 1346.5, "category": 924.855, "detail": 763.486, "player": 1477.144, "url_check": 1896.734, "total": 6415.198}, "counts": {"classes": 4, "category_videos": 36, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "detail/video/121065", "flag": "FF有广", "play_id": "play/121065-1-1"}, "player": {"parse": 0, "url": "https://vip.ffzy-plays.com/20260519/53712_3981010d/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vip.ffzy-plays.com/20260519/53712_3981010d/index.m3u8", "reason": null}}, {"spider": "虎斑", "file": "虎斑.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.573, "init": 0.001, "home": 0.001, "category": 2435.11, "detail": 9704.331, "player": 0.009, "url_check": 1046.203, "total": 13472.451}, "counts": {"classes": 6, "category_videos": 72, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "2", "vod_id": "/index.php/vod/detail/id/467113.html", "flag": "百度#虎斑", "play_id": "https://pan.baidu.com/s/1hX81VgiFEtXOBdh9y22Cdg?pwd=qsaa"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1hX81VgiFEtXOBdh9y22Cdg?pwd=qsaa", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=hX81VgiFEtXOBdh9y22Cdg&pwd=qsaa", "reason": null}}, {"spider": "蜡笔", "file": "蜡笔.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 59.837, "init": 0.002, "home": 0.003, "category": 885.688, "detail": 532.626, "player": 0.003, "url_check": 1038.945, "total": 2519.984}, "counts": {"classes": 7, "category_videos": 72, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "29", "vod_id": "9231", "flag": "百度#蜡笔", "play_id": "https://pan.baidu.com/s/1LZC9v0B6ETfpQWooAqqxJA?pwd=jcx5"}, "player": {"parse": 0, "url": "https://pan.baidu.com/s/1LZC9v0B6ETfpQWooAqqxJA?pwd=jcx5", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://pan.baidu.com/share/init?surl=LZC9v0B6ETfpQWooAqqxJA&pwd=jcx5", "reason": null}}, {"spider": "袋鼠影视", "file": "袋鼠影视.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 33.461, "init": 0.002, "home": 0.003, "category": 921.603, "detail": 220.182, "player": 229.912, "url_check": 1267.619, "total": 2673.888}, "counts": {"classes": 4, "category_videos": 36, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "414927", "flag": "蓝光专线4", "play_id": "play/414927-0-0"}, "player": {"parse": 0, "url": "https://vip.dytt-see.com/20260518/38902_ab661b15/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vip.dytt-see.com/20260518/38902_ab661b15/index.m3u8", "reason": null}}, {"spider": "视界", "file": "视界.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 22.571, "init": 0.002, "home": 436.831, "category": 222.792, "detail": 248.639, "player": 501.093, "url_check": 386.641, "total": 1830.552}, "counts": {"classes": 6, "category_videos": 30, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "20", "vod_id": "134532", "flag": "备用源(有广勿信)", "play_id": "https://svip.ffzyplay.com/?url=https://vod.feifei-video.com/20260427/42451_1abe906b/index.m3u8|魅力航班第二季|1"}, "player": {"parse": 0, "url": "https://svip.ffzyplay.com/?url=https://vod.feifei-video.com/20260427/42451_1abe906b/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://svip.ffzyplay.com/?url=https://vod.feifei-video.com/20260427/42451_1abe906b/index.m3u8", "reason": null}}, {"spider": "路漫漫", "file": "路漫漫.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 5.218, "init": 0.001, "home": 0.001, "category": 1045.419, "detail": 701.833, "player": 7069.519, "url_check": 247.776, "total": 11321.923}, "counts": {"classes": 6, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "6", "vod_id": "detail/8037.html", "flag": "dev云播", "play_id": "play/8037_2_1.html"}, "player": {"parse": 0, "url": "https://v16.toutiao50.com/3da5cecf1545b70ed89d7f504c673cd6/6a0d13ca/video/tos/alisg/tos-alisg-ve-0051c001-sg/owL5ueUTlAndDIFpIKiDnbICgDKeI4DFGeGAQG/", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://v16.toutiao50.com/3da5cecf1545b70ed89d7f504c673cd6/6a0d13ca/video/tos/alisg/tos-alisg-ve-0051c001-sg/owL5ueUTlAndDIFpIKiDnbICgDKeI4DFGeGAQG/", "reason": null}}, {"spider": "酷我听书", "file": "酷我听书.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.801, "init": 0.001, "home": 427.51, "category": 109.59, "detail": 3495.61, "player": 156.293, "url_check": 106.418, "total": 4301.371}, "counts": {"classes": 4, "category_videos": 21, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "2", "vod_id": "13492273", "flag": "酷我听书", "play_id": "free|94448942"}, "player": {"parse": 0, "url": "http://lv.sycdn.kuwo.cn/48cdbf46cf0053780f92d00112db78a1/6a0bbcba/resource/30106/trackmedia/long/M500002ZiI9a1sctnS.mp3?bitrate$128&format$mp3&source$kwplayerhd_ar_4.3.0.8_tianbao_T1A_qirui.apk&type$convert_url_with_sign&user$&loginUid$", "valid": true, "reachable": true, "status_code": 200, "final_url": "http://lv.sycdn.kuwo.cn/48cdbf46cf0053780f92d00112db78a1/6a0bbcba/resource/30106/trackmedia/long/M500002ZiI9a1sctnS.mp3?bitrate$128&format$mp3&source$kwplayerhd_ar_4.3.0.8_tianbao_T1A_qirui.apk&type$convert_url_with_sign&user$&loginUid$", "reason": null}}, {"spider": "酷狗音乐", "file": "酷狗音乐.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 10.917, "init": 10400.331, "home": 307.538, "category": 317.061, "detail": 318.471, "player": 408.726, "url_check": 167.732, "total": 11932.279}, "counts": {"classes": 12, "category_videos": 15, "detail_videos": 1, "episodes": 1}, "samples": {"tid": "recommend", "vod_id": "273602306", "flag": "酷狗音乐", "play_id": "273602306"}, "player": {"parse": 0, "url": "http://fsdg360.hw.kugou.com/202605190928/5d83cbfb56a0bc51aeb303bf6654087f/v3/c478d384201a55cff425e7db6628f50c/yp/p_0_960199/ap1013_us0_mic85f71c379c462618de1399950957c33_pi6101_mx273602306_qu128_s1586875936.mp3?ft=car_203559_10049&fts=b05bb02d44717442054bac7624ed9a29&ext=.mp3", "valid": true, "reachable": true, "status_code": 200, "final_url": "http://fsdg360.hw.kugou.com/202605190928/5d83cbfb56a0bc51aeb303bf6654087f/v3/c478d384201a55cff425e7db6628f50c/yp/p_0_960199/ap1013_us0_mic85f71c379c462618de1399950957c33_pi6101_mx273602306_qu128_s1586875936.mp3?ft=car_203559_10049&fts=b05bb02d44717442054bac7624ed9a29&ext=.mp3", "reason": null}}, {"spider": "金牌", "file": "金牌.txt", "success": false, "failed_stage": "unexpected", "error": "HTTPSConnectionPool(host='m.jiabaide.cn', port=443): Max retries exceeded with url: /api/mw-movie/anonymous/video/detail?id=143230 (Caused by ConnectTimeoutError(<HTTPSConnection(host='m.jiabaide.cn', port=443) at 0x7d6e347dafd0>, 'Connection to m.jiabaide.cn timed out. (connect timeout=10)'))", "traceback": "Traceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connection.py\", line 204, in _new_conn\n sock = connection.create_connection(\n (self._dns_host, self.port),\n ...<2 lines>...\n socket_options=self.socket_options,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/connection.py\", line 85, in create_connection\n raise err\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/connection.py\", line 73, in create_connection\n sock.connect(sa)\n ~~~~~~~~~~~~^^^^\nTimeoutError: timed out\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 787, in urlopen\n response = self._make_request(\n conn,\n ...<10 lines>...\n **response_kw,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 488, in _make_request\n raise new_e\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 464, in _make_request\n self._validate_conn(conn)\n ~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 1093, in _validate_conn\n conn.connect()\n ~~~~~~~~~~~~^^\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connection.py\", line 759, in connect\n self.sock = sock = self._new_conn()\n ~~~~~~~~~~~~~~^^\nurllib3.exceptions.ConnectTimeoutError: (<HTTPSConnection(host='m.jiabaide.cn', port=443) at 0x7d6e347dafd0>, 'Connection to m.jiabaide.cn timed out. (connect timeout=10)')\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/requests/adapters.py\", line 645, in send\n resp = conn.urlopen(\n method=request.method,\n ...<9 lines>...\n chunked=chunked,\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/connectionpool.py\", line 841, in urlopen\n retries = retries.increment(\n method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]\n )\n File \"/home/harold/workspace/atv-spiders/py/.venv/lib/python3.14/site-packages/urllib3/util/retry.py\", line 535, in increment\n raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nurllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='m.jiabaide.cn', port=443): Max retries exceeded with url: /api/mw-movie/anonymous/video/detail?id=143230 (Caused by ConnectTimeoutError(<HTTPSConnection(host='m.jiabaide.cn', port=443) at 0x7d6e347dafd0>, 'Connection to m.jiabaide.cn timed out. (connect timeout=10)'))\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 716, in validate_spider_file\n _validate_from_tid(\n ~~~~~~~~~~~~~~~~~~^\n spider=spider,\n ^^^^^^^^^^^^^^\n ...<6 lines>...\n logger=logger,\n ^^^^^^^^^^^^^^\n )\n ^\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 428, in _validate_from_tid\n detail_result = _run_timed(result[\"timings_ms\"], \"detail\", spider.detailContent, clock, [vod_id])\n File \"/home/harold/workspace/atv-spiders/py/validate_spiders.py\", line 291, in _run_timed\n return func(*args, **kwargs)\n File \"/home/harold/workspace/tvbox-resources/py/金牌.txt\", line 198, in detailContent\n File \"/home/harold/workspace/tvbox-resources/py/金牌.txt\", line 79, in _fetch_json\nrequests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='m.jiabaide.cn', port=443): Max retries exceeded with url: /api/mw-movie/anonymous/video/detail?id=143230 (Caused by ConnectTimeoutError(<HTTPSConnection(host='m.jiabaide.cn', port=443) at 0x7d6e347dafd0>, 'Connection to m.jiabaide.cn timed out. (connect timeout=10)'))\n", "timings_ms": {"module_load": 4.988, "init": 0.001, "home": 2252.759, "category": 339.437, "detail": 10012.61, "player": 0.0, "url_check": 0.0, "total": 12615.123}, "counts": {"classes": 4, "category_videos": 30, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "1", "vod_id": "143230", "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "闪电", "file": "闪电.txt", "success": false, "failed_stage": "category", "error": "分类视频列表为空", "traceback": null, "timings_ms": {"module_load": 5.936, "init": 0.0, "home": 0.0, "category": 1352.528, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 2904.334}, "counts": {"classes": 5, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": "2", "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "飞快TV", "file": "飞快TV.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 4.274, "init": 0.001, "home": 0.0, "category": 1165.978, "detail": 987.378, "player": 947.64, "url_check": 872.051, "total": 3977.88}, "counts": {"classes": 4, "category_videos": 40, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "240253", "flag": "如意资源1", "play_id": "/vodplay/240253-2-1.html"}, "player": {"parse": 0, "url": "https://svip.ryiplay18.com/20260518/6534_0420d934/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://svip.ryiplay18.com/20260518/6534_0420d934/index.m3u8", "reason": null}}, {"spider": "魔方APP", "file": "魔方APP.txt", "success": false, "failed_stage": "home", "error": "分类列表为空", "traceback": null, "timings_ms": {"module_load": 5.155, "init": 0.001, "home": 331.929, "category": 0.0, "detail": 0.0, "player": 0.0, "url_check": 0.0, "total": 337.231}, "counts": {"classes": 0, "category_videos": 0, "detail_videos": 0, "episodes": 0}, "samples": {"tid": null, "vod_id": null, "flag": null, "play_id": null}, "player": {"parse": null, "url": "", "valid": false, "reachable": null, "status_code": null, "final_url": "", "reason": null}}, {"spider": "麦田影院", "file": "麦田影院.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 11.861, "init": 0.0, "home": 0.0, "category": 432.527, "detail": 189.614, "player": 0.037, "url_check": 387.249, "total": 1022.493}, "counts": {"classes": 6, "category_videos": 20, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "1", "vod_id": "171427", "flag": "LZ源", "play_id": "eyJ1cmwiOiJodHRwczovL3YubHpjZG4yNy5jb20vMjAyNTA3MzEvNjc5XzUwYTJiMDQ3L2luZGV4Lm0zdTgiLCJwYXJzZV9hcGkiOiJodHRwczovL2RlbC5tdDMyMC5jb20vbHpmZi5waHA_dXJsPSIsImhlYWRlcnMiOnt9LCJ1c2VyX2FnZW50IjoiIn0="}, "player": {"parse": 0, "url": "https://v.lzcdn27.com/20250731/679_50a2b047/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://v.lzcdn27.com/20250731/679_50a2b047/index.m3u8", "reason": null}}, {"spider": "黑猫APP", "file": "黑猫APP.txt", "success": true, "failed_stage": null, "error": null, "traceback": null, "timings_ms": {"module_load": 7.8, "init": 0.001, "home": 2057.325, "category": 1666.943, "detail": 1675.845, "player": 0.009, "url_check": 1912.923, "total": 12838.061}, "counts": {"classes": 5, "category_videos": 30, "detail_videos": 1, "episodes": 2}, "samples": {"tid": "2", "vod_id": "91018", "flag": "🐈‍⬛标清线路2", "play_id": "标清线路3@@direct@@,https://vod.feifei-video.com/20260110/35260_c8caec33/index.m3u8,token+,1,0"}, "player": {"parse": 0, "url": "https://vod.feifei-video.com/20260110/35260_c8caec33/index.m3u8", "valid": true, "reachable": true, "status_code": 200, "final_url": "https://vod.feifei-video.com/20260110/35260_c8caec33/index.m3u8", "reason": null}}]};
const STAGE_LABELS = {"module_load": "模块加载", "init": "初始化", "home": "首页分类", "category": "分类列表", "detail": "视频详情", "player": "播放地址", "url_check": "地址校验", "unexpected": "未预期异常", "total": "总耗时"};
const RAW_SPIDER_BASE_URL = "https://github.com/har01d5/tvbox/raw/refs/heads/master/py/";
const state = {
status: "all",
failedStage: "all",
keyword: "",
minDuration: "",
maxDuration: "",
sortKey: "spider",
sortDirection: "asc",
};
function escapeHtml(value) {
return String(value ?? "")
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
function formatDuration(value) {
const numeric = Number(value ?? 0);
if (Number.isNaN(numeric)) {
return String(value ?? "");
}
if (numeric >= 1000) {
return `${Math.round((numeric / 1000) * 1000) / 1000}秒`;
}
return `${numeric}ms`;
}
function stageLabel(stage) {
return stage ? (STAGE_LABELS[stage] || stage) : "";
}
function spiderUrl(fileName) {
return RAW_SPIDER_BASE_URL + encodeURIComponent(String(fileName || ""));
}
function uniqueFailedStages(items) {
const values = new Set();
items.forEach((item) => {
if (item.failed_stage) {
values.add(item.failed_stage);
}
});
return [...values].sort((left, right) => stageLabel(left).localeCompare(stageLabel(right), "zh-Hans-CN"));
}
function sortValue(item, key) {
if (key === "status") {
return item.success ? 0 : 1;
}
if (key === "failed_stage") {
return stageLabel(item.failed_stage);
}
if (key === "spider") {
return item.spider || "";
}
return Number(item.timings_ms?.[key] ?? 0);
}
function applyFilters(items) {
return items.filter((item) => {
if (state.status === "success" && !item.success) {
return false;
}
if (state.status === "failed" && item.success) {
return false;
}
if (state.failedStage !== "all" && (item.failed_stage || "") !== state.failedStage) {
return false;
}
const haystack = `${item.spider || ""} ${item.file || ""}`.toLowerCase();
if (state.keyword && !haystack.includes(state.keyword.toLowerCase())) {
return false;
}
const total = Number(item.timings_ms?.total ?? 0);
if (state.minDuration !== "" && total < Number(state.minDuration)) {
return false;
}
if (state.maxDuration !== "" && total > Number(state.maxDuration)) {
return false;
}
return true;
});
}
function applySort(items) {
return [...items].sort((left, right) => {
const a = sortValue(left, state.sortKey);
const b = sortValue(right, state.sortKey);
const comparison = typeof a === "number" && typeof b === "number"
? a - b
: String(a).localeCompare(String(b), "zh-Hans-CN");
return state.sortDirection === "asc" ? comparison : -comparison;
});
}
function renderSummary(items) {
const success = items.filter((item) => item.success).length;
const failed = items.length - success;
document.getElementById("summary-line").textContent =
`当前显示 ${items.length} / ${report.results.length} 条,成功 ${success},失败 ${failed}`;
}
function renderRows(items) {
const tbody = document.getElementById("results-body");
if (!items.length) {
tbody.innerHTML = '<tr><td class="empty" colspan="13">当前筛选条件下没有结果</td></tr>';
return;
}
tbody.innerHTML = items.map((item) => {
const statusClass = item.success ? "success" : "failed";
const statusText = item.success ? "成功" : "失败";
return `
<tr>
<td><a href="${spiderUrl(item.file)}" target="_blank" rel="noreferrer">${escapeHtml(item.spider)}</a></td>
<td><span class="status ${statusClass}">${statusText}</span></td>
<td>${escapeHtml(stageLabel(item.failed_stage))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.total ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.module_load ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.init ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.home ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.category ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.detail ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.player ?? 0))}</td>
<td>${escapeHtml(formatDuration(item.timings_ms?.url_check ?? 0))}</td>
<td>${escapeHtml(item.player?.url ?? "")}</td>
<td>${escapeHtml(item.error ?? "")}</td>
</tr>
`;
}).join("");
}
function updateSortIndicators() {
document.querySelectorAll("[data-sort-key]").forEach((button) => {
const indicator = button.querySelector(".sort-indicator");
if (!indicator) {
return;
}
if (button.dataset.sortKey !== state.sortKey) {
indicator.textContent = "";
return;
}
indicator.textContent = state.sortDirection === "asc" ? "▲" : "▼";
});
}
function rerender() {
const filtered = applyFilters(report.results);
const sorted = applySort(filtered);
renderSummary(sorted);
renderRows(sorted);
updateSortIndicators();
}
function initializeFilters() {
const statusFilter = document.getElementById("status-filter");
const stageFilter = document.getElementById("stage-filter");
const keywordFilter = document.getElementById("keyword-filter");
const minFilter = document.getElementById("duration-min-filter");
const maxFilter = document.getElementById("duration-max-filter");
const resetButton = document.getElementById("reset-filters");
statusFilter.innerHTML = [
'<option value="all">全部状态</option>',
'<option value="success">成功</option>',
'<option value="failed">失败</option>',
].join("");
stageFilter.innerHTML = ['<option value="all">全部阶段</option>']
.concat(uniqueFailedStages(report.results).map((stage) => `<option value="${escapeHtml(stage)}">${escapeHtml(stageLabel(stage))}</option>`))
.join("");
statusFilter.addEventListener("change", (event) => {
state.status = event.target.value;
rerender();
});
stageFilter.addEventListener("change", (event) => {
state.failedStage = event.target.value;
rerender();
});
keywordFilter.addEventListener("input", (event) => {
state.keyword = event.target.value.trim();
rerender();
});
minFilter.addEventListener("input", (event) => {
state.minDuration = event.target.value;
rerender();
});
maxFilter.addEventListener("input", (event) => {
state.maxDuration = event.target.value;
rerender();
});
resetButton.addEventListener("click", () => {
state.status = "all";
state.failedStage = "all";
state.keyword = "";
state.minDuration = "";
state.maxDuration = "";
statusFilter.value = "all";
stageFilter.value = "all";
keywordFilter.value = "";
minFilter.value = "";
maxFilter.value = "";
rerender();
});
document.querySelectorAll("[data-sort-key]").forEach((button) => {
button.addEventListener("click", () => {
const key = button.dataset.sortKey;
if (state.sortKey === key) {
state.sortDirection = state.sortDirection === "asc" ? "desc" : "asc";
} else {
state.sortKey = key;
state.sortDirection = "asc";
}
rerender();
});
});
}
function initializeSummaryCards() {
document.getElementById("generated-at").textContent = report.generated_at || "";
document.getElementById("max-workers").textContent = String(report.max_workers ?? "");
document.getElementById("total-count").textContent = String(report.summary?.total ?? 0);
document.getElementById("success-count").textContent = String(report.summary?.success ?? 0);
document.getElementById("failed-count").textContent = String(report.summary?.failed ?? 0);
document.getElementById("total-duration").textContent = formatDuration(report.total_duration_ms ?? 0);
}
initializeSummaryCards();
initializeFilters();
rerender();
</script>
</body>
</html>