UNPKG

comic-book-dl

Version:
238 lines (237 loc) 8.36 kB
import got from '../../../../node_modules/got/dist/source/index.js'; import { load } from 'cheerio'; import { UA, fixPathName } from '../../../utils/index.js'; import { Base } from '../../../lib/parse/base/index.js'; import { ApiV4ChapterImageParse, ApiV4ChapterListParse, ApiV4Decrypt } from './crypto.js'; const api = { v4Chapter: 'https://nnv4api.dmzj.com/comic/chapter/', v3Chapter: 'https://m.idmzj.com/chapinfo/', v3Api: 'https://api.dmzj.com', v4Api: 'https://nnv4api.dmzj.com' }; export class Dmzj extends Base { constructor() { super(...arguments); this.type = 'Dmzj'; } async parseBookInfo() { const url = this.bookUrl; const rawUrl = url; let response; try { response = await got.get(url, this.genReqOptions()); } catch (e) { return false; } if (!response || response.statusCode !== 200) { return false; } const isMobile = /m\.idmzj/.test(url); let parseResult; if (isMobile) { parseResult = this.mSite(url, response.body); } else { parseResult = await this.pcSite(url, response.body); } if (!parseResult) return false; const name = parseResult?.name; const author = parseResult?.author; const desc = parseResult?.desc; const coverUrl = parseResult?.coverUrl; let chapters = parseResult?.chapters || []; if (!name || chapters.length === 0) { return false; } chapters = chapters.reverse(); chapters = chapters.map((item, index) => { const newItem = { ...item }; if (index !== 0) { newItem.preChapter = { name: chapters[index - 1].name, rawName: chapters[index - 1].rawName, href: chapters[index - 1].href, index: chapters[index - 1].index }; } if (index !== chapters.length - 1) { newItem.nextChapter = { name: chapters[index + 1].name, rawName: chapters[index + 1].rawName, href: chapters[index + 1].href, index: chapters[index + 1].index }; } return newItem; }); return { name, pathName: fixPathName(name), author, desc, coverUrl, coverPath: '', chapters, url, language: '简体', rawUrl }; } async getImgList(url) { const urlPath = /.*view\/(.*).html/g.exec(url)?.[1]; if (!urlPath) return []; const response = await got(`${api.v4Chapter}${urlPath}`, this.genReqOptions()); let imgList = []; try { const data = ApiV4ChapterImageParse(ApiV4Decrypt(response.body)); imgList = data?.Images ?? []; imgList = imgList.map(img => decodeURIComponent(img)); } catch (e) { const response = await got(`${api.v3Chapter}${urlPath}.html`, this.genReqOptions()); let data = {}; try { data = JSON.parse(response.body); } catch (e) { console.log(e); } imgList = data['page_url']; } return imgList; } mSite(url, body) { const $ = load(body); const name = $('#comicName').text().trim(); const desc = $('.txtDesc.autoHeight').text().trim(); const author = $('.introName').toArray().map(el => $(el).text()).join('/').trim(); const coverUrl = $('#Cover img').attr('src')?.trim() ?? ''; const chaptersReg = /initIntroData\((.*?)\)/gm; const chaptersJSONstr = chaptersReg.exec(body)?.[1] ?? ''; let tempChapters = []; try { tempChapters = JSON.parse(chaptersJSONstr); } catch (e) { return null; } if (!Array.isArray(tempChapters)) tempChapters = []; tempChapters = tempChapters.map((item) => item?.data ?? null); tempChapters = tempChapters.flat(); const chapters = []; const { origin } = new URL(url); tempChapters.forEach((item, index) => { const chapterIndex = item['chapter_order'] ?? index; chapters.push({ name: `${chapterIndex}_${fixPathName(item['chapter_name'])}`, rawName: item['chapter_name'], href: `${origin}/view/${item['comic_id']}/${item.id}.html`, imageList: [], imageListPath: [], index: chapterIndex, other: item }); }); return { name, author, desc, coverUrl, chapters, }; } async pcSite(url, body) { const reg = /.*\/(.*?)$/; const params = {}; let comicName = url.match(reg)?.[1] ?? ''; comicName = comicName.replace(/\.html/, ''); params['comic_py'] = comicName; const api = 'https://www.idmzj.com/api/v1/comic1/comic/detail'; const nuxtDataStr = body.match(/window\.__NUXT__=\((.*)\)/gm)?.[0] ?? ''; const fieldGroup = ['channel', 'app_name', 'version', 'timestamp']; fieldGroup.forEach((field, i) => { const fieldReg = new RegExp(`${field}:(.*?),`); const key = fieldGroup[i]; params[key] = nuxtDataStr.match(fieldReg)?.[1] ?? ''; }); const queryStr = new URLSearchParams(params).toString(); const response = await got.get(`${api}?${queryStr}`, this.genReqOptions()); let resJSON = null; try { resJSON = JSON.parse(response.body); resJSON = resJSON?.data?.comicInfo || {}; } catch (e) { console.log(e); return null; } const author = resJSON?.authorInfo?.authorName || ''; const name = resJSON?.title || ''; const desc = resJSON?.description || ''; const coverUrl = resJSON?.cover || ''; const chapters = []; let tempChapters = resJSON?.chapterList || []; if (tempChapters.length <= 0) { const comicId = resJSON?.id; tempChapters = await this.commonFetchChaptersList(comicId); } else { tempChapters = tempChapters.map((item) => item?.data ?? null); tempChapters = tempChapters.flat(); } tempChapters.forEach((item, index) => { const chapterIndex = item['chapter_order'] ?? index; chapters.push({ name: `${chapterIndex}_${fixPathName(item['chapter_title'])}`, rawName: item['chapter_title'], href: `https://m.idmzj.com/view/${resJSON?.id}/${item['chapter_id']}.html`, imageList: [], imageListPath: [], index: chapterIndex, other: item }); }); return { name, author, desc, coverUrl, chapters, }; } async commonFetchChaptersList(id) { if (!id) return []; const url = `${api.v4Api}/comic/detail/${id}?uid=2665531`; const response = await got.get(url, this.genReqOptions()); let chapterList = []; try { const data = ApiV4ChapterListParse(ApiV4Decrypt(response.body)); const tempChapterList = data?.Chapters ?? []; const dataFieldList = tempChapterList.map(item => item.Data); chapterList = dataFieldList.flat().map(item => { return { ['chapter_order']: item.ChapterOrder, ['chapter_title']: item.ChapterTitle, ['chapter_id']: item.ChapterId }; }); } catch (e) { return []; } return chapterList.reverse(); } genReqOptions() { return { headers: { 'user-agent': UA }, http2: true }; } }