diff --git a/docs/install/README.md b/docs/install/README.md index 498d17ba0d..8aff6ed90c 100644 --- a/docs/install/README.md +++ b/docs/install/README.md @@ -491,6 +491,12 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行 - `SCIHUB_HOST`: 可访问的 sci-hub 镜像地址,默认为 `https://sci-hub.tw`。 +- 端传媒设置,用于获取付费内容全文: + + - `INITIUM_USERNAME`: 端传媒用户名 + + - `INITIUM_PASSWORD`: 端传媒密码 + - BTBYR - `BTBYR_HOST`: 支持 ipv4 访问的 BTBYR 镜像,默认为原站 `https://bt.byr.cn/`。 diff --git a/docs/traditional-media.md b/docs/traditional-media.md index 2fbe226a36..49fbfda3bd 100644 --- a/docs/traditional-media.md +++ b/docs/traditional-media.md @@ -174,6 +174,27 @@ Category 列表: +## 端传媒 + +### 端传媒 + + + +::: warning 注意 + +付费内容全文需要登陆获取,详情见部署页面的配置模块。 + +::: + +Type 栏目: + +| 深度 | What’s New | 广场 | Pick-Up | +| ------- | ---------- | ----------------- | ------- | +| feature | news-brief | notes-and-letters | pick_up | + +通过提取文章全文,以提供比官方源更佳的阅读体验. + + ## 多维新闻网 ### 要闻 diff --git a/lib/config.js b/lib/config.js index 56f97bdba0..c810fd344b 100644 --- a/lib/config.js +++ b/lib/config.js @@ -134,6 +134,10 @@ const calculateValue = () => { hotlink: { template: envs.HOTLINK_TEMPLATE, }, + initium: { + username: envs.INITIUM_USERNAME, + password: envs.INITIUM_PASSWORD, + }, btbyr: { host: envs.BTBYR_HOST || 'https://bt.byr.cn/', cookies: envs.BTBYR_COOKIE, diff --git a/lib/router.js b/lib/router.js index c6ae0333d4..9aa1f50b8c 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2691,6 +2691,9 @@ router.get('/umass/amherst/csnews', require('./routes/umass/amherst/csnews')); // 飘花电影网 router.get('/piaohua/hot', require('./routes/piaohua/hot')); +// 端传媒 +router.get('/initium/:type?/:language?', require('./routes/initium/full')); + // Grub Street router.get('/grubstreet', require('./routes/grubstreet/index')); diff --git a/lib/routes/infzm/news.js b/lib/routes/infzm/news.js index 332e624e6e..4ed89f8114 100644 --- a/lib/routes/infzm/news.js +++ b/lib/routes/infzm/news.js @@ -5,7 +5,7 @@ const baseUrl = 'http://www.infzm.com/contents'; module.exports = async (ctx) => { const { id } = ctx.params; - const link = `${baseUrl}?term_id${id}`; + const link = `${baseUrl}?term_id=${id}`; const response = await got({ method: 'get', url: `http://www.infzm.com/contents?term_id=${id}&page=1&format=json`, diff --git a/lib/routes/initium/full.js b/lib/routes/initium/full.js new file mode 100644 index 0000000000..4650b13bc1 --- /dev/null +++ b/lib/routes/initium/full.js @@ -0,0 +1,114 @@ +const got = require('@/utils/got'); +const config = require('@/config').value; +const resolve_url = require('url').resolve; + +module.exports = async (ctx) => { + const type = ctx.params.type || 'feature'; + const language = ctx.params.language || 'zh-hans'; + + const key = { + email: config.initium.username, + password: config.initium.password, + }; + const body = JSON.stringify(key); + + let token; + const cache = await ctx.cache.get('INITIUM_TOKEN'); + if (cache) { + token = cache; + } else if (key.email === undefined) { + token = 'Basic YW5vbnltb3VzOkdpQ2VMRWp4bnFCY1ZwbnA2Y0xzVXZKaWV2dlJRY0FYTHY='; + } else { + const login = await got({ + method: 'post', + url: `https://api.theinitium.com/api/v1/auth/login/?language=${language}`, + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + Connection: 'keep-alive', + Authorization: 'Basic YW5vbnltb3VzOkdpQ2VMRWp4bnFCY1ZwbnA2Y0xzVXZKaWV2dlJRY0FYTHY=', + Origin: `https://theinitium.com/`, + Referer: `https://theinitium.com/`, + }, + body: body, + }); + + const devices = login.data.access.devices; + + for (const key in devices) { + const device = devices[key]; + if (device.status === 'logged_in' && !device.logout_at && device.platform === 'web') { + token = 'Bearer ' + device.device_id; + break; + } + } + ctx.cache.set('INITIUM_TOKEN', token); + } + + const response = await got({ + method: 'get', + url: `https://api.theinitium.com/api/v1/channel/articles/?language=${language}&slug=${type}`, + headers: { + 'X-Client-Name': 'Web', + Accept: '*/*', + Connection: 'keep-alive', + Authorization: token, + Origin: `https://theinitium.com/`, + Referer: `https://theinitium.com/`, + }, + }); + + const name = response.data.name; + const articles = response.data.digests; + + const getFullText = async (slug) => { + let content = await ctx.cache.get(slug + language); + if (content) { + return content; + } + + content = ''; + + const response = await got({ + method: 'get', + url: `https://api.theinitium.com/api/v1/article/detail/?language=${language}&slug=${slug}`, + headers: { + 'X-Client-Name': 'web', + Accept: '*/*', + Connection: 'keep-alive', + Authorization: token, + Origin: `https://theinitium.com/`, + Referer: `https://theinitium.com/`, + }, + }); + + const data = response.data; + + if (data.lead.length) { + content += '

「' + data.lead + '」

'; + } + if (data.byline.length) { + content += '

' + data.byline + '

'; + } + content += data.content.replace('