UNPKG

rsshub

Version:
333 lines (302 loc) 14.5 kB
import { type Data, type DataItem, type Route, ViewType } from '@/types'; import { art } from '@/utils/render'; import cache from '@/utils/cache'; import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; import { type CheerioAPI, type Cheerio, load } from 'cheerio'; import type { Element } from 'domhandler'; import { type Context } from 'hono'; import path from 'node:path'; export const handler = async (ctx: Context): Promise<Data> => { const { category = 'newly' } = ctx.req.param(); const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10); const baseUrl: string = 'https://www.199it.com'; const targetUrl: string = new URL(category, baseUrl).href; const response = await ofetch(targetUrl); const $: CheerioAPI = load(response); const language = $('html').attr('lang') ?? 'zh-CN'; let items: DataItem[] = []; items = $('article.newsplus') .slice(0, limit) .toArray() .map((el): Element => { const $el: Cheerio<Element> = $(el); const title: string = $el.find('h2.entry-title').text(); const pubDateStr: string | undefined = $el.find('time.entry-date').attr('datetime'); const linkUrl: string | undefined = $el.find('h2.entry-title a').attr('href'); const categoryEls: Element[] = $el.find('ul.post-categories li:not(submenu-parent)').toArray(); const categories: string[] = [...new Set(categoryEls.map((el) => $(el).text()).filter(Boolean))]; const image: string | undefined = $el.find('img.attachment-post-thumbnail').attr('src'); const upDatedStr: string | undefined = pubDateStr; const processedItem: DataItem = { title, pubDate: pubDateStr ? parseDate(pubDateStr) : undefined, link: linkUrl ? new URL(linkUrl, baseUrl).href : undefined, category: categories, image, banner: image, updated: upDatedStr ? parseDate(upDatedStr) : undefined, language, }; return processedItem; }); items = ( await Promise.all( items.map((item) => { if (!item.link) { return item; } return cache.tryGet(item.link, async (): Promise<DataItem> => { const detailResponse = await ofetch(item.link); const $$: CheerioAPI = load(detailResponse); $$('div.entry-content img.alignnone').each((_, el) => { const $el: Cheerio<Element> = $$(el); $el.replaceWith( art(path.join(__dirname, 'templates/description.art'), { images: $el.attr('src') ? [ { src: $el.attr('src'), width: $el.attr('width'), height: $el.attr('height'), }, ] : undefined, }) ); }); const title: string = $$('h1.entry-title').text(); const pubDateStr: string | undefined = $$('time.entry-date').attr('datetime'); const categoryEls: Element[] = $$('ul.post-categories li').toArray(); const categories: string[] = [...new Set(categoryEls.map((el) => $$(el).text()).filter(Boolean))]; const upDatedStr: string | undefined = pubDateStr; let processedItem: DataItem = { title, pubDate: pubDateStr ? parseDate(pubDateStr) : item.pubDate, category: categories, updated: upDatedStr ? parseDate(upDatedStr) : item.updated, language, }; const extraLinkEls: Element[] = $$('ul.related_post li a').toArray(); const extraLinks = extraLinkEls .map((extraLinkEl) => { const $$extraLinkEl: Cheerio<Element> = $$(extraLinkEl); return { url: $$extraLinkEl.attr('href'), type: 'related', content_html: $$extraLinkEl.text(), }; }) .filter((_): _ is { url: string; type: string; content_html: string } => true); if (extraLinks) { processedItem = { ...processedItem, _extra: { links: extraLinks, }, }; } $$('ul.related_post').parent().remove(); const description: string | undefined = $$('div.entry-content').html(); processedItem = { ...processedItem, description, content: { html: description, text: description, }, }; return { ...item, ...processedItem, }; }); }) ) ).filter((_): _ is DataItem => true); const title: string = $('title').text(); return { title, description: $('meta[name="description"]').attr('content'), link: targetUrl, item: items, allowEmpty: true, image: $('h3.site-title img').attr('src'), author: title.split(/-/).pop()?.trim(), language, id: targetUrl, }; }; export const route: Route = { path: '/:category{.+}?', name: '资讯', url: '199it.com', maintainers: ['nczitzk'], handler, example: '/199it/newly', parameters: { category: { description: '分类,默认为 `newly`,即最新,可在对应分类页 URL 中找到', options: [ { label: '最新', value: 'newly', }, { label: '报告', value: 'archives/category/report', }, { label: '新兴产业', value: 'archives/category/emerging', }, { label: '金融科技', value: 'archives/category/fintech', }, { label: '共享经济', value: 'archives/category/sharingeconomy', }, { label: '移动互联网', value: 'archives/category/mobile-internet', }, { label: '电子商务', value: 'archives/category/electronic-commerce', }, { label: '社交网络', value: 'archives/category/social-network', }, { label: '网络广告', value: 'archives/category/advertising', }, { label: '投资&amp;经济,互联网金融', value: 'archives/category/economic-data', }, { label: '服务', value: 'archives/category/service', }, { label: '网络服务行业', value: 'archives/category/dataindustry', }, { label: '用户研究', value: 'archives/category/internet-users', }, ], }, }, description: `:::tip 若订阅 [研究报告](https://www.199it.com/archives/category/report),网址为 \`https://www.199it.com/archives/category/report\`,请截取 \`https://www.199it.com/archives/category/report\` 到末尾的部分 \`archives/category/report\` 作为 \`category\` 参数填入,此时目标路由为 [\`/199it/archives/category/report\`](https://rsshub.app/199it/archives/category/report)。 ::: <details> <summary>更多分类</summary> | 分类 | ID | | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | [报告](http://www.199it.com/archives/category/report) | [archives/category/report](https://rsshub.app/199it/archives/category/report) | | [新兴产业](http://www.199it.com/archives/category/emerging) | [archives/category/emerging](https://rsshub.app/199it/archives/category/emerging) | | [金融科技](http://www.199it.com/archives/category/fintech) | [archives/category/fintech](https://rsshub.app/199it/archives/category/fintech) | | [共享经济](http://www.199it.com/archives/category/sharingeconomy) | [archives/category/sharingeconomy](https://rsshub.app/199it/archives/category/sharingeconomy) | | [移动互联网](http://www.199it.com/archives/category/mobile-internet) | [archives/category/mobile-internet](https://rsshub.app/199it/archives/category/mobile-internet) | | [电子商务](http://www.199it.com/archives/category/electronic-commerce) | [archives/category/electronic-commerce](https://rsshub.app/199it/archives/category/electronic-commerce) | | [社交网络](http://www.199it.com/archives/category/social-network) | [archives/category/social-network](https://rsshub.app/199it/archives/category/social-network) | | [网络广告](http://www.199it.com/archives/category/advertising) | [archives/category/advertising](https://rsshub.app/199it/archives/category/advertising) | | [投资&amp;经济,互联网金融](http://www.199it.com/archives/category/economic-data) | [archives/category/economic-data](https://rsshub.app/199it/archives/category/economic-data) | | [服务](http://www.199it.com/archives/category/service) | [archives/category/service](https://rsshub.app/199it/archives/category/service) | | [网络服务行业](http://www.199it.com/archives/category/dataindustry) | [archives/category/dataindustry](https://rsshub.app/199it/archives/category/dataindustry) | | [用户研究](http://www.199it.com/archives/category/internet-users) | [archives/category/internet-users](https://rsshub.app/199it/archives/category/internet-users) | </details> `, categories: ['new-media'], features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportRadar: true, supportBT: false, supportPodcast: false, supportScihub: false, }, radar: [ { source: ['www.199it.com/:category'], target: (params) => { const category: string = params.category; return `/199it${category ? `/${category}` : ''}`; }, }, { title: '最新', source: ['www.199it.com/newly'], target: '/newly', }, { title: '报告', source: ['www.199it.com/archives/category/report'], target: '/archives/category/report', }, { title: '新兴产业', source: ['www.199it.com/archives/category/emerging'], target: '/archives/category/emerging', }, { title: '金融科技', source: ['www.199it.com/archives/category/fintech'], target: '/archives/category/fintech', }, { title: '共享经济', source: ['www.199it.com/archives/category/sharingeconomy'], target: '/archives/category/sharingeconomy', }, { title: '移动互联网', source: ['www.199it.com/archives/category/mobile-internet'], target: '/archives/category/mobile-internet', }, { title: '电子商务', source: ['www.199it.com/archives/category/electronic-commerce'], target: '/archives/category/electronic-commerce', }, { title: '社交网络', source: ['www.199it.com/archives/category/social-network'], target: '/archives/category/social-network', }, { title: '网络广告', source: ['www.199it.com/archives/category/advertising'], target: '/archives/category/advertising', }, { title: '投资&amp;经济,互联网金融', source: ['www.199it.com/archives/category/economic-data'], target: '/archives/category/economic-data', }, { title: '服务', source: ['www.199it.com/archives/category/service'], target: '/archives/category/service', }, { title: '网络服务行业', source: ['www.199it.com/archives/category/dataindustry'], target: '/archives/category/dataindustry', }, { title: '用户研究', source: ['www.199it.com/archives/category/internet-users'], target: '/archives/category/internet-users', }, ], view: ViewType.Articles, };