diff --git a/docs/runbook/sites.md b/docs/runbook/sites.md index 98c993ad..74a7e505 100644 --- a/docs/runbook/sites.md +++ b/docs/runbook/sites.md @@ -117,6 +117,7 @@ - 外部 ID 另写 `source_release.raw._detail`(`imdbId / doubanId / tmdb{type,id}`),列表快照 upsert 不覆盖它。身份解析把它和列表给的 `raw._site.imdbId / doubanId` 一起当显式 ID:本地召回查已接受的外部身份;需要查 TMDB 时,有 TMDB ID 直接取详情,否则 IMDb ID 走 `/find/{imdb}?external_source=imdb_id`,命中就不再按标题搜索;TMDB 不支持豆瓣 ID,豆瓣只用于本地召回。是否查 TMDB 仍按惰性识别规则(DEC-1),外部 ID 本身不触发查询。 - 截图:响应里只有代理路径 `/api/v1/img/site-detail/{releaseId}/{index}`,服务端从缓存取原始地址,公网校验(每跳重定向复核)、不带站点凭据、按文件头认图片(不放行 SVG)、≤ 8 MB,浏览器缓存 24 小时。站内附件如果需要登录才能看会显示为裂图,不会为截图消耗站点请求。 - 憨憨详情页(HH-2 按真实页面 `probe.labels` 核对):没有 `#kdescr`,内容分节为「标签 div + 相邻值 div」:`mediainfo`、`海报`、`豆瓣`(内有 `span.font-bold` 小标签 片名 / 年代 / 类别 / 导演 …)、`截图`、`种子文件`(只有「查看列表」按钮)、`发布者`、`发布时间`。对应规则:简介没有容器时取「豆瓣 / 影片信息 / IMDb」信息块,小标签补冒号、一项一行;截图取「截图」一节的 img(`data-src` 优先,海报不算截图),没有再取简介里的图;IMDb 依次取页面链接 → 简介 / 信息块 / MediaInfo 里的 `imdb.com/title/tt…` 或 `IMDB : tt…` 行(只收 `tt` + 7~8 位,不收孤立 tt 串),TMDB 取链接或 `TMDB : tv/294990` 行,豆瓣取链接或 `douban.com/subject/…`;兜底出的 IMDb / 豆瓣也回填到 `SiteRelease.imdbId / doubanId`;发布时间没有 `span[title]` 时取「发布时间 / 上传时间」字段文本。文件清单:定义 `umt.detail.page.fileListPath`(憨憨 `viewfilelist.php?id={id}`)配置了且页面上没有内联清单时,同一次详情刷新里再请求 1 次(走同一限流器、计数),失败只是没有清单。fixture `HHANCLUB_DETAIL_PAGE_2026` / `HHANCLUB_FILELIST_FRAGMENT`:标签名称与顺序来自真实页面,嵌套按已验证的标题 / 副标题结构推定,部署后打开一条憨憨资源的详情抽屉核对一次。 +- 观众详情页(DET-2 按真实页面核对,样本 `packages/adapters/test/differential/inputs/detail/rl-audiences-detail-*.html.txt` 已脱敏,回归测试 `test/differential/detail.test.ts`;列表页样本 `inputs/indexer/rl-audiences-list.html.txt` 进 MP 差分):标准 rowhead 表格,但有几处与通用 NexusPHP 不同,写在定义里。h1 的促销是 `font.free / font.halfdown …`(列表是 `img.pro_*`)加「剩余时间:」和到期 `span[title]`,用 `umt.detail.promo` 覆盖列表的促销字段;h1 的「剩余时间:」文本不进标题,标题区里的 `span[title]` 也不当发布时间(发布时间取「下载」行「发布于」的 span)。没有「同伴」行,做种 / 下载 / 完成数取基本信息行右侧 `#seeders / #leechers / a[title=完成]`(`umt.detail.fields.seeders / leechers / snatched`);种子 Hash 取 `#copyTorrentHashLink[data-hash]`(`fields.infoHash`,回填 `infoHash`)。副标题行右侧有豆瓣 / IMDb / 烂番茄 / Metacritic 评分徽标(`[title*=评分]`),解析时去掉;评分本身本工具没有字段,不收。标签是 `span.detail-tag-list > span.tags`,只取最内层。上传者在「下载」行的 `span.torrent-uploader-wrap`(匿名发布为「匿名」);另有「发布者带宽」一行,所以上传者标签改为精确匹配。简介开头的站点声明 `#ad_torrentdetail` 用 `umt.detail.page.descriptionStrip` 去掉;MediaInfo / BDInfo 是 `div.codetop`(文件名 / BDInfo)+ `div.show`(摘要表或同一份 BDInfo)+ `div.hide > div.codemain`(原文),三者都从简介里去掉;简介是 `
\r\n`,源码换行不再算一行(以前每行之间多一空行)。截图排除豆瓣海报(站点经 `dbimgs.audiences.me/?…doubanio.com…poster` 代理)与站点横幅 `/banners/`。IMDb / 豆瓣 ID 取简介里的链接;TMDB 页面上没有;单种 H&R 标记页面上没有(列表也没有),保持「未知」。文件清单不在页面上(点「N个文件」后 AJAX 加载,端点未核对),暂不另发请求。列表副标题改取 `span.torrent-subtitle-text`(`span.torrent-subtitle-line` 里先是标签,以前副标题前面会粘着「官方中字DIY…」)。 - 截图代理的 Referer:截图与站点同根域(憨憨图床 `pic.hhanclub.net`、`proxy-cover.hhanclub.net`)时带 `Referer: <站点地址>/`(防盗链),外部图床(如 pixhost)不带;任何情况都不带 Cookie。 - 解析:`packages/adapters/src/sites/spider/detail-page.ts`。简介取 MovieClaw `detail_description_css`(缺省 `#kdescr`);MediaInfo 取定义 `umt.detail.page.mediaInfo` → 「MediaInfo」字段标签 → 简介里第一个像 MediaInfo 的引用 / 代码块;文件清单取 `umt.detail.page.files` → MovieClaw `detail_file_list_css` → 「文件列表」字段 → `#filelist` 表格,不额外请求 `viewfilelist.php`。字段标签除 `td.rowhead` 外可在 `umt.detail.page.labelSelectors` 加(憨憨:`div.font-bold.leading-6`、`span.font-bold`)。`page.probe` 记录页面上找到的字段标签,只存缓存不展示,站点改版时用来排查。馒头从 API 的 `descr`(BBCode)与 `mediainfo` 取同样的结构。 diff --git a/packages/adapters/src/sites/definitions/audiences.json b/packages/adapters/src/sites/definitions/audiences.json index d4d47e59..b657b49e 100644 --- a/packages/adapters/src/sites/definitions/audiences.json +++ b/packages/adapters/src/sites/definitions/audiences.json @@ -140,7 +140,7 @@ } }, "description": { - "selector": "span.torrent-subtitle-line" + "selector": "span.torrent-subtitle-text" }, "category": { "selector": "a[href*=\"?cat=\"]", @@ -168,7 +168,7 @@ } }, "umt": { - "version": "audiences@0.2.1-unverified", + "version": "audiences@0.3.1", "kind": "nexusphp", "displayName": "观众", "timezone": "+08:00", @@ -225,7 +225,55 @@ }, "description": "#kdescr", "headerScope": "h1#top", - "notFoundMarkers": ["没有该ID的种子", "No torrent with ID"] + "notFoundMarkers": ["没有该ID的种子", "No torrent with ID"], + "fields": { + "seeders": "#seeders", + "leechers": "#leechers", + "snatched": "a[title='完成'][href*='viewsnatches.php']", + "infoHash": "#copyTorrentHashLink::attr(data-hash)" + }, + "promo": { + "downloadvolumefactor": { + "case": { + "font.free": 0, + "font.twoupfree": 0, + "font.halfdown": 0.5, + "font.twouphalfdown": 0.5, + "font.thirtypercent": 0.3, + "img.pro_free": 0, + "img.pro_free2up": 0, + "img.pro_50pctdown": 0.5, + "img.pro_50pctdown2up": 0.5, + "img.pro_30pctdown": 0.3, + "*": 1 + } + }, + "uploadvolumefactor": { + "case": { + "font.twoup": 2, + "font.twoupfree": 2, + "font.twouphalfdown": 2, + "img.pro_50pctdown2up": 2, + "img.pro_free2up": 2, + "img.pro_2up": 2, + "*": 1 + } + }, + "freedate": { + "selector": "img[class^=\"pro_\"], span[title]", + "attribute": "title", + "filters": [ + { + "name": "re_search", + "args": ["\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", 0] + } + ] + } + }, + "page": { + "uploader": "span.torrent-uploader-wrap", + "descriptionStrip": "#ad_torrentdetail" + } } } } diff --git a/packages/adapters/src/sites/definitions/schema.ts b/packages/adapters/src/sites/definitions/schema.ts index 83fe8ae2..46186a65 100644 --- a/packages/adapters/src/sites/definitions/schema.ts +++ b/packages/adapters/src/sites/definitions/schema.ts @@ -139,8 +139,13 @@ const UmtNexusSchema = z.strictObject({ imdb: z.string().optional(), douban: z.string().optional(), fileList: z.string().optional(), + seeders: z.string().optional(), + leechers: z.string().optional(), + snatched: z.string().optional(), + infoHash: z.string().optional(), }) .optional(), + promo: z.record(z.string(), SpiderFieldSelectorSchema).optional(), page: z .strictObject({ labelSelectors: z.array(z.string()).optional(), @@ -150,6 +155,7 @@ const UmtNexusSchema = z.strictObject({ uploader: z.string().optional(), files: z.string().optional(), fileListPath: z.string().optional(), + descriptionStrip: z.string().optional(), }) .optional(), }) diff --git a/packages/adapters/src/sites/detail-text.ts b/packages/adapters/src/sites/detail-text.ts index ea569a30..186a044e 100644 --- a/packages/adapters/src/sites/detail-text.ts +++ b/packages/adapters/src/sites/detail-text.ts @@ -8,6 +8,9 @@ import { extractDoubanId, extractImdbId } from "./util.ts"; const NOT_SCREENSHOT = /(smilies|smiley|emoji|\/icons?\/|pic\/(?:trans|cattrans|flag)|\/flags?\/|avatar|\.svg(?:$|\?))/i; +/** 按完整地址排除:豆瓣海报(含站点的豆瓣图片代理 `?https://img…doubanio.com/…poster…`)与站点横幅装饰图 */ +const NOT_SCREENSHOT_URL = /(doubanio\.com\/view\/photo\/[a-z_]*poster|\/banners?\/)/i; + export const MAX_SCREENSHOTS = 20; export const MAX_FILES = 500; @@ -36,7 +39,7 @@ export function screenshotUrl(src: string | null | undefined, base: string): str return null; } if (u.protocol !== "http:" && u.protocol !== "https:") return null; - if (NOT_SCREENSHOT.test(u.pathname)) return null; + if (NOT_SCREENSHOT.test(u.pathname) || NOT_SCREENSHOT_URL.test(u.href)) return null; return u.toString(); } diff --git a/packages/adapters/src/sites/spider/detail-page.ts b/packages/adapters/src/sites/spider/detail-page.ts index 2f2cca81..821c20ca 100644 --- a/packages/adapters/src/sites/spider/detail-page.ts +++ b/packages/adapters/src/sites/spider/detail-page.ts @@ -43,17 +43,35 @@ const normLabel = (t: string) => .replace(/[::]+$/, "") .toLowerCase(); -/** 保留换行的文本:
与块级元素换行 */ +/** 换行占位:先把
/ 块级换行记成它,再去掉 HTML 源码里的换行(浏览器按空白处理),最后还原 */ +const BR = "\u0000"; + +/** + * 保留换行的文本:
与块级元素换行。源码换行不算换行(观众的简介是 `
\r\n`, + * 两者都算会让每行之间多一空行);
 里的换行保留。
+ */
 function blockText($: CheerioAPI, el: El): string {
   const c = el.clone();
   c.find("script, style").remove();
-  c.find("br").replaceWith("\n");
-  c.find("div, p, li, tr, pre, fieldset, blockquote, h1, h2, h3, h4, h5, h6").each((_, n) => {
-    $(n).append("\n");
+  c.find("pre, textarea").each((_, n) => {
+    $(n).text($(n).text().replace(/\r?\n/g, BR));
   });
-  return tidyText(c.text());
+  c.find("br").replaceWith(BR);
+  c.find("div, p, li, tr, pre, fieldset, blockquote, h1, h2, h3, h4, h5, h6").each((_, n) => {
+    $(n).append(BR);
+  });
+  const text = c
+    .text()
+    .replace(/\r?\n/g, " ")
+    // `
\r\n下一行` 的源码换行变成了行首一个空格 + .replace(new RegExp(`${BR} `, "g"), BR) + .replaceAll(BR, "\n"); + return tidyText(text); } +/** NexusPHP MediaInfo 控件的外壳:标题栏 div.codetop、摘要表 div.show、原文 div.hide(观众三者相邻) */ +const MI_WIDGET = "div.codetop, div.show, div.hide"; + const SIZE_TAIL = /^(.*?)\s*[(([]\s*([\d.,]+\s*[KMGTP]?i?B)\s*[))\]]\s*$/i; const HAS_EXT = /\.[A-Za-z0-9]{2,5}$/; @@ -113,8 +131,9 @@ export function extractDetailPage($: CheerioAPI, conf: DetailConf, base: string) }; addLabels(conf.rowLabel, (e) => e.nextAll(conf.rowValue).first()); for (const sel of p.labelSelectors ?? []) addLabels(sel, (e) => e.next()); - const byLabel = (names: string[]): El | null => - pairs.find((x) => names.some((n) => x.label.startsWith(normLabel(n))))?.value ?? null; + const byLabel = (names: string[], exact = false): El | null => + pairs.find((x) => names.some((n) => (exact ? x.label === normLabel(n) : x.label.startsWith(normLabel(n))))) + ?.value ?? null; page.probe.labels = [...new Set(pairs.map((x) => x.label))].slice(0, 40); // 简介容器 @@ -170,10 +189,30 @@ export function extractDetailPage($: CheerioAPI, conf: DetailConf, base: string) page.probe.imageCount = imgs.length; page.screenshots = imgs.slice(0, MAX_SCREENSHOTS); - // 简介纯文本:去掉 MediaInfo 块与图片 + // 简介纯文本:去掉站点固定内容、MediaInfo 块(连同控件标题栏 / 摘要表)与图片 if (desc?.length) { const c = desc.clone(); - if (miBlockIndex >= 0) c.find(MI_BLOCKS).eq(miBlockIndex).remove(); + if (miBlockIndex >= 0) { + const isMi = (n: Parameters[0]) => looksLikeMediaInfo(blockText($, $(n))); + // 同一份 MediaInfo 常出现两次(摘要 div.show 与原文 div.hide):另外去掉最内层的 MediaInfo 块, + // 在控件外壳(div.codetop / div.show / div.hide)里时连同相邻外壳一起去掉 + const extra = c + .find(MI_BLOCKS) + .filter((_, n) => isMi(n) && !$(n).find(MI_BLOCKS).toArray().some(isMi)) + .map((_, n) => { + const e = $(n); + const shell = e.parent().is(MI_WIDGET) ? e.parent() : e; + const out = [shell.get(0)!]; + if (!shell.is(MI_WIDGET)) return out; + for (let x = shell.prev(); x.is(MI_WIDGET) && out.length < 3; x = x.prev()) out.push(x.get(0)!); + for (let x = shell.next(); x.is(MI_WIDGET) && out.length < 4; x = x.next()) out.push(x.get(0)!); + return out; + }) + .get(); + c.find(MI_BLOCKS).eq(miBlockIndex).remove(); + for (const w of extra) $(w).remove(); + } + if (p.descriptionStrip) c.find(p.descriptionStrip).remove(); c.find("img").remove(); const t = blockText($, c); if (t) page.descriptionText = t.slice(0, 20_000); @@ -221,17 +260,16 @@ export function extractDetailPage($: CheerioAPI, conf: DetailConf, base: string) // 标签 const tagEl = p.tags ? $(p.tags) : byLabel(LABELS.tags); if (tagEl?.length) { - const parts = tagEl.find("span, a").length - ? tagEl - .find("span, a") - .map((_, n) => $(n).text().trim()) - .get() - : tagEl.text().split(/[\s,,|/]+/); + // 只取最内层的 span / a(观众外面还包了一层 span.detail-tag-list,取外层会把全部标签连成一个) + const leaves = tagEl.find("span, a").filter((_, n) => $(n).find("span, a").length === 0); + const parts = leaves.length ? leaves.map((_, n) => $(n).text().trim()).get() : tagEl.text().split(/[\s,,|/]+/); page.tags = [...new Set(parts.map((t) => t.trim()).filter((t) => t && t.length <= 20))].slice(0, 20); } // 上传者 - const upEl = p.uploader ? $(p.uploader).first() : byLabel(LABELS.uploader); + // 上传者标签精确匹配:观众另有「发布者带宽」一行 + const upSel = p.uploader ? $(p.uploader).first() : null; + const upEl = upSel?.length ? upSel : byLabel(LABELS.uploader, true); if (upEl?.length) { const a = upEl.is("a") ? upEl : upEl.find("a[href*='userdetails.php']").first(); const name = (a.length ? a.text() : upEl.text()).replace(/\s+/g, " ").trim(); diff --git a/packages/adapters/src/sites/spider/detail.ts b/packages/adapters/src/sites/spider/detail.ts index ce417a5c..6f57c57b 100644 --- a/packages/adapters/src/sites/spider/detail.ts +++ b/packages/adapters/src/sites/spider/detail.ts @@ -51,8 +51,15 @@ export function parseDetailPage( .text() ) .replace(/\s+/g, " ") + // 促销到期的「剩余时间:」是 h1 的直接文本节点(观众),不属于标题 + .replace(/\s*(?:剩余时间|剩餘時間|Remaining(?: time)?)\s*[::]?\s*$/i, "") .trim(); - const subtitle = f.subtitle ? (mcSelect($, null, f.subtitle) ?? undefined) : row(conf.labels.subtitle)?.text().trim(); + const subtitleEl = f.subtitle ? null : row(conf.labels.subtitle)?.clone(); + // 副标题行右侧的豆瓣 / IMDb / 烂番茄等评分徽标(观众)不算副标题 + subtitleEl?.find("[title*='评分'], [title*='Rating'], img").remove(); + const subtitle = f.subtitle + ? (mcSelect($, null, f.subtitle) ?? undefined) + : subtitleEl?.text().replace(/\s+/g, " ").trim(); const basicText = row(conf.labels.basicInfo)?.text().replace(/\s+/g, " ") ?? ""; const sizeText = f.size ? (/([\d.,]+\s*[KMGTP]?i?B)/i.exec(mcSelect($, null, f.size) ?? "")?.[1] ?? null) @@ -64,6 +71,9 @@ export function parseDetailPage( const peersText = row(conf.labels.peers)?.text().replace(/\s+/g, " ") ?? ""; const seeders = /(\d[\d,]*)\s*个?做种者|(\d[\d,]*)\s*seeder/i.exec(peersText); const leechers = /(\d[\d,]*)\s*个?下载者|(\d[\d,]*)\s*leecher/i.exec(peersText); + // 站点把做种 / 下载 / 完成数放在其它位置时(观众:基本信息行右侧的 #seeders / #leechers / 完成链接)按选择器取 + const countOf = (sel: string | undefined) => (sel ? parseCount(mcSelect($, null, sel) ?? undefined) : null); + const infoHash = mcSelect($, null, f.infoHash)?.toLowerCase(); const descEl = $(conf.description).first(); const descText = descEl.text().trim(); const descHtml = descEl.html() ?? ""; @@ -76,17 +86,22 @@ export function parseDetailPage( list: def.torrents.list, fields: Object.fromEntries( (["downloadvolumefactor", "uploadvolumefactor", "freedate", "hr"] as const) - .filter((k) => fields[k]) - .map((k) => [k, fields[k]]), + .map((k) => [k, conf.promo?.[k] ?? fields[k]] as const) + .filter(([, v]) => v), ), }, browse: undefined, }; const promo = new SiteSpider(promoDef).infoFrom($, $(conf.headerScope).first()); // 发布时间:带完整时间的 span[title] → 「发布时间 / 上传时间 / 添加时间」字段的文本(憨憨是 div 标签 + 值) + // 标题区(headerScope)里的 span[title] 是促销到期时间,不是发布时间 const timeTitle = $("span[title]") - .filter((_, el) => /\d{4}-\d{2}-\d{2} \d{2}:\d{2}/.test($(el).attr("title") ?? "")) + .filter( + (_, el) => + /\d{4}-\d{2}-\d{2} \d{2}:\d{2}/.test($(el).attr("title") ?? "") && + $(el).closest(conf.headerScope).length === 0, + ) .first() .attr("title") ?? /(?:发布时间|上传时间|添加时间|Added)\s*[::]?\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}(?::\d{2})?)/.exec( @@ -99,9 +114,9 @@ export function parseDetailPage( title, category: { id: catId, name: catText ?? categoryName(def, catId ?? undefined) }, sizeBytes: sizeText ? parseSizeMp(sizeText) : null, - seeders: seeders ? parseCount(seeders[1] ?? seeders[2]) : null, - leechers: leechers ? parseCount(leechers[1] ?? leechers[2]) : null, - snatched: null, + seeders: seeders ? parseCount(seeders[1] ?? seeders[2]) : countOf(f.seeders), + leechers: leechers ? parseCount(leechers[1] ?? leechers[2]) : countOf(f.leechers), + snatched: countOf(f.snatched), promotion: promotionFromFactors( promo.downloadvolumefactor, promo.uploadvolumefactor, @@ -116,6 +131,7 @@ export function parseDetailPage( observedAt, }; if (subtitle) detail.subtitle = subtitle; + if (infoHash && /^[0-9a-f]{40}$/.test(infoHash)) detail.infoHash = infoHash; if (descText) detail.descriptionText = descText.slice(0, 20_000); const imdb = extractImdbId(mcSelect($, null, f.imdb)) ?? extractImdbId(descHtml) ?? extractImdbId(descText); if (imdb) detail.imdbId = imdb; diff --git a/packages/adapters/src/sites/spider/schema.ts b/packages/adapters/src/sites/spider/schema.ts index 4a7d00b8..827ac40a 100644 --- a/packages/adapters/src/sites/spider/schema.ts +++ b/packages/adapters/src/sites/spider/schema.ts @@ -196,8 +196,27 @@ export interface UmtSiteExtension { * 用于 HHClub 这类 div 详情页。 */ fields?: Partial< - Record<"title" | "subtitle" | "size" | "description" | "download" | "imdb" | "douban" | "fileList", string> + Record< + | "title" + | "subtitle" + | "size" + | "description" + | "download" + | "imdb" + | "douban" + | "fileList" + | "seeders" + | "leechers" + | "snatched" + | "infoHash", + string + > >; + /** + * 详情页促销 / H&R 字段(downloadvolumefactor / uploadvolumefactor / freedate / hr),覆盖同名列表字段。 + * 详情页头部的促销标记常与列表不同(列表 img.pro_free,详情 h1 里 font.free + 「剩余时间」span)。 + */ + promo?: Record; /** * 详情页扩展内容(简介 / MediaInfo / 截图 / 文件 / 标签 / 上传者)的站点特化,均可省略(走通用规则,见 detail-page.ts)。 * 选择器为普通 CSS。 @@ -216,6 +235,8 @@ export interface UmtSiteExtension { * 每次详情刷新最多 1 次,失败不影响详情。 */ fileListPath?: string; + /** 从简介里去掉的站点固定内容(如站点声明),普通 CSS */ + descriptionStrip?: string; }; }; /** 下载路径(按资源 ID 拼接) */ diff --git a/packages/adapters/test/differential/detail.test.ts b/packages/adapters/test/differential/detail.test.ts new file mode 100644 index 00000000..6c55841a --- /dev/null +++ b/packages/adapters/test/differential/detail.test.ts @@ -0,0 +1,96 @@ +/** + * 详情页解析回归(DET-2):观众 audiences.me 真实详情页(2026-09-30 抓取,脱敏:只留标题栏与详情表, + * 去掉用户栏 / 评论 / 「行为」行的 downhash 下载链接 / 用户链接)。MP 通用 SiteSpider 不解析详情页, + * 没有 MP 期望可比;期望值按页面原文逐项人工核对。 + */ +import { describe, expect, it } from "vitest"; +import { audiencesDefinition } from "../../src/sites/index.ts"; +import { parseDetailPage } from "../../src/sites/spider/detail.ts"; +import { readInput } from "./diff-util.ts"; + +const OBSERVED = "2026-09-30T12:11:30.000Z"; +const parse = (id: string) => { + const r = parseDetailPage( + readInput(`inputs/detail/rl-audiences-detail-${id}.html.txt`), + audiencesDefinition, + id, + OBSERVED, + ); + expect(r.kind).toBe("ok"); + return r.detail!; +}; + +describe("观众详情页(真实样本)", () => { + it("725858:原盘 DIY,50% 无期限,BDInfo", () => { + const d = parse("725858"); + expect(d).toMatchObject({ + title: "Rose 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies", + // 副标题行右侧的豆瓣 / IMDb / 烂番茄 / Metacritic 评分不进副标题 + subtitle: "罗斯 / 扑朔迷离的露丝(港)【德版原盘DIY 简繁字幕】", + category: { id: "401", name: "电影" }, + sizeBytes: 23654532383, + seeders: 126, + leechers: 1, + snatched: 276, + promotion: { type: "50%", downloadFactor: 0.5, uploadFactor: 1, expiresAt: null }, + hr: "unknown", + uploadedAt: "2026-09-27T09:25:07.000Z", + infoHash: "f7a77044521104ef2edafc0ab9bfc3774f763079", + imdbId: "tt25399154", + doubanId: "35322132", + tags: ["官方", "中字", "官字组", "DIY", "禁转"], + downloadUrl: "https://audiences.me/download.php?id=725858", + }); + const p = d.page!; + expect(p.uploader).toBe("匿名"); + expect(p.mediaInfo).toMatch(/^DISC INFO:\n\nDisc Label: {5}Rose\.2026/); + expect(p.mediaInfo).toContain("Presentation Graphics Chinese 15.892 kbps 繁体中文"); + // 简介:没有站点声明、没有 BDInfo(页面上摘要 / 原文各一份)、行间没有多余空行 + expect(p.descriptionText).toMatch(/^引用\n1\.原盘来自@4FR/); + expect(p.descriptionText).toContain("◎片  名 Rose\n◎年  代 2026\n"); + expect(p.descriptionText).not.toMatch(/声明|DISC INFO|BDInfo/); + // 截图:豆瓣海报与站点横幅不算 + expect(p.screenshots).toEqual([ + "https://stor.picx.cx/images/2026/09/27/mvuGsV.jpg", + "https://stor.picx.cx/images/2026/09/27/mvuLud.jpg", + "https://stor.picx.cx/images/2026/09/27/mvuyvF.jpg", + "https://stor.picx.cx/images/2026/09/27/mvuTGH.jpg", + "https://stor.picx.cx/images/2026/09/27/mvu7AP.jpg", + ]); + expect(p.tmdb).toBeNull(); + // 文件清单不在页面上(点击后 AJAX 加载,端点未核对),暂不另发请求 + expect(p.files).toEqual([]); + }); + + it("727077:WEB-DL 剧集,免费带到期,MediaInfo", () => { + const d = parse("727077"); + expect(d).toMatchObject({ + // h1 里「剩余时间:」文本节点不进标题 + title: "A Prophet S01E16 2026 2160p iQIYI WEB-DL H265 HDR DDP5.1-ADWeb", + subtitle: + "我不是大师 第16集 | 类型:剧情 悬疑 | 主演:李现 李一桐 吴刚 刘冠麟 果靖霖 | 长风起 / 将相 / 江相 / 我是个算命先生", + category: { id: "402", name: "剧集" }, + sizeBytes: 3575560274, + seeders: 319, + leechers: 12, + snatched: 407, + // 免费到期 2026-10-01 18:08:55(+08:00);发布时间 2026-09-30 18:08:55 不能被促销到期时间顶替 + promotion: { type: "free", downloadFactor: 0, uploadFactor: 1, expiresAt: "2026-10-01T10:08:55.000Z" }, + uploadedAt: "2026-09-30T10:08:55.000Z", + infoHash: "20183f7fe0b46b28f86a225871a2bdd0fd95e888", + imdbId: "tt36758489", + doubanId: "37297001", + tags: ["官方", "国语", "中字", "HDR10"], + }); + const p = d.page!; + expect(p.mediaInfo).toMatch(/^General\nUnique ID {32}: 274676047450136587438060874497470881694/); + expect(p.mediaInfo).toContain( + "\nVideo\nID : 1\nFormat : HEVC\n", + ); + // MediaInfo 控件的标题栏(文件名)与摘要表也不留在简介里 + expect(p.descriptionText).not.toMatch(/GeneralVideoAudio|Unique ID|\.mkv$/m); + expect(p.descriptionText).toMatch(/^引用\n请不要转发此种至PTTime/); + expect(p.screenshots).toHaveLength(6); + expect(p.screenshots.some((u) => /poster|banner/.test(u))).toBe(false); + }); +}); diff --git a/packages/adapters/test/differential/indexer.json b/packages/adapters/test/differential/indexer.json index b1664674..a074fff8 100644 --- a/packages/adapters/test/differential/indexer.json +++ b/packages/adapters/test/differential/indexer.json @@ -40,7 +40,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -339,11 +339,11 @@ "source": "definition", "id": "audiences", "file": "packages/adapters/src/sites/definitions/audiences.json", - "sha256": "fcf0aa51d84d2a192a149b802613f79163bc961f97fc8e576288627cb3d1bb08" + "sha256": "eff11683d4ac0a7c75abf8eea2ffa9dbc5fc44adbf83e05638b3f82de0d85b5b" }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -546,7 +546,7 @@ "source": "definition", "id": "audiences", "file": "packages/adapters/src/sites/definitions/audiences.json", - "sha256": "fcf0aa51d84d2a192a149b802613f79163bc961f97fc8e576288627cb3d1bb08" + "sha256": "eff11683d4ac0a7c75abf8eea2ffa9dbc5fc44adbf83e05638b3f82de0d85b5b" }, "input": { "file": "inputs/indexer/tk-hhanclub-list.html.txt", @@ -571,7 +571,7 @@ "source": "definition", "id": "audiences", "file": "packages/adapters/src/sites/definitions/audiences.json", - "sha256": "fcf0aa51d84d2a192a149b802613f79163bc961f97fc8e576288627cb3d1bb08" + "sha256": "eff11683d4ac0a7c75abf8eea2ffa9dbc5fc44adbf83e05638b3f82de0d85b5b" }, "input": { "file": "inputs/indexer/tk-chdbits-list.html.txt", @@ -674,7 +674,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -991,7 +991,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -1280,7 +1280,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -1583,7 +1583,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -1886,7 +1886,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -2203,7 +2203,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -2278,7 +2278,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -2581,7 +2581,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -2852,11 +2852,11 @@ "source": "definition", "id": "hhanclub", "file": "packages/adapters/src/sites/definitions/hhanclub.json", - "sha256": "a15c4b4496a22368c85b7cba5bada167c2cc191893b632cbfda4ce9627a161d5" + "sha256": "7b765193b1298f7b319f9598cd88d3aadb507c6cf4e0bf9f42406ea0799cfac3" }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -2877,7 +2877,7 @@ "source": "definition", "id": "hhanclub", "file": "packages/adapters/src/sites/definitions/hhanclub.json", - "sha256": "a15c4b4496a22368c85b7cba5bada167c2cc191893b632cbfda4ce9627a161d5" + "sha256": "7b765193b1298f7b319f9598cd88d3aadb507c6cf4e0bf9f42406ea0799cfac3" }, "input": { "file": "inputs/indexer/tk-hhanclub-list.html.txt", @@ -2970,7 +2970,7 @@ "source": "definition", "id": "hhanclub", "file": "packages/adapters/src/sites/definitions/hhanclub.json", - "sha256": "a15c4b4496a22368c85b7cba5bada167c2cc191893b632cbfda4ce9627a161d5" + "sha256": "7b765193b1298f7b319f9598cd88d3aadb507c6cf4e0bf9f42406ea0799cfac3" }, "input": { "file": "inputs/indexer/tk-chdbits-list.html.txt", @@ -2999,7 +2999,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -3302,7 +3302,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -3619,7 +3619,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -3936,7 +3936,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -4239,7 +4239,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -4528,7 +4528,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -4831,7 +4831,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -5120,7 +5120,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -5423,7 +5423,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -5740,7 +5740,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -6017,7 +6017,7 @@ }, "input": { "file": "inputs/indexer/tk-audiences-list.html.txt", - "sha256": "c9f4e36ea44b1fddb36a90c9906f90e2e303413247efb487f8d296f143ed8f5f" + "sha256": "dbac4c78c5cb9611dc6b23fffa683b8ffdc6dc55ebf35f66058efa9cd1b3196e" }, "query": { "keyword": "x", @@ -6088,11 +6088,11 @@ "source": "definition", "id": "audiences", "file": "packages/adapters/src/sites/definitions/audiences.json", - "sha256": "fcf0aa51d84d2a192a149b802613f79163bc961f97fc8e576288627cb3d1bb08" + "sha256": "eff11683d4ac0a7c75abf8eea2ffa9dbc5fc44adbf83e05638b3f82de0d85b5b" }, "input": { "file": "inputs/indexer/tk-audiences-login.html.txt", - "sha256": "e97696e6b9b1bfd5b14a7e16b18ca1e0cb98d553ad6363bb8d70a557741de92c" + "sha256": "211059cfefde33331b8e04482ebf8c6d50a591b389eb28fc6a7d53fa3c31182d" }, "query": { "keyword": "x", @@ -6132,6 +6132,393 @@ "torrents": [] } }, + { + "id": "audiences@rl-audiences-list", + "definition": { + "source": "definition", + "id": "audiences", + "file": "packages/adapters/src/sites/definitions/audiences.json", + "sha256": "eff11683d4ac0a7c75abf8eea2ffa9dbc5fc44adbf83e05638b3f82de0d85b5b" + }, + "input": { + "file": "inputs/indexer/rl-audiences-list.html.txt", + "sha256": "cc4ce084fdf1a8f514cfad312a92db71049f22b347c1b8d1fcc9f49e70c8ee82" + }, + "query": { + "keyword": "x", + "search_type": "torrents" + }, + "mp": { + "is_error": false, + "torrents": [ + { + "title": "Only Bears 2026 1080p Creator Provided AAC AV1-PosiBear", + "description": "何止是熊 | 2026年熊族浪漫喜剧短片 | 标签:男同性恋 / 熊 / 浪漫", + "page_url": "https://audiences.me/details.php?id=727091&hit=1", + "enclosure": "https://audiences.me/download.php?id=727091", + "grabs": 0, + "peers": 93, + "seeders": 1, + "size": 503222108, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 19:31:59", + "date_elapsed": "38分", + "freedate": null, + "labels": ["原创", "中字", "首发"], + "category": "电影" + }, + { + "title": "Leviticus 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies", + "description": "利未记 / 爱的魔样(台) / 少年同志驱魔记(港)【原盘DIY 简繁双语字幕】", + "page_url": "https://audiences.me/details.php?id=726624&hit=1", + "enclosure": "https://audiences.me/download.php?id=726624", + "grabs": 199, + "peers": 5, + "seeders": 121, + "size": 24953759990, + "imdbid": "tt39143902", + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-29 17:56:48", + "date_elapsed": "1天\n2时", + "freedate": null, + "labels": ["官方", "中字", "官字组", "DIY"], + "category": "电影" + }, + { + "title": "A New Dawn 2026 1080p BluRay Remux AVC DTS-HD MA 5.1-Nest@ADE", + "description": "花绿青绽放之日 / 花绿青绽放之时(港 / 台) / 新的黎明 / A New Dawn / Une aube nouvelle / 花緑青が明ける日に [中日双语字幕]", + "page_url": "https://audiences.me/details.php?id=726336&hit=1", + "enclosure": "https://audiences.me/download.php?id=726336", + "grabs": 320, + "peers": 0, + "seeders": 142, + "size": 23643794964, + "imdbid": null, + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-29 00:20:16", + "date_elapsed": "1天\n19时", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "动画", "禁转", "应求"], + "category": "电影" + }, + { + "title": "Out of the Past 1947 2160p UHD BluRay HEVC DV DTS-HD MA 2.0-Runrun@Audies", + "description": "漩涡之外 / 旧恨新欢(港) / 来自过去 / Build My Gallows High【IG菜单新增按钮】【华纳WAC版UHD原盘DIY/简繁双语中字】", + "page_url": "https://audiences.me/details.php?id=726249&hit=1", + "enclosure": "https://audiences.me/download.php?id=726249", + "grabs": 208, + "peers": 0, + "seeders": 112, + "size": 63093069578, + "imdbid": "tt0039689", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-28 21:28:11", + "date_elapsed": "1天\n22时", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY", "Dolby Vision", "HDR10"], + "category": "电影" + }, + { + "title": "The Invite 2026 1080p BluRay AVC TrueHD 5.1-DIY@Audies", + "description": "激情邀约 / 诱人饭聚(港) / 开放性邀请(台) / 多愁善感(美版) / 邀请【原盘DIY 简繁双语字幕】", + "page_url": "https://audiences.me/details.php?id=726196&hit=1", + "enclosure": "https://audiences.me/download.php?id=726196", + "grabs": 246, + "peers": 0, + "seeders": 119, + "size": 30300994273, + "imdbid": "tt14173636", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-28 15:29:02", + "date_elapsed": "2天\n4时", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY", "禁转"], + "category": "电影" + }, + { + "title": "Rose 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies", + "description": "罗斯 / 扑朔迷离的露丝(港)【德版原盘DIY 简繁字幕】", + "page_url": "https://audiences.me/details.php?id=725858&hit=1", + "enclosure": "https://audiences.me/download.php?id=725858", + "grabs": 276, + "peers": 1, + "seeders": 126, + "size": 23654532383, + "imdbid": "tt25399154", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-27 17:25:07", + "date_elapsed": "3天", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY", "禁转"], + "category": "电影" + }, + { + "title": "Passenger 2026 1080p GBR BluRay AVC TrueHD 7.1 Atmos-DIY@Audies", + "description": "鬼上车 / 乘吓(港) / 亡命旅人 【英版原盘DIY/双语简繁字幕】", + "page_url": "https://audiences.me/details.php?id=725737&hit=1", + "enclosure": "https://audiences.me/download.php?id=725737", + "grabs": 197, + "peers": 0, + "seeders": 85, + "size": 30161407836, + "imdbid": "tt33763941", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-27 10:52:51", + "date_elapsed": "3天", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY"], + "category": "电影" + }, + { + "title": "The Spirealm Voyager S01E06 2026 2160p WEB-DL H265 DDP2.0-ADWeb", + "description": "[国创连载] 灵境行者 第06集 | 类型:动作 动画 奇幻 | 灵境行者之夜游神篇", + "page_url": "https://audiences.me/details.php?id=727090&hit=1", + "enclosure": "https://audiences.me/download.php?id=727090", + "grabs": 364, + "peers": 16, + "seeders": 290, + "size": 694713057, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 19:31:15", + "date_elapsed": "39分", + "freedate": null, + "labels": ["官方", "国语", "中字", "动画"], + "category": "电视剧" + }, + { + "title": "A Prophet S01E16 2026 2160p iQIYI WEB-DL H265 HDR DDP5.1-ADWeb", + "description": "我不是大师 第16集 | 类型:剧情 悬疑 | 主演:李现 李一桐 吴刚 刘冠麟 果靖霖 | 长风起 / 将相 / 江相 / 我是个算命先生", + "page_url": "https://audiences.me/details.php?id=727077&hit=1", + "enclosure": "https://audiences.me/download.php?id=727077", + "grabs": 406, + "peers": 13, + "seeders": 318, + "size": 3575560274, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 18:08:55", + "date_elapsed": "2时\n1分", + "freedate": null, + "labels": ["官方", "国语", "中字", "HDR10"], + "category": "电视剧" + }, + { + "title": "Heart Signal S09E34 2026 1080p WEB-DL H265 AAC-ADWeb", + "description": "心动的信号 第九季 正片 第10期下:最终抉择,玥儿做出最终决定 | 心动的信号9", + "page_url": "https://audiences.me/details.php?id=727036&hit=1", + "enclosure": "https://audiences.me/download.php?id=727036", + "grabs": 139, + "peers": 3, + "seeders": 78, + "size": 558083604, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 17:01:46", + "date_elapsed": "3时\n9分", + "freedate": null, + "labels": ["官方", "国语", "中字"], + "category": "电视剧" + } + ] + }, + "mp_rust": { + "is_error": false, + "torrents": [ + { + "title": "Only Bears 2026 1080p Creator Provided AAC AV1-PosiBear", + "description": "何止是熊 | 2026年熊族浪漫喜剧短片 | 标签:男同性恋 / 熊 / 浪漫", + "page_url": "https://audiences.me/details.php?id=727091&hit=1", + "enclosure": "https://audiences.me/download.php?id=727091", + "grabs": 0, + "peers": 93, + "seeders": 1, + "size": 503222108, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 19:31:59", + "date_elapsed": "38分", + "freedate": null, + "labels": ["原创", "中字", "首发"], + "category": "电影" + }, + { + "title": "Leviticus 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies", + "description": "利未记 / 爱的魔样(台) / 少年同志驱魔记(港)【原盘DIY 简繁双语字幕】", + "page_url": "https://audiences.me/details.php?id=726624&hit=1", + "enclosure": "https://audiences.me/download.php?id=726624", + "grabs": 199, + "peers": 5, + "seeders": 121, + "size": 24953759990, + "imdbid": "tt39143902", + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-29 17:56:48", + "date_elapsed": "1天\n2时", + "freedate": null, + "labels": ["官方", "中字", "官字组", "DIY"], + "category": "电影" + }, + { + "title": "A New Dawn 2026 1080p BluRay Remux AVC DTS-HD MA 5.1-Nest@ADE", + "description": "花绿青绽放之日 / 花绿青绽放之时(港 / 台) / 新的黎明 / A New Dawn / Une aube nouvelle / 花緑青が明ける日に [中日双语字幕]", + "page_url": "https://audiences.me/details.php?id=726336&hit=1", + "enclosure": "https://audiences.me/download.php?id=726336", + "grabs": 320, + "peers": 0, + "seeders": 142, + "size": 23643794964, + "imdbid": null, + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-29 00:20:16", + "date_elapsed": "1天\n19时", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "动画", "禁转", "应求"], + "category": "电影" + }, + { + "title": "Out of the Past 1947 2160p UHD BluRay HEVC DV DTS-HD MA 2.0-Runrun@Audies", + "description": "漩涡之外 / 旧恨新欢(港) / 来自过去 / Build My Gallows High【IG菜单新增按钮】【华纳WAC版UHD原盘DIY/简繁双语中字】", + "page_url": "https://audiences.me/details.php?id=726249&hit=1", + "enclosure": "https://audiences.me/download.php?id=726249", + "grabs": 208, + "peers": 0, + "seeders": 112, + "size": 63093069578, + "imdbid": "tt0039689", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-28 21:28:11", + "date_elapsed": "1天\n22时", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY", "Dolby Vision", "HDR10"], + "category": "电影" + }, + { + "title": "The Invite 2026 1080p BluRay AVC TrueHD 5.1-DIY@Audies", + "description": "激情邀约 / 诱人饭聚(港) / 开放性邀请(台) / 多愁善感(美版) / 邀请【原盘DIY 简繁双语字幕】", + "page_url": "https://audiences.me/details.php?id=726196&hit=1", + "enclosure": "https://audiences.me/download.php?id=726196", + "grabs": 246, + "peers": 0, + "seeders": 119, + "size": 30300994273, + "imdbid": "tt14173636", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-28 15:29:02", + "date_elapsed": "2天\n4时", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY", "禁转"], + "category": "电影" + }, + { + "title": "Rose 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies", + "description": "罗斯 / 扑朔迷离的露丝(港)【德版原盘DIY 简繁字幕】", + "page_url": "https://audiences.me/details.php?id=725858&hit=1", + "enclosure": "https://audiences.me/download.php?id=725858", + "grabs": 276, + "peers": 1, + "seeders": 126, + "size": 23654532383, + "imdbid": "tt25399154", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-27 17:25:07", + "date_elapsed": "3天", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY", "禁转"], + "category": "电影" + }, + { + "title": "Passenger 2026 1080p GBR BluRay AVC TrueHD 7.1 Atmos-DIY@Audies", + "description": "鬼上车 / 乘吓(港) / 亡命旅人 【英版原盘DIY/双语简繁字幕】", + "page_url": "https://audiences.me/details.php?id=725737&hit=1", + "enclosure": "https://audiences.me/download.php?id=725737", + "grabs": 197, + "peers": 0, + "seeders": 85, + "size": 30161407836, + "imdbid": "tt33763941", + "downloadvolumefactor": 0.5, + "uploadvolumefactor": 1, + "pubdate": "2026-09-27 10:52:51", + "date_elapsed": "3天", + "freedate": "50%", + "labels": ["官方", "中字", "官字组", "DIY"], + "category": "电影" + }, + { + "title": "The Spirealm Voyager S01E06 2026 2160p WEB-DL H265 DDP2.0-ADWeb", + "description": "[国创连载] 灵境行者 第06集 | 类型:动作 动画 奇幻 | 灵境行者之夜游神篇", + "page_url": "https://audiences.me/details.php?id=727090&hit=1", + "enclosure": "https://audiences.me/download.php?id=727090", + "grabs": 364, + "peers": 16, + "seeders": 290, + "size": 694713057, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 19:31:15", + "date_elapsed": "39分", + "freedate": null, + "labels": ["官方", "国语", "中字", "动画"], + "category": "电视剧" + }, + { + "title": "A Prophet S01E16 2026 2160p iQIYI WEB-DL H265 HDR DDP5.1-ADWeb", + "description": "我不是大师 第16集 | 类型:剧情 悬疑 | 主演:李现 李一桐 吴刚 刘冠麟 果靖霖 | 长风起 / 将相 / 江相 / 我是个算命先生", + "page_url": "https://audiences.me/details.php?id=727077&hit=1", + "enclosure": "https://audiences.me/download.php?id=727077", + "grabs": 406, + "peers": 13, + "seeders": 318, + "size": 3575560274, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 18:08:55", + "date_elapsed": "2时\n1分", + "freedate": null, + "labels": ["官方", "国语", "中字", "HDR10"], + "category": "电视剧" + }, + { + "title": "Heart Signal S09E34 2026 1080p WEB-DL H265 AAC-ADWeb", + "description": "心动的信号 第九季 正片 第10期下:最终抉择,玥儿做出最终决定 | 心动的信号9", + "page_url": "https://audiences.me/details.php?id=727036&hit=1", + "enclosure": "https://audiences.me/download.php?id=727036", + "grabs": 139, + "peers": 3, + "seeders": 78, + "size": 558083604, + "imdbid": null, + "downloadvolumefactor": 0, + "uploadvolumefactor": 1, + "pubdate": "2026-09-30 17:01:46", + "date_elapsed": "3时\n9分", + "freedate": null, + "labels": ["官方", "国语", "中字"], + "category": "电视剧" + } + ] + } + }, { "id": "hw-dsl-case@hw-dsl-rows", "definition": { diff --git a/packages/adapters/test/differential/inputs/detail/rl-audiences-detail-725858.html.txt b/packages/adapters/test/differential/inputs/detail/rl-audiences-detail-725858.html.txt new file mode 100644 index 00000000..821c5583 --- /dev/null +++ b/packages/adapters/test/differential/inputs/detail/rl-audiences-detail-725858.html.txt @@ -0,0 +1,164 @@ + +观众 :: 种子详情 - Powered by NexusPHP +
+

Rose 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies    [50%]

+
+ + + + + + + + + + + + + + +
下载[Audiences].Rose.2026.1080p.BluRay.AVC.DTS-HD.MA.5.1-DIY@Audies.torrent     由 匿名发布于3天前
副标题
罗斯 / 扑朔迷离的露丝(港)【德版原盘DIY 简繁字幕】
豆瓣8.7/10IMDb7.6/10Rotten Tomatoes100%Metacritic88/100
基本信息大小:22.03 GB   类型: 电影   媒介: Blu-ray DIY   编码: H.264(AVC)   分辨率: 1080p   音频编码: DTS-HD MA   制作组: Audies1261276
标签官方中字官字组DIY禁转
Show/Hide豆瓣信息
罗斯 2026 · 电影 · 奥地利 / 德国 · 德语 · 剧情
Show/Hide IMDb信息
Rose 2026 · Austria, Germany · German · Biography, Drama, History
Show/Hide 简介
引用
声明:
+Audiences提供的所有资源均是在网上搜集且由用户上传,不可用于任何形式的商业盈利活动!
+否则产生的一切后果将由您自己承担,本站将不对本站的任何内容负任何法律责任!
+该内容仅做为宽带测试、学习交流等使用,请在下载后24小时内尽快删除。
+如喜欢该作品请支持正版!正版!


+
引用
1.原盘来自@4FR,字幕OCR自微博@乱耳飞舞字幕组。
+2.由BelamiMN@Audiences完成字幕逐句精校。
+3.追加简繁共两个字幕,右键调出。
+4.PowerDVD20,PotPlayer测试播放通过,其他播放器自行测试。
+5.在此感谢各位原作者及分享者!如有侵权请联系删除


+
+image
+
+◎译  名  罗斯 / 扑朔迷离的露丝(港)
+◎片  名 Rose
+◎年  代 2026
+◎产  地 奥地利 / 德国
+◎类  别 剧情
+◎语  言 德语
+◎上映日期 2026-04-30(德国) / 2026-04-17(奥地利) / 2026-02-15(柏林电影节)
+◎IMDb链接  https://www.imdb.com/title/tt25399154/
+◎豆瓣评分 8.7/10 from 7625 users
+◎豆瓣链接 https://movie.douban.com/subject/35322132/
+◎导  演  马库斯·施莱泽 Markus Schleinzer
+◎编  剧  马库斯·施莱泽 Markus Schleinzer / 亚历山大·布罗姆 Alexander Brom
+◎主  演  桑德拉·惠勒 Sandra Hüller
+           卡洛·布劳恩 Caro Braun
+           玛丽莎·格罗瓦尔德 Marisa Growaldt
+           戈德哈尔德·吉瑟 Godehard Giese
+           奥古斯丁诺·伦肯 Augustino Renken
+           罗伯特·格维斯戴克 Robert Gwisdek
+           玛丽亚·德拉格斯 Maria Dragus
+           斯文·埃里克·贝希托夫 Sven Eric Bechtolf
+           赖纳·埃格 Rainer Egger
+           Maurice Leonhard Maurice Leonhard
+           Annalisa Hohl Annalisa Hohl
+           Anne Klein Anne Klein
+           巴斯蒂安·特罗斯特 Bastian Trost
+
+◎标  签  女性 | 历史
+
+◎简  介  
+
+ 故事取材于欧洲历史上多起女扮男装的真实事件。十七世纪早期,三十年战争结束后,一个女人伪装成一名叫“罗斯”的士兵出现在一个偏僻的新教村庄,声称自己是一座荒废庄园的继承者,努力获得村民的接纳。
+
+image
+

+DISC INFO:
+
+Disc Label:     Rose.2026.1080p.BluRay.AVC.DTS-HD.MA.5.1-DIY@Audies
+Disc Size:      23,653,376,335 bytes
+Protection:     AACS
+Extras:         BD-Java
+BDInfo:         0.7.5.8
+
+PLAYLIST REPORT:
+
+Name:                   00008.MPLS
+Length:                 1:34:13.250 (h:m:s.ms)
+Size:                   23,379,640,320 bytes
+Total Bitrate:          33.08 Mbps
+
+VIDEO:
+
+Codec                   Bitrate             Description    
+-----                   -------             -----------    
+MPEG-4 AVC Video        27450 kbps          1080p / 24 fps / 16:9 / High Profile 4.1
+
+AUDIO:
+
+Codec                           Language        Bitrate         Description    
+-----                           --------        -------         -----------    
+DTS-HD Master Audio             German          1759 kbps       5.1 / 48 kHz /  1759 kbps / 16-bit (DTS Core: 5.1 / 48 kHz /  1509 kbps / 16-bit)
+DTS-HD Master Audio             German          821 kbps        2.0 / 48 kHz /   821 kbps / 16-bit (DTS Core: 2.0 / 48 kHz /   512 kbps / 16-bit)
+DTS-HD Master Audio             German          776 kbps        2.0 / 48 kHz /   776 kbps / 16-bit (DTS Core: 2.0 / 48 kHz /   256 kbps / 16-bit)
+
+SUBTITLES:
+
+Codec                           Language        Bitrate         Description    
+-----                           --------        -------         -----------    
+Presentation Graphics           German          24.351 kbps                    
+Presentation Graphics           Chinese         15.778 kbps     简体中文                    
+Presentation Graphics           Chinese         15.892 kbps     繁体中文                    
+
+
+

+DISC INFO:
+
+Disc Label:     Rose.2026.1080p.BluRay.AVC.DTS-HD.MA.5.1-DIY@Audies
+Disc Size:      23,653,376,335 bytes
+Protection:     AACS
+Extras:         BD-Java
+BDInfo:         0.7.5.8
+
+PLAYLIST REPORT:
+
+Name:                   00008.MPLS
+Length:                 1:34:13.250 (h:m:s.ms)
+Size:                   23,379,640,320 bytes
+Total Bitrate:          33.08 Mbps
+
+VIDEO:
+
+Codec                   Bitrate             Description    
+-----                   -------             -----------    
+MPEG-4 AVC Video        27450 kbps          1080p / 24 fps / 16:9 / High Profile 4.1
+
+AUDIO:
+
+Codec                           Language        Bitrate         Description    
+-----                           --------        -------         -----------    
+DTS-HD Master Audio             German          1759 kbps       5.1 / 48 kHz /  1759 kbps / 16-bit (DTS Core: 5.1 / 48 kHz /  1509 kbps / 16-bit)
+DTS-HD Master Audio             German          821 kbps        2.0 / 48 kHz /   821 kbps / 16-bit (DTS Core: 2.0 / 48 kHz /   512 kbps / 16-bit)
+DTS-HD Master Audio             German          776 kbps        2.0 / 48 kHz /   776 kbps / 16-bit (DTS Core: 2.0 / 48 kHz /   256 kbps / 16-bit)
+
+SUBTITLES:
+
+Codec                           Language        Bitrate         Description    
+-----                           --------        -------         -----------    
+Presentation Graphics           German          24.351 kbps                    
+Presentation Graphics           Chinese         15.778 kbps     简体中文                    
+Presentation Graphics           Chinese         15.892 kbps     繁体中文                    
+
+
+


+
+image
+image
+
+image
+
+image
+
+image
+
+image
其它版本6个其它版本
种子文件
文件数:76个文件     种子Hash
热度表 + + + + +
查看: 741点击: 553完成: 276最近活动:3分前
+
+
+
+
diff --git a/packages/adapters/test/differential/inputs/detail/rl-audiences-detail-727077.html.txt b/packages/adapters/test/differential/inputs/detail/rl-audiences-detail-727077.html.txt new file mode 100644 index 00000000..12e83cd8 --- /dev/null +++ b/packages/adapters/test/differential/inputs/detail/rl-audiences-detail-727077.html.txt @@ -0,0 +1,192 @@ + +观众 :: 种子详情 - Powered by NexusPHP +
+

A Prophet S01E16 2026 2160p iQIYI WEB-DL H265 HDR DDP5.1-ADWeb    [免费] 剩余时间:21时57分

+
+ + + + + + + + + + + + + + +
下载[Audiences].我不是大师.A.Prophet.S01.2026.2160p.iQIYI.WEB-DL.H265.HDR.DDP5.1-ADWeb.torrent     由 匿名发布于2时2分前
副标题我不是大师 第16集 | 类型:剧情 悬疑 | 主演:李现 李一桐 吴刚 刘冠麟 果靖霖 | 长风起 / 将相 / 江相 / 我是个算命先生
基本信息大小:3.33 GB   类型: 剧集   媒介: WEB-DL   编码: H.265(HEVC)   分辨率: 4K   音频编码: DD/AC3   制作组: ADWeb   季: 1   集: 1631912407
标签官方国语中字HDR10
Show/Hide豆瓣信息
我不是大师 2026 · 剧集 · 中国大陆 · 汉语普通话 · 剧情/悬疑
Show/Hide IMDb信息
Show/Hide 简介
引用
声明:
+Audiences提供的所有资源均是在网上搜集且由用户上传,不可用于任何形式的商业盈利活动!
+否则产生的一切后果将由您自己承担,本站将不对本站的任何内容负任何法律责任!
+该内容仅做为宽带测试、学习交流等使用,请在下载后24小时内尽快删除。
+如喜欢该作品请支持正版!正版!


+
引用
请不要转发此种至PTTime,谢谢!祝您观影愉快!
+If you support us, For safety reason, Please do not forward this torrent to PTTime, Thanks! Enjoy your movie!

image
+
+◎译  名  长风起 / 将相 / 江相 / 我是个算命先生
+◎片  名 我不是大师
+◎年  代 2026
+◎产  地 中国大陆
+◎类  别 剧情 / 悬疑
+◎语  言 汉语普通话
+◎上映日期 2026-09-24(中国大陆)
+◎IMDb链接  https://www.imdb.com/title/tt36758489/
+◎豆瓣评分 /10 from 0 users
+◎豆瓣链接 https://movie.douban.com/subject/37297001/
+◎集  数 24
+◎片  长 45分钟
+◎导  演  杨磊 Lei Yang
+◎编  剧  杨哲 Zhe Yang /  
+◎主  演  李现 Xian Li
+           李一桐 Yitong Li
+           吴刚 Gang Wu
+           刘冠麟 Guanlin Liu
+           果靖霖 Jinglin Guo
+           海一天 Yitian Hai
+           梁天 Tian Liang
+           岳旸 Yang Yue
+           杨一威 Yiwei Yang
+           张晶伟 Jingwei Zhang
+           张晓谦 Xiaoqian Zhang
+           黄小蕾 Xiaolei Huang
+           薛佳凝 Jianing Xue
+           罗海琼 Haiqiong Luo
+           王沛禄 Peilu Wang
+           魏千翔 Qianxiang Wei
+           艾晓琪 Xiaoqi Ai
+           宋奕星 Xinjiayi Song
+           王奕婷 Yiting Wang
+           刘美含 Meihan Liu
+           黄奕 Yi Huang
+           徐洋 Yang Xu
+           孙爽 Shuang Sun
+           李殿尊 Dianzun Li
+           艾霖 Lin Ai
+
+◎简  介  
+
+ 上官诚明全家惨遭天相派设局灭门,他化名潜伏,以牙还牙,以眼还眼,联手身陷泥淖却势要逆天改命的江飞燕,用连环骗局反噬仇敌,一路揭露骗术黑幕,最终瓦解天相派,解救受控者,惩恶扬善终彰善念。
+  
+  改编自易之小说《我是个算命先生》。
+image
+
+
引用
★★★★★ General Information ★★★★★
+
+RELEASE.NAME...: 我不是大师.A.Prophet.S01E16.2026.2160p.iQIYI.WEB-DL.H265.HDR.DDP5.1-ADWeb
+RELEASE.TIME...: 2026-09-30 10:08:19.286 UTC
+RELEASE.SIZE...: 3.33 GiB
+RELEASE.FORMAT.: Matroska
+DURATION.......: 00:44:30.991 (HH:MM:SS.MMM)
+OVERALL.BITRATE: 10.7 Mb/s
+VIDEO.CODEC....: HEVC Main 10@L5@Main @ 10.3 Mb/s
+FRAME.RATE.....: 25.000 FPS
+RESOLUTION.....: 3840 x 1920
+HDR.FORMAT.....: HDR Vivid, Version 1
+AUDIO.1........: 普通话 DDP Dolby Digital Plus 6 channels @ 256 kb/s
+AUDIO.2........: 普通话 AAC AAC 2 channels @ 192 kb/s
+UPLOADER.......: ADWeb
+


+image
+
+image
+image
+image
+image
+
GeneralVideoAudio(2)Subtitles
Format: Matroska
Duration: 44 min 30 s
File Size: 3.33 GiB
Bit Rate: 10.7mb/s
Format: HEVC (10 bits)
Bit Rate: 10.3mb/s
Resolution: 3840*1920 (2.000)
Frame Rate: 25.000 FPS
HDR: HDR Vivid, Version 1
Chinese (China) E-AC-3 5.1ch @ 256kb/s (普通话 DDP)
Chinese (China) AAC LC 2.0ch @ 192kb/s (普通话 AAC)
General
+Unique ID                                : 274676047450136587438060874497470881694 (0xCEA4AEB6F1D87A4D7C1CEDF56399DF9E)
+Complete name                            : 我不是大师.A.Prophet.S01E16.2026.2160p.iQIYI.WEB-DL.H265.HDR.DDP5.1-ADWeb.mkv
+Format                                   : Matroska
+Format version                           : Version 4
+File size                                : 3.33 GiB
+Duration                                 : 44 min 30 s
+Overall bit rate                         : 10.7 Mb/s
+Frame rate                               : 25.000 FPS
+Encoded date                             : 2026-09-30 10:08:15 UTC
+Writing application                      : mkvmerge 100.0 ('Do Hot Girls Like Chords') 64-bit
+Writing library                          : libebml v1.4.5 + libmatroska v1.7.1
+
+Video
+ID                                       : 1
+Format                                   : HEVC
+Format/Info                              : High Efficiency Video Coding
+Format profile                           : Main 10@L5@Main
+HDR format                               : HDR Vivid, Version 1
+Codec ID                                 : V_MPEGH/ISO/HEVC
+Duration                                 : 44 min 30 s
+Bit rate                                 : 10.3 Mb/s
+Width                                    : 3 840 pixels
+Height                                   : 1 920 pixels
+Display aspect ratio                     : 2.000
+Frame rate mode                          : Constant
+Frame rate                               : 25.000 FPS
+Color space                              : YUV
+Chroma subsampling                       : 4:2:0
+Bit depth                                : 10 bits
+Bits/(Pixel*Frame)                       : 0.056
+Stream size                              : 3.19 GiB (96%)
+Default                                  : Yes
+Forced                                   : No
+Color range                              : Limited
+Color primaries                          : BT.2020
+Transfer characteristics                 : PQ
+Matrix coefficients                      : BT.2020 non-constant
+Mastering display color primaries        : R: x=0.708000 y=0.292000, G: x=0.170000 y=0.797000, B: x=0.130000 y=0.046000, White point: x=0.312700 y=0.329000
+Mastering display luminance              : min: 0.0001 cd/m2, max: 1000 cd/m2
+Maximum Content Light Level              : 748 cd/m2
+Maximum Frame-Average Light Level        : 25 cd/m2
+
+Audio #1
+ID                                       : 2
+Format                                   : E-AC-3
+Format/Info                              : Enhanced AC-3
+Commercial name                          : Dolby Digital Plus
+Codec ID                                 : A_EAC3
+Duration                                 : 44 min 30 s
+Bit rate mode                            : Constant
+Bit rate                                 : 256 kb/s
+Channel(s)                               : 6 channels
+Channel layout                           : L R C LFE Ls Rs
+Sampling rate                            : 48.0 kHz
+Frame rate                               : 31.250 FPS (1536 SPF)
+Compression mode                         : Lossy
+Stream size                              : 81.5 MiB (2%)
+Title                                    : 普通话 DDP
+Language                                 : Chinese (China)
+Service kind                             : Complete Main
+Default                                  : Yes
+Forced                                   : No
+Dialog Normalization                     : -20 dB
+compr                                    : -0.28 dB
+dialnorm_Average                         : -20 dB
+dialnorm_Minimum                         : -20 dB
+dialnorm_Maximum                         : -20 dB
+
+Audio #2
+ID                                       : 3
+Format                                   : AAC LC
+Format/Info                              : Advanced Audio Codec Low Complexity
+Codec ID                                 : A_AAC-2
+Duration                                 : 44 min 30 s
+Bit rate                                 : 192 kb/s
+Channel(s)                               : 2 channels
+Channel layout                           : L R
+Sampling rate                            : 44.1 kHz
+Frame rate                               : 43.066 FPS (1024 SPF)
+Compression mode                         : Lossy
+Stream size                              : 60.5 MiB (2%)
+Title                                    : 普通话 AAC
+Language                                 : Chinese (China)
+Default                                  : No
+Forced                                   : No
+
+
+

其它版本46个其它版本
种子文件
文件数:1个文件     种子Hash
热度表 + + + + +
查看: 99点击: 492完成: 407最近活动:< 1分前
+
+
diff --git a/packages/adapters/test/differential/inputs/indexer/rl-audiences-list.html.txt b/packages/adapters/test/differential/inputs/indexer/rl-audiences-list.html.txt new file mode 100644 index 00000000..211b3b92 --- /dev/null +++ b/packages/adapters/test/differential/inputs/indexer/rl-audiences-list.html.txt @@ -0,0 +1,203 @@ + +观众 :: 种子 - Powered by NexusPHP +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
类型 + + + + 标题 + + + + + + + + + +
电影Not Allowed
+
Only Bears 2026 1080p Creator Provided AAC AV1-PosiBear Free 剩余时间:23时21分
原创中字首发何止是熊 | 2026年熊族浪漫喜剧短片 | 标签:男同性恋 / 熊 / 浪漫
038分479.91
MB
1930
匿名
电影Blu-ray DIY
+
Leviticus 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies [热门] Free 剩余时间:9时46分
官方中字官字组DIY利未记 / 爱的魔样(台) / 少年同志驱魔记(港)【原盘DIY 简繁双语字幕】
01天
2时
23.24
GB
1215199
匿名
电影Remux
+
A New Dawn 2026 1080p BluRay Remux AVC DTS-HD MA 5.1-Nest@ADE [热门] 50%
官方中字官字组动画禁转应求花绿青绽放之日 / 花绿青绽放之时(港 / 台) / 新的黎明 / A New Dawn / Une aube nouvelle / 花緑青が明ける日に [中日双语字幕]
01天
19时
22.02
GB
1420320
匿名
电影UHD Blu-ray DIY
+
Out of the Past 1947 2160p UHD BluRay HEVC DV DTS-HD MA 2.0-Runrun@Audies [热门] 50%
官方中字官字组DIYDolby VisionHDR10漩涡之外 / 旧恨新欢(港) / 来自过去 / Build My Gallows High【IG菜单新增按钮】【华纳WAC版UHD原盘DIY/简繁双语中字】
8.18.087%85
21天
22时
58.76
GB
1120208
匿名
电影Blu-ray DIY
+
The Invite 2026 1080p BluRay AVC TrueHD 5.1-DIY@Audies [热门] 50%
官方中字官字组DIY禁转激情邀约 / 诱人饭聚(港) / 开放性邀请(台) / 多愁善感(美版) / 邀请【原盘DIY 简繁双语字幕】
7.97.896%82
12天
4时
28.22
GB
1190246
匿名
电影Blu-ray DIY
+
Rose 2026 1080p BluRay AVC DTS-HD MA 5.1-DIY@Audies [热门] 50%
官方中字官字组DIY禁转罗斯 / 扑朔迷离的露丝(港)【德版原盘DIY 简繁字幕】
8.77.6100%88
23天22.03
GB
1261276
匿名
电影Blu-ray DIY
+
Passenger 2026 1080p GBR BluRay AVC TrueHD 7.1 Atmos-DIY@Audies [热门] 50%
官方中字官字组DIY鬼上车 / 乘吓(港) / 亡命旅人 【英版原盘DIY/双语简繁字幕】
6.05.546%52
03天28.09
GB
850197
匿名
剧集WebDL 2160p
+
The Spirealm Voyager S01E06 2026 2160p WEB-DL H265 DDP2.0-ADWeb [热门] Free 剩余时间:23时20分
官方国语中字动画[国创连载] 灵境行者 第06集 | 类型:动作 动画 奇幻 | 灵境行者之夜游神篇
039分662.53
MB
29016364
匿名
剧集WebDL 2160p
+
A Prophet S01E16 2026 2160p iQIYI WEB-DL H265 HDR DDP5.1-ADWeb [热门] Free 剩余时间:21时58分
官方国语中字HDR10我不是大师 第16集 | 类型:剧情 悬疑 | 主演:李现 李一桐 吴刚 刘冠麟 果靖霖 | 长风起 / 将相 / 江相 / 我是个算命先生
02时
1分
3.33
GB
31813406
匿名
综艺WebDL 1080p
+
Heart Signal S09E34 2026 1080p WEB-DL H265 AAC-ADWeb Free 剩余时间:20时50分
官方国语中字心动的信号 第九季 正片 第10期下:最终抉择,玥儿做出最终决定 | 心动的信号9
03时
9分
532.23
MB
783139
匿名
+
diff --git a/packages/adapters/test/differential/inputs/indexer/tk-audiences-list.html.txt b/packages/adapters/test/differential/inputs/indexer/tk-audiences-list.html.txt index d655a126..5f586f1b 100644 --- a/packages/adapters/test/differential/inputs/indexer/tk-audiences-list.html.txt +++ b/packages/adapters/test/differential/inputs/indexer/tk-audiences-list.html.txt @@ -2,11 +2,15 @@
mockuser 12.5 TB 3.2 TB - 退出
+mockuser +分享率20.48 +信 +

1

@@ -20,7 +24,7 @@ @@ -34,7 +38,7 @@ @@ -62,7 +66,7 @@ diff --git a/packages/adapters/test/differential/inputs/indexer/tk-audiences-login.html.txt b/packages/adapters/test/differential/inputs/indexer/tk-audiences-login.html.txt index 9bf89b86..41bf002e 100644 --- a/packages/adapters/test/differential/inputs/indexer/tk-audiences-login.html.txt +++ b/packages/adapters/test/differential/inputs/indexer/tk-audiences-login.html.txt @@ -1,3 +1,4 @@ 观众 :: 登录

你需要启用cookies才能登录

+ \ No newline at end of file diff --git a/packages/testkit/src/sites/mock-nexusphp.ts b/packages/testkit/src/sites/mock-nexusphp.ts index 544d7bd7..0f6e21e7 100644 --- a/packages/testkit/src/sites/mock-nexusphp.ts +++ b/packages/testkit/src/sites/mock-nexusphp.ts @@ -130,7 +130,10 @@ function row(r: MockNexusRelease): string { ? `${esc(r.truncatedText)}` : `${esc(r.title)}`; const hr = r.hr ? ` H&R` : ""; - const sub = r.subtitle ? `
${esc(r.subtitle)}` : ""; + // 观众真实结构(DET-2 核对):副标题行里先是标签 span,正文在 span.torrent-subtitle-text + const sub = r.subtitle + ? `
${esc(r.subtitle)}` + : ""; return `
类型标题评论存活时间大小种子下载完成发布者
电影 - +
Dune.Part.Two.2024.2160p.UHD.BluRay.REMUX.DV.HDR.HEVC.TrueHD.Atmos.7.1-FraMeSToR Free
沙丘2 / 沙丘:第二部 | 杜比视界 国英双语 中字
Dune.Part.Two.2024.2160p.UHD.BluRay.REMUX.DV.HDR.HEVC.TrueHD.Atmos.7.1-FraMeSToR Free
沙丘2 / 沙丘:第二部 | 杜比视界 国英双语 中字
download
0
综艺 - +
Keep.Running.S12E01.20240426.2160p.WEB-DL.H265.AAC-LelveTV H&R
奔跑吧 第十二季 第1期
Keep.Running.S12E01.20240426.2160p.WEB-DL.H265.AAC-LelveTV H&R
奔跑吧 第十二季 第1期
download
0
剧集 - +
The.Bear.S03.2160p.DSNP.WEB-DL.DDP5.1.Atmos.DV.H.265-FLUX 2X 50%
熊家餐馆 第三季
The.Bear.S03.2160p.DSNP.WEB-DL.DDP5.1.Atmos.DV.H.265-FLUX 2X 50%
熊家餐馆 第三季
download
0
纪录片 - +
Planet.Earth.III.2023.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.5.1-GRP 2X
地球脉动 第三季
Planet.Earth.III.2023.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.5.1-GRP 2X
地球脉动 第三季
download
0
${esc(r.catName)} diff --git a/scripts/mp-sync/gen-differential.py b/scripts/mp-sync/gen-differential.py index 267f0c0f..12b0025a 100644 --- a/scripts/mp-sync/gen-differential.py +++ b/scripts/mp-sync/gen-differential.py @@ -677,7 +677,9 @@ def gen_indexer(out_dir: Optional[str] = None) -> Path: runs.append((sid, d, {"source": "definition", "id": site_id, "file": str(f.relative_to(UMT_ROOT)), "sha256": _sha256(f.read_bytes())}, pg, {}, "x", "torrents")) - for site_id, pg in (("audiences", "tk-audiences-login.html.txt"), ("chdbits", "tk-chdbits-login.html.txt")): + # rl-*:真实站点页面脱敏后的样本(DET-2 观众列表页),只配对应站点的定义 + for site_id, pg in (("audiences", "tk-audiences-login.html.txt"), ("chdbits", "tk-chdbits-login.html.txt"), + ("audiences", "rl-audiences-list.html.txt")): f, d = defs[site_id] runs.append((f"{site_id}@{pg.removesuffix(".html.txt")}", d, {"source": "definition", "id": site_id, "file": str(f.relative_to(UMT_ROOT)), diff --git a/scripts/mp-sync/movieclaw-overrides/audiences.json b/scripts/mp-sync/movieclaw-overrides/audiences.json index e7ac5573..23510f09 100644 --- a/scripts/mp-sync/movieclaw-overrides/audiences.json +++ b/scripts/mp-sync/movieclaw-overrides/audiences.json @@ -1,5 +1,5 @@ { - "$comment": "W1-3b 手写观众定义(按 MP indexer schema;仅对 testkit mock 验证)。深合并到 MovieClaw v0.27.0 转换结果之上,本文件的值优先,MovieClaw 值只补空。 umt.detail.fields=null:保留 W1-3b rowhead 详情模型(已对 mock 验证),不采用 MovieClaw 默认逐字段选择器。", + "$comment": "W1-3b 手写观众定义(按 MP indexer schema;仅对 testkit mock 验证)。深合并到 MovieClaw v0.27.0 转换结果之上,本文件的值优先,MovieClaw 值只补空。 umt.detail.fields=null:保留 W1-3b rowhead 详情模型(已对 mock 验证),不采用 MovieClaw 默认逐字段选择器。 DET-2(2026-09-30 真实账号核对列表页 1 次 + 详情页 2 次):列表副标题取 span.torrent-subtitle-text(span.torrent-subtitle-line 里先是标签);详情 h1 促销是 font.free / font.halfdown 等 + 「剩余时间」span[title](umt.detail.promo);做种 / 下载 / 完成数在基本信息行右侧 #seeders / #leechers / a[title=完成](没有「同伴」行);种子 Hash 在 #copyTorrentHashLink[data-hash];上传者在 span.torrent-uploader-wrap(匿名为「匿名」);简介开头的站点声明 #ad_torrentdetail 去掉;文件清单不在页面上(点击「N个文件」后由 common.js 的 toggleFileList AJAX 加载,端点未核对),暂不另发请求。", "id": "audiences", "name": "观众", "domain": "https://audiences.me/", @@ -141,7 +141,7 @@ ] }, "description": { - "selector": "span.torrent-subtitle-line" + "selector": "span.torrent-subtitle-text" }, "labels": { "selector": "span.tags" @@ -159,7 +159,7 @@ } }, "umt": { - "version": "audiences@0.2.1-unverified", + "version": "audiences@0.3.1", "kind": "nexusphp", "displayName": "观众", "timezone": "+08:00", @@ -198,7 +198,54 @@ "description": "#kdescr", "headerScope": "h1#top", "notFoundMarkers": ["没有该ID的种子", "No torrent with ID"], - "fields": null + "fields": { + "seeders": "#seeders", + "leechers": "#leechers", + "snatched": "a[title='完成'][href*='viewsnatches.php']", + "infoHash": "#copyTorrentHashLink::attr(data-hash)" + }, + "promo": { + "downloadvolumefactor": { + "case": { + "font.free": 0, + "font.twoupfree": 0, + "font.halfdown": 0.5, + "font.twouphalfdown": 0.5, + "font.thirtypercent": 0.3, + "img.pro_free": 0, + "img.pro_free2up": 0, + "img.pro_50pctdown": 0.5, + "img.pro_50pctdown2up": 0.5, + "img.pro_30pctdown": 0.3, + "*": 1 + } + }, + "uploadvolumefactor": { + "case": { + "font.twoup": 2, + "font.twoupfree": 2, + "font.twouphalfdown": 2, + "img.pro_50pctdown2up": 2, + "img.pro_free2up": 2, + "img.pro_2up": 2, + "*": 1 + } + }, + "freedate": { + "selector": "img[class^=\"pro_\"], span[title]", + "attribute": "title", + "filters": [ + { + "name": "re_search", + "args": ["\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", 0] + } + ] + } + }, + "page": { + "uploader": "span.torrent-uploader-wrap", + "descriptionStrip": "#ad_torrentdetail" + } } } }