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('
', '').replace(/ ({
+ title: item.article.headline,
+ description: await getFullText(item.article.slug),
+ link: resolve_url('https://theinitium.com', item.article.url),
+ pubDate: item.article.date,
+ }))
+ );
+
+ ctx.state.data = {
+ title: `端传媒 - ${name}`,
+ link: `https://theinitium.com`,
+ item: items,
+ };
+};