Optimize code
This commit is contained in:
1 parent
9e9bd2ec83
commit
e65e6a4602
2 files changed
+32
-85
No files matched your search
+31
-84
@@ -3,11 +3,9 @@ import * as cheerio from 'cheerio';
|
|||||||
import { getCache, setCache, getConfig } from './cache.js';
|
import { getCache, setCache, getConfig } from './cache.js';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
|
||||||
// ─── 通用请求函数 ────────────────────────────────────────
|
// ─── 通用请求函数(JAVBUS / JavLibrary 使用)────────────
|
||||||
function fetchHtml(url, cookie = '') {
|
function fetchHtml(url, cookie = '') {
|
||||||
const cookieHeader = cookie
|
const cookieHeader = cookie ? `-H "Cookie: ${cookie}"` : '';
|
||||||
? `-H "Cookie: ${cookie}"`
|
|
||||||
: '';
|
|
||||||
const result = execSync(
|
const result = execSync(
|
||||||
`curl -sL "${url}" \
|
`curl -sL "${url}" \
|
||||||
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" \
|
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" \
|
||||||
@@ -26,7 +24,6 @@ function searchJavbus(id) {
|
|||||||
const html = fetchHtml(url);
|
const html = fetchHtml(url);
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
// 判断是否找到(404页面包含特定文字)
|
|
||||||
if ($('title').text().includes('404') || !$('.container .row').length) {
|
if ($('title').text().includes('404') || !$('.container .row').length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -48,12 +45,9 @@ function searchJavbus(id) {
|
|||||||
score: '',
|
score: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 遍历详情字段
|
|
||||||
$('.info p').each((_, el) => {
|
$('.info p').each((_, el) => {
|
||||||
const text = $(el).text().trim();
|
const text = $(el).text().trim();
|
||||||
const labelEl = $(el).find('span.header');
|
const label = $(el).find('span.header').text().trim();
|
||||||
const label = labelEl.text().trim();
|
|
||||||
|
|
||||||
if (/發行日期|发行日期/.test(label)) {
|
if (/發行日期|发行日期/.test(label)) {
|
||||||
result.releaseDate = text.replace(label, '').trim();
|
result.releaseDate = text.replace(label, '').trim();
|
||||||
} else if (/長度|长度/.test(label)) {
|
} else if (/長度|长度/.test(label)) {
|
||||||
@@ -69,13 +63,11 @@ function searchJavbus(id) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 类别
|
|
||||||
$('span.genre a').each((_, el) => {
|
$('span.genre a').each((_, el) => {
|
||||||
const tag = $(el).text().trim();
|
const tag = $(el).text().trim();
|
||||||
if (tag) result.tags.push(tag);
|
if (tag) result.tags.push(tag);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 女优
|
|
||||||
$('.star-name a').each((_, el) => {
|
$('.star-name a').each((_, el) => {
|
||||||
const name = $(el).text().trim();
|
const name = $(el).text().trim();
|
||||||
if (name) result.actresses.push(name);
|
if (name) result.actresses.push(name);
|
||||||
@@ -90,15 +82,11 @@ function searchJavbus(id) {
|
|||||||
// ─── 数据源二:JavLibrary ────────────────────────────────
|
// ─── 数据源二:JavLibrary ────────────────────────────────
|
||||||
function searchJavlibrary(id) {
|
function searchJavlibrary(id) {
|
||||||
try {
|
try {
|
||||||
// 中文版搜索页
|
|
||||||
const searchUrl = `https://www.javlibrary.com/cn/vl_searchbyid.php?keyword=${encodeURIComponent(id)}`;
|
const searchUrl = `https://www.javlibrary.com/cn/vl_searchbyid.php?keyword=${encodeURIComponent(id)}`;
|
||||||
const searchHtml = fetchHtml(searchUrl);
|
const searchHtml = fetchHtml(searchUrl);
|
||||||
const $ = cheerio.load(searchHtml);
|
const $ = cheerio.load(searchHtml);
|
||||||
|
|
||||||
// 如果直接跳转到详情页(只有一个结果)
|
|
||||||
let detailHtml = searchHtml;
|
let detailHtml = searchHtml;
|
||||||
|
|
||||||
// 如果是搜索结果列表,找第一个匹配的
|
|
||||||
const firstResult = $('.videos .video a').first();
|
const firstResult = $('.videos .video a').first();
|
||||||
if (firstResult.length) {
|
if (firstResult.length) {
|
||||||
const detailPath = firstResult.attr('href');
|
const detailPath = firstResult.attr('href');
|
||||||
@@ -106,8 +94,6 @@ function searchJavlibrary(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const $d = cheerio.load(detailHtml);
|
const $d = cheerio.load(detailHtml);
|
||||||
|
|
||||||
// 确认找到了正确页面
|
|
||||||
if (!$d('#video_id .text').length) return null;
|
if (!$d('#video_id .text').length) return null;
|
||||||
|
|
||||||
const foundId = $d('#video_id .text').text().trim().toUpperCase();
|
const foundId = $d('#video_id .text').text().trim().toUpperCase();
|
||||||
@@ -130,13 +116,11 @@ function searchJavlibrary(id) {
|
|||||||
score: $d('#video_review .score').text().trim(),
|
score: $d('#video_review .score').text().trim(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// 类别
|
|
||||||
$d('#video_genres .genre a').each((_, el) => {
|
$d('#video_genres .genre a').each((_, el) => {
|
||||||
const tag = $d(el).text().trim();
|
const tag = $d(el).text().trim();
|
||||||
if (tag) result.tags.push(tag);
|
if (tag) result.tags.push(tag);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 演员
|
|
||||||
$d('#video_cast .cast .star a').each((_, el) => {
|
$d('#video_cast .cast .star a').each((_, el) => {
|
||||||
const name = $d(el).text().trim();
|
const name = $d(el).text().trim();
|
||||||
if (name) result.actresses.push(name);
|
if (name) result.actresses.push(name);
|
||||||
@@ -148,59 +132,31 @@ function searchJavlibrary(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── 数据源三:JAVDB(需要Cookie) ──────────────────────
|
// ─── 数据源三:JAVDB(需要Cookie,仅Linux/Mac)──────────
|
||||||
async function searchJavdb(id) {
|
async function searchJavdb(id) {
|
||||||
try {
|
try {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
if (!config.session) return null;
|
if (!config.session) return null;
|
||||||
|
|
||||||
|
// Windows上Cloudflare封锁了非OpenSSL的TLS请求,跳过
|
||||||
|
if (process.platform === 'win32') return null;
|
||||||
|
|
||||||
const session = decodeURIComponent(config.session);
|
const session = decodeURIComponent(config.session);
|
||||||
const cookie = `locale=zh; over18=1; _jdb_session=${session}`;
|
const cookie = `locale=zh; over18=1; _jdb_session=${session}`;
|
||||||
const isWindows = process.platform === 'win32';
|
|
||||||
|
|
||||||
// Linux 用 curl(OpenSSL TLS,Cloudflare 接受)
|
function fetchJavdbHtml(url) {
|
||||||
// Windows 用 Node.js https(绕过 Schannel 问题)
|
return execSync(
|
||||||
async function fetchJavdbHtml(url) {
|
`curl -sL "${url}" \
|
||||||
if (!isWindows) {
|
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" \
|
||||||
// Linux/Mac:用 curl
|
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
|
||||||
return execSync(
|
-H "Accept-Language: zh-CN,zh;q=0.9" \
|
||||||
`curl -sL "${url}" \
|
-H "Cookie: ${cookie}"`,
|
||||||
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" \
|
{ timeout: 15000, maxBuffer: 1024 * 1024 * 10 }
|
||||||
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
|
).toString();
|
||||||
-H "Accept-Language: zh-CN,zh;q=0.9" \
|
|
||||||
-H "Cookie: ${cookie}"`,
|
|
||||||
{ timeout: 15000, maxBuffer: 1024 * 1024 * 10 }
|
|
||||||
).toString();
|
|
||||||
} else {
|
|
||||||
// Windows:用 Node.js https
|
|
||||||
const { default: https } = await import('https');
|
|
||||||
const { default: http } = await import('http');
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const client = url.startsWith('https') ? https : http;
|
|
||||||
const req = client.get(url, {
|
|
||||||
headers: {
|
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
|
||||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
||||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
|
||||||
'Cookie': cookie,
|
|
||||||
},
|
|
||||||
}, (res) => {
|
|
||||||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
||||||
resolve(fetchJavdbHtml(res.headers.location));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const chunks = [];
|
|
||||||
res.on('data', chunk => chunks.push(chunk));
|
|
||||||
res.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
req.setTimeout(15000, () => { req.destroy(); reject(new Error('timeout')); });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchUrl = `https://javdb.com/search?q=${encodeURIComponent(id)}&f=all`;
|
const searchUrl = `https://javdb.com/search?q=${encodeURIComponent(id)}&f=all`;
|
||||||
const searchHtml = await fetchJavdbHtml(searchUrl);
|
const searchHtml = fetchJavdbHtml(searchUrl);
|
||||||
|
|
||||||
const $ = cheerio.load(searchHtml);
|
const $ = cheerio.load(searchHtml);
|
||||||
let detailPath = null;
|
let detailPath = null;
|
||||||
@@ -221,13 +177,13 @@ async function searchJavdb(id) {
|
|||||||
let detailHtml = '';
|
let detailHtml = '';
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
detailHtml = await fetchJavdbHtml(`https://javdb.com${detailPath}`);
|
detailHtml = fetchJavdbHtml(`https://javdb.com${detailPath}`);
|
||||||
if (detailHtml.length > 1000) break;
|
if (detailHtml.length > 1000) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (detailHtml.length < 1000) return null;
|
if (detailHtml.length < 1000) return null;
|
||||||
return parseJavdb(detailHtml, id);
|
return parseJavdb(detailHtml, id);
|
||||||
} catch (e) {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,48 +248,39 @@ function parseJavdb(html, queryId) {
|
|||||||
|
|
||||||
// ─── 主入口:依次尝试三个数据源 ─────────────────────────
|
// ─── 主入口:依次尝试三个数据源 ─────────────────────────
|
||||||
export async function search(id) {
|
export async function search(id) {
|
||||||
// 用户输入连字符 031926-100,搜索时转成下划线 031926_100
|
// FC2 格式识别:031926-100 → 031926_100(JAVDB 存储格式)
|
||||||
let searchId = id;
|
let searchId = id;
|
||||||
if (/^\d{5,6}-\d+$/.test(id)) {
|
if (/^\d{5,6}-\d+$/.test(id)) {
|
||||||
searchId = id.replace('-', '_');
|
searchId = id.replace(/-/g, '_'); // 全局替换,更安全
|
||||||
console.log(chalk.gray(` 识别为FC2番号: ${id}`));
|
console.log(chalk.gray(` 识别为FC2格式的车牌号: ${id}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
const cached = getCache(id);
|
const cached = getCache(id);
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
// 最多自动重试 3 次,每次间隔 1 秒
|
|
||||||
const MAX_RETRY = 3;
|
const MAX_RETRY = 3;
|
||||||
|
|
||||||
for (let attempt = 1; attempt <= MAX_RETRY; attempt++) {
|
for (let attempt = 1; attempt <= MAX_RETRY; attempt++) {
|
||||||
let result = null;
|
let result = null;
|
||||||
|
|
||||||
// 第一优先:JAVBUS
|
|
||||||
result = searchJavbus(searchId);
|
result = searchJavbus(searchId);
|
||||||
if (result) {
|
if (result) { setCache(id, result); return result; }
|
||||||
setCache(id, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 第二优先:JavLibrary
|
|
||||||
result = searchJavlibrary(searchId);
|
result = searchJavlibrary(searchId);
|
||||||
if (result) {
|
if (result) { setCache(id, result); return result; }
|
||||||
setCache(id, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 第三优先:JAVDB
|
|
||||||
result = await searchJavdb(searchId);
|
result = await searchJavdb(searchId);
|
||||||
if (result) {
|
if (result) { setCache(id, result); return result; }
|
||||||
setCache(id, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 本次没找到,如果还有重试机会就等待
|
|
||||||
if (attempt < MAX_RETRY) {
|
if (attempt < MAX_RETRY) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000)); // 改成 2 秒
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Windows 用户提示
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
process.stderr.write(chalk.gray(' 温馨提示: 此车牌号需要JAVDB数据源,Windows暂不支持~\n'));
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "javinfo",
|
"name": "javinfo",
|
||||||
"version": "1.1.11",
|
"version": "1.1.12",
|
||||||
"description": "AV番号命令行查询工具",
|
"description": "AV番号命令行查询工具",
|
||||||
"main": "./index.js",
|
"main": "./index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
Reference in new issue
Block a user