feat: add 端传媒 (#4787)

This commit is contained in:
prnake
2020-05-18 12:41:34 +08:00
committed by GitHub
parent 58e05978a1
commit a94db47755
6 changed files with 149 additions and 1 deletions

View File

@@ -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/`

View File

@@ -174,6 +174,27 @@ Category 列表:
</Route>
## 端传媒
### 端传媒
<Route author="prnake" example="/initium/feature/zh-hans" path="/initium/:type?/:language?" :paramsDesc="['栏目,缺省为深度''语言,简体`zh-hans`,繁体`zh-hant`,缺省为简体']">
::: warning 注意
付费内容全文需要登陆获取,详情见部署页面的配置模块。
:::
Type 栏目:
| 深度 | Whats New | 广场 | Pick-Up |
| ------- | ---------- | ----------------- | ------- |
| feature | news-brief | notes-and-letters | pick_up |
通过提取文章全文,以提供比官方源更佳的阅读体验.
</Route>
## 多维新闻网
### 要闻

View File

@@ -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,

View File

@@ -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'));

View File

@@ -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`,

114
lib/routes/initium/full.js Normal file
View File

@@ -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 += '<p>「' + data.lead + '」</p>';
}
if (data.byline.length) {
content += '<p>' + data.byline + '</p>';
}
content += data.content.replace('<figure class="advertisement"/><br/>', '').replace(/<figure.class="image.invite_friend_image".*$/g, '');
ctx.cache.set(slug + language, content);
return content;
};
const items = await Promise.all(
articles.map(async (item) => ({
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,
};
};