diff --git a/docs/traditional-media.md b/docs/traditional-media.md index 8e0bb2f196..2addd8ccda 100644 --- a/docs/traditional-media.md +++ b/docs/traditional-media.md @@ -1621,21 +1621,136 @@ category 对应的关键词有 ### 首页头条 - + ### 频道 - + -| 视频 | 时事 | 财经 | 思想 | 澎湃号 | 生活 | -| ----- | ----- | ----- | ----- | ----- | ----- | -| 26916 | 25950 | 25951 | 25952 | 36079 | 25953 | +| 频道 ID | 频道名 | +| ------ | --- | +| 25949 | 要闻 | +| 26916 | 视频 | +| 108856 | 战疫 | +| 25950 | 时事 | +| 25951 | 财经 | +| 36079 | 澎湃号 | +| 119908 | 科技 | +| 25952 | 思想 | +| 119489 | 智库 | +| 25953 | 生活 | +| 26161 | 问吧 | +| -21 | 体育 | +| -24 | 评论 | +| -23 | 国际 | -### 列表 +### 栏目 - + + +| 栏目 ID | 栏目名 | +| ------ | ------- | +| 26912 | 上直播 | +| 26913 | 七环视频 | +| 26965 | 温度计 | +| 26908 | 一级视场 | +| 27260 | World 湃 | +| 26907 | 湃客科技 | +| 33168 | 纪录湃 | +| 26911 | 围观 | +| 26918 | @所有人 | +| 26906 | 大都会 | +| 26909 | 追光灯 | +| 26910 | 运动装 | +| 26914 | 健寻记 | +| 82188 | AI 播报 | +| 89035 | 眼界 | +| 92278 | 关键帧 | +| 90069 | 战疫 | +| 25462 | 中国政库 | +| 25488 | 中南海 | +| 97924 | 初心之路 | +| 25489 | 舆论场 | +| 25490 | 打虎记 | +| 25423 | 人事风向 | +| 25426 | 法治中国 | +| 25424 | 一号专案 | +| 25463 | 港台来信 | +| 25491 | 长三角政商 | +| 25428 | 直击现场 | +| 68750 | 公益湃 | +| 27604 | 暖闻 | +| 25464 | 澎湃质量报告 | +| 25425 | 绿政公署 | +| 25429 | 澎湃国际 | +| 25481 | 外交学人 | +| 25430 | 澎湃防务 | +| 25678 | 唐人街 | +| 25427 | 澎湃人物 | +| 25422 | 浦江头条 | +| 25487 | 教育家 | +| 25634 | 全景现场 | +| 25635 | 美数课 | +| 25600 | 快看 | +| 25434 | 10% 公司 | +| 25436 | 能见度 | +| 25433 | 地产界 | +| 25438 | 财经上下游 | +| 25435 | 金改实验室 | +| 25437 | 牛市点线面 | +| 119963 | IPO 最前线 | +| 25485 | 澎湃商学院 | +| 25432 | 自贸区连线 | +| 37978 | 进博会在线 | +| 36079 | 湃客 | +| 27392 | 政务 | +| 77286 | 媒体 | +| 27234 | 科学湃 | +| 119445 | 生命科学 | +| 119447 | 未来 2% | +| 119446 | 元宇宙观察 | +| 119448 | 科创 101 | +| 119449 | 科学城邦 | +| 25444 | 社论 | +| 27224 | 澎湃评论 | +| 26525 | 思想湃 | +| 26878 | 上海书评 | +| 25483 | 思想市场 | +| 25457 | 私家历史 | +| 25574 | 翻书党 | +| 25455 | 艺术评论 | +| 26937 | 古代艺术 | +| 25450 | 文化课 | +| 25482 | 逝者 | +| 25536 | 专栏 | +| 26506 | 异次元 | +| 97313 | 海平面 | +| 103076 | 一问三知 | +| 25445 | 澎湃研究所 | +| 25446 | 全球智库 | +| 26915 | 城市漫步 | +| 25456 | 市政厅 | +| 104191 | 世界会客厅 | +| 25448 | 有戏 | +| 26609 | 文艺范 | +| 25942 | 身体 | +| 26015 | 私・奔 | +| 25599 | 运动家 | +| 25842 | 私家地理 | +| 80623 | 非常品 | +| 26862 | 楼市 | +| 25769 | 生活方式 | +| 25990 | 澎湃联播 | +| 26173 | 视界 | +| 26202 | 亲子学堂 | +| 26404 | 赢家 | +| 26490 | 汽车圈 | +| 115327 | IP SH | +| 117340 | 酒业 | + + ### 明查 diff --git a/lib/v2/thepaper/channel.js b/lib/v2/thepaper/channel.js index 5ba356b625..4a22c8414f 100644 --- a/lib/v2/thepaper/channel.js +++ b/lib/v2/thepaper/channel.js @@ -1,15 +1,18 @@ const utils = require('./utils'); +const cheerio = require('cheerio'); +const got = require('@/utils/got'); module.exports = async (ctx) => { const { id } = ctx.params; - const rootUrl = 'https://m.thepaper.cn'; - - const link = id === '26916' ? `${rootUrl}/channel_26916` : `${rootUrl}/list_page.jsp?nodeid=${id}&isList=0&pageidx=1`; - const items = await utils.ProcessFeed(id === '26916' ? '.list_video_item' : '.list_item_infor', link, ctx); + const channel_url = `https://m.thepaper.cn/channel/${id}`; + const response = await got(channel_url); + const data = JSON.parse(cheerio.load(response.data)('#__NEXT_DATA__').html()); + const list = data.props.pageProps.data.list; + const items = await Promise.all(list.map((item) => utils.ProcessItem(item, ctx))); ctx.state.data = { - title: `澎湃新闻频道 - ${id}`, - link: `${rootUrl}/channel_${id}`, + title: `澎湃新闻频道 - ${utils.ChannelIdToName(id, data)}`, + link: channel_url, item: items, }; }; diff --git a/lib/v2/thepaper/featured.js b/lib/v2/thepaper/featured.js index 31e4e7fa04..bb237b9fe4 100644 --- a/lib/v2/thepaper/featured.js +++ b/lib/v2/thepaper/featured.js @@ -1,14 +1,17 @@ const utils = require('./utils'); +const cheerio = require('cheerio'); +const got = require('@/utils/got'); module.exports = async (ctx) => { - const rootUrl = 'https://m.thepaper.cn'; + const response = await got('https://m.thepaper.cn'); + const data = JSON.parse(cheerio.load(response.data)('#__NEXT_DATA__').html()); + const list = data.props.pageProps.data.list; - const link = `${rootUrl}/list_page.jsp?&nodeid=25949&isList=1&pageidx=1`; - const items = await utils.ProcessFeed('.list_item_infor', link, ctx); + const items = await Promise.all(list.map((item) => utils.ProcessItem(item, ctx))); ctx.state.data = { title: '澎湃新闻 - 首页头条', - link: `${rootUrl}/channel_25949`, + link: 'https://m.thepaper.cn', item: items, }; }; diff --git a/lib/v2/thepaper/list.js b/lib/v2/thepaper/list.js index 4988961ea7..06c417c7fa 100644 --- a/lib/v2/thepaper/list.js +++ b/lib/v2/thepaper/list.js @@ -1,15 +1,19 @@ const utils = require('./utils'); +const cheerio = require('cheerio'); +const got = require('@/utils/got'); module.exports = async (ctx) => { const { id } = ctx.params; - const rootUrl = 'https://m.thepaper.cn'; + const list_url = `https://m.thepaper.cn/list/${id}`; + const response = await got(list_url); + const data = JSON.parse(cheerio.load(response.data)('#__NEXT_DATA__').html()); + const list = data.props.pageProps.data.list; - const link = `${rootUrl}/list_page.jsp?nodeid=${id}&isList=1&pageidx=1`; - const items = await utils.ProcessFeed('.list_item_infor', link, ctx); + const items = await Promise.all(list.map((item) => utils.ProcessItem(item, ctx))); ctx.state.data = { - title: `澎湃新闻列表 - ${id}`, - link: `${rootUrl}/list_${id}`, + title: `澎湃新闻栏目 - ${utils.ListIdToName(id, data)}`, + link: list_url, item: items, }; }; diff --git a/lib/v2/thepaper/maintainer.js b/lib/v2/thepaper/maintainer.js index b348757802..c985bbd3fe 100644 --- a/lib/v2/thepaper/maintainer.js +++ b/lib/v2/thepaper/maintainer.js @@ -1,8 +1,8 @@ module.exports = { '/839studio/:id': ['umm233'], '/839studio': ['umm233'], - '/channel/:id': ['xyqfer', 'nczitzk'], - '/featured': ['HenryQW', 'nczitzk'], + '/channel/:id': ['xyqfer', 'nczitzk', 'bigfei'], + '/featured': ['HenryQW', 'nczitzk', 'bigfei'], '/factpaper/:status?': ['nczitzk'], - '/list/:id': ['nczitzk'], + '/list/:id': ['nczitzk', 'bigfei'], }; diff --git a/lib/v2/thepaper/radar.js b/lib/v2/thepaper/radar.js index 42cf1c2c2b..ac9ef6ff04 100644 --- a/lib/v2/thepaper/radar.js +++ b/lib/v2/thepaper/radar.js @@ -15,10 +15,10 @@ module.exports = { target: (params, url) => `/thepaper/channel/${new URL(url).search(/channel_(\d+)/)}`, }, { - title: '列表', + title: '栏目', docs: 'https://docs.rsshub.app/traditional-media.html#peng-pai-xin-wen-lie-biao', source: ['/'], - target: (params, url) => `/thepaper/channel/${new URL(url).search(/list_(\d+)/)}`, + target: (params, url) => `/thepaper/list/${new URL(url).search(/list_(\d+)/)}`, }, { title: '澎湃美数组作品集', diff --git a/lib/v2/thepaper/templates/video_detail.art b/lib/v2/thepaper/templates/video_detail.art new file mode 100644 index 0000000000..f8ac883f24 --- /dev/null +++ b/lib/v2/thepaper/templates/video_detail.art @@ -0,0 +1,6 @@ + diff --git a/lib/v2/thepaper/utils.js b/lib/v2/thepaper/utils.js index 29850b5827..a96b03fd5a 100644 --- a/lib/v2/thepaper/utils.js +++ b/lib/v2/thepaper/utils.js @@ -1,55 +1,70 @@ const cheerio = require('cheerio'); -const date = require('@/utils/date'); const { parseDate } = require('@/utils/parse-date'); -const timezone = require('@/utils/timezone'); const got = require('@/utils/got'); +const { art } = require('@/utils/render'); +const path = require('path'); module.exports = { - ProcessFeed: async (query, link, ctx) => { - const res = await got(link); + ProcessItem: async (item, ctx) => { + if (item.link) { + // external link + return { + title: item.name, + link: item.link, + description: item.name, + pubDate: parseDate(item.pubTimeLong), + media: { + content: { + url: item.pic, + }, + }, + }; + } else { + const itemUrl = `https://m.thepaper.cn/detail/${item.contId}`; + return await ctx.cache.tryGet(itemUrl, async () => { + const res = await got(itemUrl); + const data = JSON.parse(cheerio.load(res.data)('#__NEXT_DATA__').html()); + const detailData = data.props.pageProps.detailData; - const $ = cheerio.load(res.data); - const list = $(query).slice(0, 10).get(); + const contentDetail = detailData.contentDetail || detailData.liveDetail; + let description = contentDetail.content || contentDetail.summary; - return Promise.all( - list.map((item) => { - const $ = cheerio.load(item); - const itemUrl = `https://m.thepaper.cn/${$(item).find('a').eq(0).attr('href')}`; - return ctx.cache.tryGet(itemUrl, async () => { - const res = await got(itemUrl); - const content = cheerio.load(res.data); + if (contentDetail.videos) { + description = + art(path.join(__dirname, 'templates/video_detail.art'), { + videos: contentDetail.videos, + }) + description; + } - let description, pubDate; - - if (content('div.news_video_msg').length > 0) { - description = content('#vdetail_sum').html(); - pubDate = timezone( - parseDate( - content('div.news_video_msg') - .html() - .replace(/ /gi, '') - .split('
')[0] - ), - +8 - ); - } else if (content('#slider_wrapper_ul').length > 0) { - description = ''; - pubDate = new Date(date($(item).find('div.list_item_extra span').eq(1).text())).toUTCString(); - } else { - description = content('div.newsdetail_content').html(); - pubDate = timezone(parseDate(content('div.date').text().trim().split('来源:')[0].trim()), +8); + return { + title: contentDetail.name, + link: itemUrl, + description, + pubDate: parseDate(contentDetail.pubTime), + author: contentDetail.author, + media: { + content: { + url: item.pic || contentDetail.sharePic || (contentDetail.videos && contentDetail.videos.coverUrl), + }, + thumbnails: { + url: item.pic || contentDetail.sharePic, + }, + }, + }; + }); + } + }, + ChannelIdToName: (nodeId, next_data) => next_data.props.appProps.menu.channelList.find((c) => c.nodeId.toString() === nodeId.toString()).name, + ListIdToName: (listId, next_data) => { + const channelList = next_data.props.appProps.menu.channelList; + for (const c of channelList) { + if (c.childNodeList && c.childNodeList.length > 0) { + for (const l of c.childNodeList) { + if (l.nodeId.toString() === listId.toString()) { + return l.name; } - - const single = { - title: content('title').text(), - link: itemUrl, - description, - pubDate, - author: content('div.author').text(), - }; - return single; - }); - }) - ); + } + } + } }, };