UNPKG

rsshub

Version:
180 lines (170 loc) 6.53 kB
import { Route, ViewType } from '@/types'; import cache from '@/utils/cache'; import got from '@/utils/got'; import { load } from 'cheerio'; import { parseDate } from '@/utils/parse-date'; import timezone from '@/utils/timezone'; import pMap from 'p-map'; export const route: Route = { path: '/gnn/:category?', categories: ['anime'], view: ViewType.Articles, example: '/gamer/gnn/1', parameters: { category: { description: '版塊', options: [ { value: '1', label: 'PC' }, { value: '3', label: 'TV 掌機' }, { value: '4', label: '手機遊戲' }, { value: '5', label: '動漫畫' }, { value: '9', label: '主題報導' }, { value: '11', label: '活動展覽' }, { value: '13', label: '電競' }, { value: 'ns', label: 'Switch' }, { value: 'ps5', label: 'PS5' }, { value: 'ps4', label: 'PS4' }, { value: 'xbone', label: 'XboxOne' }, { value: 'xbsx', label: 'XboxSX' }, { value: 'pc', label: 'PC 單機' }, { value: 'olg', label: 'PC 線上' }, { value: 'ios', label: 'iOS' }, { value: 'android', label: 'Android' }, { value: 'web', label: 'Web' }, { value: 'comic', label: '漫畫' }, { value: 'anime', label: '動畫' }, ], }, }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: true, supportBT: false, supportPodcast: false, supportScihub: false, }, name: 'GNN 新聞', maintainers: ['Arracc', 'ladeng07', 'pseudoyu'], handler, description: '缺省為首頁', }; async function handler(ctx) { const category = ctx.req.param('category'); let url = ''; let categoryName = ''; const categoryTable = { 1: 'PC', 3: 'TV 掌機', 4: '手機遊戲', 5: '動漫畫', 9: '主題報導', 11: '活動展覽', 13: '電競', ns: 'Switch', ps5: 'PS5', ps4: 'PS4', xbone: 'XboxOne', xbsx: 'XboxSX', pc: 'PC 單機', olg: 'PC 線上', ios: 'iOS', android: 'Android', web: 'Web', comic: '漫畫', anime: '動畫', }; const mainCategory = ['1', '3', '4', '5', '9', '11', '13']; if (!category || !Object.keys(categoryTable).includes(category)) { url = 'https://gnn.gamer.com.tw/'; } else { categoryName = '-' + categoryTable[category]; url = mainCategory.includes(category) ? `https://gnn.gamer.com.tw/index.php?k=${category}` : `https://acg.gamer.com.tw/news.php?p=${category}`; } const response = await got({ method: 'get', url, }); const data = response.data; const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 50; const $ = load(data); const list = $('div.BH-lbox.GN-lbox2') .children() .not('p,a,img,span') // <div data-news-id="291265" id="291265"></div> .not('[data-news-id]') .slice(0, limit) .toArray() .map((item) => { item = $(item); let aLabelNode; let tag; // a label with div if (item.find('h1').length === 0) { // a label without div aLabelNode = item.find('a'); tag = item.find('div.platform-tag_list').text(); } else { aLabelNode = item.find('h1').find('a'); tag = item.find('div.platform-tag_list').text(); } return { title: '[' + tag + ']' + aLabelNode.text(), link: aLabelNode.attr('href').replace('//', 'https://'), }; }); const items = await pMap( list, async (item) => { item.description = await cache.tryGet(item.link, async () => { const response = await got.get(item.link); let component = ''; const urlReg = /window\.lazySizesConfig/g; let pubInfo; let dateStr; if (response.body.search(urlReg) >= 0) { const $ = load(response.data); if ($('span.GN-lbox3C').length > 0) { // official publish 1 pubInfo = $('span.GN-lbox3C').text().split(')'); item.author = pubInfo[0].replace('(', '').replace(' 報導', ''); dateStr = pubInfo[1].trim(); } else { // official publish 2 pubInfo = $('span.GN-lbox3CA').text().split(')'); item.author = pubInfo[0].replace('(', '').replace(' 報導', ''); dateStr = pubInfo[1].replace('原文出處', '').trim(); } component = $('div.GN-lbox3B').html(); } else { // url redirect const _response = await got.get(item.link); const _$ = load(_response.data); if (_$('div.MSG-list8C').length > 0) { // personal publish 1 pubInfo = _$('span.ST1').text().split('│'); item.author = pubInfo[0].replace('作者:', ''); dateStr = pubInfo[_$('span.ST1').find('a').length > 0 ? 2 : 1]; component = _$('div.MSG-list8C').html(); } else { // personal publish 2 pubInfo = _$('div.article-intro').text().replaceAll('\n', '').split('|'); item.author = pubInfo[0]; dateStr = pubInfo[1]; component = _$('div.text-paragraph').html(); } } item.pubDate = timezone(parseDate(dateStr, 'YYYY-MM-DD HH:mm:ss'), +8); component = component.replaceAll(/\b(data-src)\b/g, 'src'); return component; }); return item; }, { concurrency: 5 } ); return { title: '巴哈姆特-GNN新聞' + categoryName, link: url, item: items, }; }