feat: 角色下载脚本适配原神和星穹铁道

This commit is contained in:
2026-08-05 21:57:29 +08:00
parent e1c9bda4e1
commit 09a652fcd6
2 changed files with 51 additions and 5 deletions
+49 -4
View File
@@ -21,7 +21,9 @@ const {
* @property {string} [url] 完整 parse API 地址(与 baseUrl + wikiTitle 二选一) * @property {string} [url] 完整 parse API 地址(与 baseUrl + wikiTitle 二选一)
* @property {string} [wikiTitle] Wiki 页面标题 * @property {string} [wikiTitle] Wiki 页面标题
* @property {string} savePath 图片保存目录 * @property {string} savePath 图片保存目录
* @property {string} imageSelector 图片 CSS 选择器 * @property {string} [scopeSelector] 限定搜索范围的容器选择器,如 table.fandom-table
* @property {number} [scopeIndex=0] 当存在多个 scope 时,取第几个(从 0 开始)
* @property {string} imageSelector 图片 CSS 选择器(相对于 scope 或整页)
* @property {string} [imageUrlAttr='src'] 图片 URL 所在属性,如 src、data-src * @property {string} [imageUrlAttr='src'] 图片 URL 所在属性,如 src、data-src
* @property {(name: string) => string} [nameTransform] 文件名二次处理 * @property {(name: string) => string} [nameTransform] 文件名二次处理
* @property {number} [downloadDelayMs] 下载间隔,默认 500ms * @property {number} [downloadDelayMs] 下载间隔,默认 500ms
@@ -30,6 +32,30 @@ const {
/** @type {WikiConfig[]} */ /** @type {WikiConfig[]} */
const wikiConfigs = [ const wikiConfigs = [
{
name: 'genshin',
baseUrl: 'https://genshin-impact.fandom.com',
wikiTitle: 'Character/List',
savePath: path.join(__dirname, 'output', 'genshin'),
scopeSelector: 'table.fandom-table',
scopeIndex: 0,
imageSelector: 'td:first-child img[data-relevant="1"]',
imageUrlAttr: 'data-src',
nameTransform: (name) => name.replace(/-icon$/, ''),
verifyApiUrl: 'https://paul.ren/api/page/get?slug=photo-collection-genshin',
},
{
name: 'sr',
baseUrl: 'https://honkai-star-rail.fandom.com',
wikiTitle: 'Character/List',
savePath: path.join(__dirname, 'output', 'sr'),
scopeSelector: 'table.article-table',
scopeIndex: 0,
imageSelector: 'td:first-child img[data-relevant="1"]',
imageUrlAttr: 'data-src',
nameTransform: (name) => name.replace(/character-/, '').replace(/-icon$/, ''),
verifyApiUrl: 'https://paul.ren/api/page/get?slug=photo-collection-sr',
},
{ {
name: 'nte', name: 'nte',
baseUrl: 'https://neverness-to-everness.fandom.com/wiki/Character/List', baseUrl: 'https://neverness-to-everness.fandom.com/wiki/Character/List',
@@ -95,12 +121,29 @@ async function fetchWikiHtml(config) {
return html; return html;
} }
function extractImages(html, imageSelector, imageUrlAttr = 'src') { function extractImages(html, config) {
const {
imageSelector,
imageUrlAttr = 'src',
scopeSelector,
scopeIndex = 0,
} = config;
const $ = cheerio.load(html); const $ = cheerio.load(html);
const $container = scopeSelector
? $(scopeSelector).eq(scopeIndex)
: null;
if (scopeSelector && $container.length === 0) {
return [];
}
const $images = $container ? $container.find(imageSelector) : $(imageSelector);
const results = []; const results = [];
const seenNames = new Set(); const seenNames = new Set();
$(imageSelector).each((_, element) => { console.log('表格搜索数量:', $images.length);
$images.each((_, element) => {
const $img = $(element); const $img = $(element);
const rawUrl = resolveImageUrl($img, imageUrlAttr); const rawUrl = resolveImageUrl($img, imageUrlAttr);
@@ -119,6 +162,8 @@ function extractImages(html, imageSelector, imageUrlAttr = 'src') {
results.push({ url: cleanedUrl, rawName }); results.push({ url: cleanedUrl, rawName });
}); });
console.log('已去重结果数量:', results.length);
return results; return results;
} }
@@ -148,7 +193,7 @@ async function downloadWiki(config) {
fs.mkdirSync(config.savePath, { recursive: true }); fs.mkdirSync(config.savePath, { recursive: true });
const html = await fetchWikiHtml(config); const html = await fetchWikiHtml(config);
const images = extractImages(html, config.imageSelector, config.imageUrlAttr ?? 'src'); const images = extractImages(html, config);
console.log(`共找到 ${images.length} 张角色图`); console.log(`共找到 ${images.length} 张角色图`);
+2 -1
View File
@@ -10,7 +10,8 @@ function cleanImageUrl(url) {
function generateImageName(url) { function generateImageName(url) {
const fileNameMatch = url.match(/\/([^/]+)\.png/i); const fileNameMatch = url.match(/\/([^/]+)\.png/i);
if (fileNameMatch && fileNameMatch[1]) { if (fileNameMatch && fileNameMatch[1]) {
return fileNameMatch[1].toLowerCase().replace(/_/g, '-'); // 去除 .、&、(、) 等特殊字符
return fileNameMatch[1].toLowerCase().replace(/_/g, '-').replaceAll(/\.|%26|%28|%29|%e2%80%a2/g, "").replace(/-{2,}/g, '-');
} }
return null; return null;
} }