Featured: Added a fourth data source, NJAV, improving JAVCode coverage.
- Added the `searchNjav` function, supporting direct URL queries using code names. - High stability based on JSON-LD structured data parsing. - No cookies required; works on both Windows and Linux. - Adjusted data source priority: JAVBUS → NJAV → JavLibrary → JAVDB - Version upgraded to v1.2.0
This commit is contained in:
1 parent
e65e6a4602
commit
8a2a09ebed
2 files changed
+82
-1
No files matched your search
@@ -188,6 +188,80 @@ async function searchJavdb(id) {
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 数据源四:NJAV(无需Cookie,覆盖率高)────────────
|
||||
function searchNjav(id) {
|
||||
try {
|
||||
const url = `https://www.njav.com/zh/xvideos/${id.toLowerCase()}`;
|
||||
const html = fetchHtml(url);
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// 确认页面包含正确番号
|
||||
const pageTitle = $('title').text();
|
||||
if (!pageTitle.includes(id.toUpperCase())) return null;
|
||||
|
||||
const result = {
|
||||
id,
|
||||
source: 'NJAV',
|
||||
title: '',
|
||||
actresses: [],
|
||||
actors: [],
|
||||
releaseDate: '',
|
||||
duration: '',
|
||||
studio: '',
|
||||
label: '',
|
||||
director: '',
|
||||
series: '',
|
||||
tags: [],
|
||||
coverUrl: `https://static.javcdn.vip/images/${id.toLowerCase()}/thumb_h.webp`,
|
||||
score: '',
|
||||
};
|
||||
|
||||
// 优先用 JSON-LD 解析,最稳定
|
||||
const jsonLd = $('script[type="application/ld+json"]').text();
|
||||
if (jsonLd) {
|
||||
try {
|
||||
const data = JSON.parse(jsonLd);
|
||||
result.title = data.name || '';
|
||||
result.releaseDate = data.uploadDate?.substring(0, 10) || '';
|
||||
// 解析时长 PT3H22M51S → 3:22:51
|
||||
if (data.duration) {
|
||||
const m = data.duration.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/);
|
||||
if (m) {
|
||||
const h = m[1] || '0';
|
||||
const min = m[2] ? m[2].padStart(2, '0') : '00';
|
||||
const sec = m[3] ? m[3].padStart(2, '0') : '00';
|
||||
result.duration = `${h}:${min}:${sec}`;
|
||||
}
|
||||
}
|
||||
if (Array.isArray(data.actor)) {
|
||||
result.actresses = data.actor.map(a => a.name).filter(Boolean);
|
||||
}
|
||||
if (Array.isArray(data.genre)) {
|
||||
result.tags = data.genre;
|
||||
}
|
||||
if (data.partOfSeries?.name) {
|
||||
result.series = data.partOfSeries.name;
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// 补充 HTML 里的字段(JSON-LD 没有的)
|
||||
$('.detail-item div').each((_, el) => {
|
||||
const label = $(el).find('span').first().text().trim();
|
||||
const value = $(el).find('span').last().text().trim();
|
||||
if (/片商|制作|製作|Studio|Maker/i.test(label)) {
|
||||
result.studio = value;
|
||||
} else if (/導演|Director/i.test(label)) {
|
||||
result.director = value;
|
||||
}
|
||||
});
|
||||
|
||||
return result.title ? result : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function parseJavdb(html, queryId) {
|
||||
const $ = cheerio.load(html);
|
||||
const result = {
|
||||
@@ -263,12 +337,19 @@ export async function search(id) {
|
||||
for (let attempt = 1; attempt <= MAX_RETRY; attempt++) {
|
||||
let result = null;
|
||||
|
||||
// 第一优先:JAVBUS(最快,直接番号拼URL)
|
||||
result = searchJavbus(searchId);
|
||||
if (result) { setCache(id, result); return result; }
|
||||
|
||||
// 第二优先:NJAV(无需Cookie,覆盖率高,能查到JUR等小众番号)
|
||||
result = searchNjav(searchId);
|
||||
if (result) { setCache(id, result); return result; }
|
||||
|
||||
// 第三优先:JavLibrary(补充数据)
|
||||
result = searchJavlibrary(searchId);
|
||||
if (result) { setCache(id, result); return result; }
|
||||
|
||||
// 第四优先:JAVDB(需要Cookie,仅Linux)
|
||||
result = await searchJavdb(searchId);
|
||||
if (result) { setCache(id, result); return result; }
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javinfo",
|
||||
"version": "1.1.12",
|
||||
"version": "1.2.0",
|
||||
"description": "AV番号命令行查询工具",
|
||||
"main": "./index.js",
|
||||
"type": "module",
|
||||
|
||||
Reference in new issue
Block a user