fix(route): 日本经济新闻中文版 (#11994)
* fix(route): 日本经济新闻中文版 * fix: missing language * refactor: migrate nikkei to v2 * refactor: merge nikkei-cn into nikkei * refactor: merge nikkei-asia into nikkei ---------
This commit is contained in:
parent
1878fca9e5
commit
ca9efda5d4
|
|
@ -166,7 +166,6 @@
|
|||
{ title: '标签最近更新', docs: 'https://docs.rsshub.app/multimedia.html#mqube', source: '/search/tag/:tag', target: '/mqube/tag/:tag' },
|
||||
],
|
||||
},
|
||||
'nikkei.com': { _name: '日本経済新聞', www: [{ title: 'ホームページ', docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen', source: '/', target: '/nikkei/index' }] },
|
||||
'last.fm': {
|
||||
_name: 'Last.fm',
|
||||
www: [
|
||||
|
|
|
|||
|
|
@ -350,17 +350,11 @@ Only `s00017` is in English.
|
|||
| hi | id | ko | fa | pt | ru | es |
|
||||
|
||||
| Kiswahili | ภาษาไทย | Türkçe | Українська | اردو | Tiếng Việt |
|
||||
| --------- | | ------- | ------ | ---------- | ---- | ---------- |
|
||||
| --------- | ------- | ------ | ---------- | ---- | ---------- |
|
||||
| sw | th | tr | uk | ur | vi |
|
||||
|
||||
</RouteEn>
|
||||
|
||||
## Nikkei Asia
|
||||
|
||||
### Latest News
|
||||
|
||||
<RouteEn author="rainrdx" example="/nikkei-asia" path="/nikkei-asia"/>
|
||||
|
||||
## Radio Free Asia (RFA)
|
||||
|
||||
### News
|
||||
|
|
@ -660,6 +654,26 @@ Provides all of the articles by the specified New York Times author.
|
|||
| series-books|
|
||||
| young-adult-hardcover|
|
||||
|
||||
## The Nikkei 日本経済新聞
|
||||
|
||||
### Home
|
||||
|
||||
<RouteEn author="zjysdhr" example="/nikkei/index" path="/nikkei/index" radar="1" rssbud="1" />
|
||||
|
||||
### News
|
||||
|
||||
<RouteEn author="Arracc" example="/nikkei/news" path="/nikkei/:category/:article_type?" :paramsDesc="['Category, see table below','Only includes free articles, set `free` to enable, disabled by default']">
|
||||
|
||||
| 総合 | オピニオン | 経済 | 政治 | 金融 | マーケット | ビジネス | マネーのまなび | テック | 国際 | スポーツ | 社会・調査 | 地域 | 文化 | ライフスタイル |
|
||||
| ---- | --------- | ------- | -------- | --------- | -------- | ------- | ----------- | ---------- | ------------- | ------- | --------- | ------- | ------- | ------------- |
|
||||
| news | opinion | economy | politics | financial | business | 不支持 | 不支持 | technology | international | sports | society | local | culture | lifestyle |
|
||||
|
||||
</RouteEn>
|
||||
|
||||
### Nikkei Asia Latest News
|
||||
|
||||
<RouteEn author="rainrdx" example="/nikkei/asia" path="/nikkei/asia" radar="1"/>
|
||||
|
||||
## The Wall Street Journal (WSJ)
|
||||
|
||||
### News
|
||||
|
|
|
|||
|
|
@ -305,12 +305,6 @@ pageClass: routes
|
|||
|
||||
</Route>
|
||||
|
||||
## Nikkei Asia
|
||||
|
||||
### 最新新闻
|
||||
|
||||
<Route author="rainrdx" example="/nikkei-asia" path="/nikkei-asia"/>
|
||||
|
||||
## Now 新聞
|
||||
|
||||
### 新聞
|
||||
|
|
@ -1069,7 +1063,7 @@ IT・科学 tech_science
|
|||
|
||||
### 最新报道
|
||||
|
||||
<Route author="Rongronggg9" example="/kyodonews" path="/kyodonews/:language?/:keyword?" :paramsDesc="['语言: `china` = 简体中文 (默认), `tchina` = 繁體中文', '关键词']">
|
||||
<Route author="Rongronggg9" example="/kyodonews" path="/kyodonews/:language?/:keyword?" :paramsDesc="['语言: `china` = 简体中文 (默认), `tchina` = 繁體中文', '关键词']">
|
||||
|
||||
`keyword` 为关键词,由于共同网有许多关键词并不在主页列出,此处不一一列举,可从关键词页的 URL 的最后一级路径中提取。如 `日中关系` 的关键词页 URL 为 `https://china.kyodonews.net/news/japan-china_relationship`, 则将 `japan-china_relationship` 填入 `keyword`。特别地,当填入 `rss` 时,将从共同网官方 RSS 中抓取文章;略去时,将从首页抓取最新报道 (注意:首页更新可能比官方 RSS 稍慢)。
|
||||
|
||||
|
|
@ -1938,45 +1932,43 @@ category 对应的关键词有
|
|||
|
||||
</Route>
|
||||
|
||||
## 日本经济新闻中文版
|
||||
## 日本经济新闻
|
||||
|
||||
### 新闻
|
||||
### 首页
|
||||
|
||||
<Route author="nczitzk" example="/nikkei-cn" path="/nikkei-cn/:language?/:category?/:type?" :paramsDesc="['语言,可选 `zh` 即 繁体中文,`cn` 即 简体中文', '分类,默认为空,可在对应分类页 URL 中找到', '子分类,默认为空,可在对应分类页 URL 中找到']" radar="1" rssbud="1">
|
||||
<Route author="zjysdhr" example="/nikkei/index" path="/nikkei/index" radar="1" rssbud="1" />
|
||||
|
||||
### 新聞
|
||||
|
||||
<Route author="Arracc" example="/nikkei/news" path="/nikkei/:category/:article_type?" :paramsDesc="['版块', '文章类型,`free` 仅无料全文,缺省为无料全文、有料非全文']">
|
||||
|
||||
综合页文章标题添加板块标签
|
||||
|
||||
| 総合 | オピニオン | 経済 | 政治 | 金融 | マーケット | ビジネス | マネーのまなび | テック | 国際 | スポーツ | 社会・調査 | 地域 | 文化 | ライフスタイル |
|
||||
| ---- | ------- | ------- | -------- | --------- | -------- | ---- | ------- | ---------- | ------------- | ------ | ------- | ----- | ------- | --------- |
|
||||
| news | opinion | economy | politics | financial | business | 不支持 | 不支持 | technology | international | sports | society | local | culture | lifestyle |
|
||||
|
||||
</Route>
|
||||
|
||||
### 中文版新闻
|
||||
|
||||
<Route author="nczitzk" example="/nikkei/cn" path="/nikkei/cn/:language?/:path?" :paramsDesc="['语言,可选 `zh` 即 繁体中文,`cn` 即 简体中文', '类目路径,默认为空,可在对应类目页 URL 中找到']" radar="1" rssbud="1">
|
||||
|
||||
::: tip 提示
|
||||
|
||||
如 [中国 经济 日经中文网](https://cn.nikkei.com/china/ceconomy.html) 的 URL 为 <https://cn.nikkei.com/china/ceconomy.html> 对应路由为 [`/nikkei-cn/cn/china/ceconomy`](https://rsshub.app/nikkei-cn/cn/china/ceconomy)
|
||||
如 [中国 经济 日经中文网](https://cn.nikkei.com/china/ceconomy.html) 的 URL 为 <https://cn.nikkei.com/china/ceconomy.html> 对应路由为 [`/nikkei/cn/cn/china/ceconomy`](https://rsshub.app/nikkei/cn/cn/china/ceconomy)
|
||||
|
||||
如 [中國 經濟 日經中文網](https://zh.cn.nikkei.com/china/ceconomy.html) 的 URL 为 <https://zh.cn.nikkei.com/china/ceconomy.html> 对应路由为 [`/nikkei-cn/zh/china/ceconomy`](https://rsshub.app/nikkei-cn/zh/china/ceconomy)
|
||||
如 [中國 經濟 日經中文網](https://zh.cn.nikkei.com/china/ceconomy.html) 的 URL 为 <https://zh.cn.nikkei.com/china/ceconomy.html> 对应路由为 [`/nikkei/cn/zh/china/ceconomy`](https://rsshub.app/nikkei/cn/zh/china/ceconomy)
|
||||
|
||||
特别地,当 `category` 填入 `rss` 后(即路由为 [`/nikkei-cn/cn/rss`](https://rsshub.app/nikkei-cn/cn/rss)),此时返回的是 [官方 RSS 的内容](https://cn.nikkei.com/rss.html)
|
||||
特别地,当 `path` 填入 `rss` 后(如路由为 [`/nikkei/cn/cn/rss`](https://rsshub.app/nikkei/cn/cn/rss)),此时返回的是 [官方 RSS 的内容](https://cn.nikkei.com/rss.html)
|
||||
|
||||
:::
|
||||
|
||||
</Route>
|
||||
|
||||
## 日本経済新聞
|
||||
### Nikkei Asia 最新新闻
|
||||
|
||||
### ホームページ
|
||||
|
||||
<Route author="zjysdhr" example="/nikkei/index" path="/nikkei/index" radar="1" rssbud="1">
|
||||
|
||||
日文版首页
|
||||
|
||||
</Route>
|
||||
|
||||
### 新聞
|
||||
|
||||
<Route author="Arracc" example="/nikkei/news" path="/nikkei/:category/:article_type?" :paramsDesc="['版块','文章类型,free 仅无料全文,缺省为无料全文、有料非全文']">
|
||||
|
||||
综合页文章标题添加板块标签
|
||||
|
||||
| 総合 | マネーのまなび | 経済・金融 | 政治 | ビジネス | マネーのまなび | テクノロジー | 国際 | スポーツ | 社会・くらし | オピニオン | 文化 | FT | 地域 | 日経ビジネス | ライフ |
|
||||
| ---- | ------- | ------- | -------- | -------- | ------- | ---------- | ------------- | ------ | ------- | ------- | ------- | --- | ----- | ------ | --- |
|
||||
| news | 未支持 | economy | politics | business | 未支持 | technology | international | sports | society | opinion | culture | 未支持 | local | 未支持 | 未支持 |
|
||||
|
||||
</Route>
|
||||
<Route author="rainrdx" example="/nikkei/asia" path="/nikkei/asia" radar="1"/>
|
||||
|
||||
## 厦门网
|
||||
|
||||
|
|
|
|||
|
|
@ -411,17 +411,6 @@ module.exports = {
|
|||
},
|
||||
],
|
||||
},
|
||||
'nikkei.com': {
|
||||
_name: '日本経済新聞',
|
||||
www: [
|
||||
{
|
||||
title: 'ホームページ',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen',
|
||||
source: '/',
|
||||
target: '/nikkei/index',
|
||||
},
|
||||
],
|
||||
},
|
||||
'last.fm': {
|
||||
_name: 'Last.fm',
|
||||
www: [
|
||||
|
|
|
|||
|
|
@ -2402,8 +2402,8 @@ router.get('/coronavirus/yahoo-japan/:tdfk?', lazyloadRouteHandler('./routes/cor
|
|||
router.get('/njfu/jwc/:category?', lazyloadRouteHandler('./routes/universities/njfu/jwc'));
|
||||
|
||||
// 日本経済新聞
|
||||
router.get('/nikkei/index', lazyloadRouteHandler('./routes/nikkei/index'));
|
||||
router.get('/nikkei/:category/:article_type?', lazyloadRouteHandler('./routes/nikkei/news'));
|
||||
// router.get('/nikkei/index', lazyloadRouteHandler('./routes/nikkei/index'));
|
||||
// router.get('/nikkei/:category/:article_type?', lazyloadRouteHandler('./routes/nikkei/news'));
|
||||
|
||||
// MQube
|
||||
router.get('/mqube/user/:user', lazyloadRouteHandler('./routes/mqube/user'));
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const url = 'https://www.nikkei.com';
|
||||
const response = await got({ method: 'get', url });
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('div[data-rn-track-category]')
|
||||
.map((_, e) => {
|
||||
const element = $(e);
|
||||
const title = element.data('rn-track-value').title;
|
||||
const link = url + element.find('a').attr('href');
|
||||
|
||||
const src = element.find('img').attr('src');
|
||||
const dataSrc = element.find('img').attr('data-src');
|
||||
|
||||
const imgSrc = dataSrc ? dataSrc : src;
|
||||
const desc = `<img src="${imgSrc}" />` + element.find('div .k-card__excerpt');
|
||||
|
||||
return {
|
||||
title,
|
||||
description: desc,
|
||||
link,
|
||||
};
|
||||
})
|
||||
.get();
|
||||
|
||||
ctx.state.data = {
|
||||
title: '日本経済新聞',
|
||||
link: url,
|
||||
item: list,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const category = ctx.params.category;
|
||||
const article_type = ctx.params.article_type;
|
||||
let url = '';
|
||||
if (category === 'news') {
|
||||
url = `https://www.nikkei.com`;
|
||||
} else {
|
||||
url = `https://www.nikkei.com/${category}/archive`;
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url,
|
||||
});
|
||||
const data = response.data;
|
||||
const $ = cheerio.load(data);
|
||||
|
||||
let categoryName = '';
|
||||
let list = null;
|
||||
let iconElement = '';
|
||||
if (category === 'news') {
|
||||
categoryName = '総合';
|
||||
list = $('div.k-card.k-card--small.k-card--reverse,.k-card--headline').not('[data-rn-track="hub-ad-recommend"]').not('.k-hub-card--small-title');
|
||||
iconElement = 'li.k-card__icon';
|
||||
} else {
|
||||
categoryName = $('h1.l-miH11_title').text().trim();
|
||||
list = $('div#CONTENTS_MAIN').children('div.m-miM09').not('.PRa');
|
||||
iconElement = 'span.m-iconMember';
|
||||
}
|
||||
|
||||
const deleteItems = [];
|
||||
const items = await Promise.all(
|
||||
list
|
||||
.map(async (index, item) => {
|
||||
item = $(item);
|
||||
let title = '';
|
||||
let link = '';
|
||||
const memberLimit = item.find(iconElement).length > 0;
|
||||
|
||||
if (memberLimit && article_type === 'free') {
|
||||
deleteItems.push(title);
|
||||
return {
|
||||
title,
|
||||
description: '',
|
||||
link,
|
||||
};
|
||||
} else {
|
||||
if (category === 'news') {
|
||||
title = item.find('a').eq(0).text();
|
||||
link = item.find('a.k-card__block-link').eq(0).attr('href');
|
||||
} else {
|
||||
title = item.children('h3').children('a').text();
|
||||
link = item.find('a').eq(0).attr('href');
|
||||
}
|
||||
if (link.substring(0, 4) !== 'http') {
|
||||
link = 'https://www.nikkei.com' + link;
|
||||
}
|
||||
|
||||
const tagArr = [];
|
||||
if (categoryName === '総合') {
|
||||
const tagTable = {
|
||||
economy: '経済・金融',
|
||||
politics: '政治',
|
||||
business: 'ビジネス',
|
||||
technology: 'テクノロジー',
|
||||
international: '国際',
|
||||
sports: 'スポーツ',
|
||||
society: '社会・くらし',
|
||||
opinion: 'オピニオン',
|
||||
culture: '文化',
|
||||
local: '地域',
|
||||
style: 'ライフ',
|
||||
};
|
||||
item.find('li.k-card__tag')
|
||||
.children()
|
||||
.each((index, item) => {
|
||||
const tagPath = $(item).attr('href');
|
||||
let tag = '';
|
||||
if (tagPath.indexOf('?dw') >= 0) {
|
||||
tag = $('a[href="https://www.nikkei.com' + tagPath.replace('?', '/?') + '"]')
|
||||
.parent()
|
||||
.parent()
|
||||
.parent()
|
||||
.parent()
|
||||
.parent()
|
||||
.children('a')
|
||||
.text();
|
||||
} else if (tagPath.indexOf('style') >= 0) {
|
||||
tag = 'ライフ';
|
||||
} else {
|
||||
tag = tagTable[tagPath.split('/')[1]];
|
||||
}
|
||||
tag = tag ? tag : 'コラム';
|
||||
if (tag !== 'トップ' && tagArr.indexOf(tag) < 0) {
|
||||
tagArr.push(tag);
|
||||
}
|
||||
});
|
||||
const start = tagArr.indexOf('コラム');
|
||||
if (start >= 0 && tagArr.length > 1) {
|
||||
tagArr.splice(start, 1);
|
||||
}
|
||||
}
|
||||
if (memberLimit) {
|
||||
tagArr.push('会員限定');
|
||||
}
|
||||
if (tagArr.length > 0) {
|
||||
title = '[' + tagArr.join(' ') + '] ' + title;
|
||||
}
|
||||
|
||||
const description = await ctx.cache.tryGet(link, async () => {
|
||||
const response = await got.get(link);
|
||||
const $ = cheerio.load(response.data);
|
||||
if ($('section.container_cz8tiun').length > 0) {
|
||||
$('section.container_cz8tiun')
|
||||
.find('figure')
|
||||
.each((index, item) => {
|
||||
const imgSrc = $(item).attr('data-src-for-image-viewer');
|
||||
const $imgElement = $('<img src="' + imgSrc + '"/>');
|
||||
$(item).prepend($imgElement);
|
||||
});
|
||||
return $('section.container_cz8tiun').html();
|
||||
} else {
|
||||
return $('div.sc-54bcr2-2.jMNzyO').html();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
link,
|
||||
};
|
||||
}
|
||||
})
|
||||
.get()
|
||||
);
|
||||
|
||||
for (const deleteItem of deleteItems) {
|
||||
for (let index = 0; index < items.length; index++) {
|
||||
const item = items[index];
|
||||
if (item.title === deleteItem) {
|
||||
items.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.state.data = {
|
||||
title: '日本経済新聞-' + categoryName,
|
||||
link: url,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
'/nikkei-asia': ['rainrdx'],
|
||||
};
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
module.exports = {
|
||||
'nikkei.com': {
|
||||
_name: 'Nikkei Asia',
|
||||
asia: [
|
||||
{
|
||||
title: 'Latest News',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#nikkei-asia',
|
||||
source: '/',
|
||||
target: '/nikkei-asia/',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/', require('./index'));
|
||||
};
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const timezone = require('@/utils/timezone');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { isValidHost } = require('@/utils/valid-host');
|
||||
|
||||
const cleanContent = (language, content) => {
|
||||
switch (language) {
|
||||
case 'cn': {
|
||||
return content.replace(/<strong>版权声明:日本经济新闻社版权所有,未经授权不得转载或部分复制,违者必究。<\/strong>/g, '');
|
||||
}
|
||||
case 'zh': {
|
||||
return content.replace(/<strong>版權聲明:日本經濟新聞社版權所有,未經授權不得轉載或部分複製,違者必究。<\/strong>/g, '');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getPubDate = (link) => {
|
||||
const matches = link.match(/(\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}|\d{8})/);
|
||||
return matches ? timezone(parseDate(matches[1], 'YYYY-MM-DD-HH-mm-ss'), +9) : undefined;
|
||||
};
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const language = ctx.params.language ?? 'cn';
|
||||
const category = ctx.params.category ?? '';
|
||||
const type = ctx.params.type ?? '';
|
||||
if (!isValidHost(language)) {
|
||||
throw Error('Invalid language');
|
||||
}
|
||||
|
||||
const rootUrl = `https://${language === 'zh' ? `zh.cn` : language}.nikkei.com`;
|
||||
const currentUrl = `${rootUrl}/${category ? (category === 'rss' ? 'rss.html' : `${category}${type ? `/${type}` : ''}.html`) : ''}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
let items =
|
||||
category === 'rss'
|
||||
? response.data.match(/<link>(http:\/\/.*\.html)<\/link>/g).map((l) => ({
|
||||
link: l.replace(/<(\/)?link>/g, '').replace(/http:/g, 'https:'),
|
||||
pubDate: getPubDate(l),
|
||||
}))
|
||||
: $('dt a, p.newsDetailTtl a, ul.listStyle01 li a, table.sliderContent3 td a')
|
||||
.toArray()
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
|
||||
const link = item.attr('href');
|
||||
|
||||
return {
|
||||
link: `${link.startsWith('http') ? '' : rootUrl}${link}`,
|
||||
pubDate: getPubDate(link),
|
||||
};
|
||||
})
|
||||
.sort((a, b) => b.pubDate - a.pubDate) // desc
|
||||
.reduce((prev, cur) => (prev.length && prev[prev.length - 1].link === cur.link ? prev : [...prev, cur]), []) // deduplicate
|
||||
.slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 25);
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: `${item.link}?tmpl=component&print=1`,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
content('#contentDiv div').first().remove();
|
||||
|
||||
item.author = content('meta[name="author"]').attr('content');
|
||||
item.title = content('meta[name="twitter:title"]').attr('content');
|
||||
item.description = cleanContent(language, content('#contentDiv').html());
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: $('title').first().text(),
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
'/:language?/:category?/:type?': ['nczitzk'],
|
||||
};
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
module.exports = {
|
||||
'nikkei.com': {
|
||||
_name: '日本经济新闻',
|
||||
cn: [
|
||||
{
|
||||
title: '新闻',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen-zhong-wen-ban-xin-wen',
|
||||
source: '/',
|
||||
target: '/nikkei-cn/cn/:category?/:type?',
|
||||
},
|
||||
],
|
||||
zh: [
|
||||
{
|
||||
title: '新聞',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen-zhong-wen-ban-xin-wen',
|
||||
source: '/',
|
||||
target: '/nikkei-cn/zh/:category?/:type?',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/:language?/:category?/:type?', require('./index'));
|
||||
};
|
||||
|
|
@ -22,11 +22,23 @@ module.exports = async (ctx) => {
|
|||
|
||||
item.pubDate = parseDate(item.published);
|
||||
item.link = item.shareurl;
|
||||
item.category = item.section;
|
||||
|
||||
const fulltextcontent = cheerio.load(fulltext.data);
|
||||
item.description = fulltextcontent('section[class="pp-article__body"]')
|
||||
.html()
|
||||
.replace(/\.\.\/\.\.\/\.\.\/\.\.\//g, 'https://main-asianreview-nikkei.content.pugpig.com/');
|
||||
fulltextcontent('.pp-header-group__headline, .lightbox__control, .o-ads, #AdAsia').remove();
|
||||
fulltextcontent('img').each((_, img) => {
|
||||
if (img.attribs.full) {
|
||||
img.attribs.src = img.attribs.full;
|
||||
delete img.attribs.full;
|
||||
}
|
||||
});
|
||||
item.description =
|
||||
fulltextcontent('section[class="pp-article__header"]')
|
||||
.html()
|
||||
.replace(/\.\.\/\.\.\/\.\.\/\.\.\//g, 'https://main-asianreview-nikkei.content.pugpig.com/') +
|
||||
fulltextcontent('section[class="pp-article__body"]')
|
||||
.html()
|
||||
.replace(/\.\.\/\.\.\/\.\.\/\.\.\//g, 'https://main-asianreview-nikkei.content.pugpig.com/');
|
||||
return item;
|
||||
})
|
||||
)
|
||||
|
|
@ -35,6 +47,7 @@ module.exports = async (ctx) => {
|
|||
ctx.state.data = {
|
||||
title: 'Nikkei Asia',
|
||||
link: 'https://asia.nikkei.com',
|
||||
image: 'https://main-asianreview-nikkei.content.pugpig.com/pugpig_assets/admin/pub120x120.jpg',
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const timezone = require('@/utils/timezone');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const parser = require('@/utils/rss-parser');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
let language = '';
|
||||
let path = ctx.path;
|
||||
|
||||
if (!/^\/cn\/(cn|zh)/.test(path)) {
|
||||
language = 'cn';
|
||||
} else {
|
||||
language = path.match(/^\/cn\/(cn|zh)/)[1];
|
||||
path = path.match(new RegExp('\\/cn\\/' + language + '(.*)'))[1];
|
||||
}
|
||||
|
||||
const limit = ctx.query.limit ? parseInt(ctx.query.limit) : 25;
|
||||
|
||||
const rootUrl = `https://${language === 'zh' ? 'zh.' : ''}cn.nikkei.com`;
|
||||
const currentUrl = `${rootUrl}${path}`;
|
||||
const isOfficialRSS = path === `/rss`;
|
||||
let officialFeed;
|
||||
|
||||
let items = [],
|
||||
$;
|
||||
|
||||
if (isOfficialRSS) {
|
||||
officialFeed = await parser.parseURL(currentUrl);
|
||||
items = officialFeed.items.slice(0, limit).map((item) => ({
|
||||
title: item.title,
|
||||
link: `${rootUrl}/x-columnviewpoint/${item.link.match(/\/([\d-]+\.html)/)[1]}`,
|
||||
}));
|
||||
} else {
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: currentUrl,
|
||||
});
|
||||
|
||||
$ = cheerio.load(response.data);
|
||||
|
||||
items = $('dt a')
|
||||
.toArray()
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
|
||||
return {
|
||||
title: item.text(),
|
||||
link: `${rootUrl}/x-columnviewpoint/${item.attr('href').match(/\/([\d-]+\.html)/)[1]}`,
|
||||
};
|
||||
})
|
||||
.reduce((prev, cur) => (prev.length && prev[prev.length - 1].link === cur.link ? prev : [...prev, cur]), [])
|
||||
.slice(0, limit);
|
||||
}
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: `${item.link}?print=1`,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
const divs = content('#contentDiv div');
|
||||
divs.first().remove();
|
||||
divs.last().remove();
|
||||
|
||||
item.pubDate = timezone(parseDate(item.link.match(/\/\d+-(.*?)\.html/)[1], 'YYYY-MM-DD-HH-mm-ss'), +9);
|
||||
|
||||
item.author = content('meta[name="author"]').attr('content');
|
||||
item.title = item.title ?? content('meta[name="twitter:title"]').attr('content');
|
||||
item.description = content('#contentDiv')
|
||||
.html()
|
||||
?.replace(/ /g, '')
|
||||
.replace(/<p><\/p>/g, '');
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: isOfficialRSS ? officialFeed.title : $('title').first().text(),
|
||||
description: isOfficialRSS ? officialFeed.description : '',
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const url = 'https://www.nikkei.com';
|
||||
const response = await got(url);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('a[data-rn-inview-track-value]')
|
||||
.toArray()
|
||||
.map((e) => {
|
||||
e = $(e);
|
||||
const data = e.data('rn-track-value');
|
||||
const title = data.title;
|
||||
const link = `${url}/article/${data.kiji_id_raw}/`;
|
||||
|
||||
const parent = e.parent();
|
||||
const img = parent.find('img[class^=image_]');
|
||||
const imgSrc = img.attr('src');
|
||||
const imgAlt = img.attr('alt');
|
||||
|
||||
const desc = `<img src="${imgSrc}" alt="${imgAlt}">` + (parent.find('[class^=excerptContainer]').length ? parent.find('[class^=excerptContainer]').html() : '');
|
||||
|
||||
return {
|
||||
title,
|
||||
description: desc,
|
||||
link,
|
||||
};
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: '日本経済新聞',
|
||||
link: url,
|
||||
item: list,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
'/asia': ['rainrdx'],
|
||||
'/cn/:language?/:path?': ['nczitzk'],
|
||||
'/index': ['zjysdhr'],
|
||||
'/:category/:article_type?': ['Arracc'],
|
||||
};
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const baseUrl = 'https://www.nikkei.com';
|
||||
const { category, article_type = 'paid' } = ctx.params;
|
||||
let url = '';
|
||||
if (category === 'news') {
|
||||
url = `${baseUrl}/news/category/`;
|
||||
} else {
|
||||
url = `${baseUrl}/${category}/archive/`;
|
||||
}
|
||||
|
||||
const response = await got(url);
|
||||
const data = response.data;
|
||||
const $ = cheerio.load(data);
|
||||
|
||||
let categoryName = '';
|
||||
const listSelector = $('div#CONTENTS_MAIN').children('div.m-miM09').not('.PRa');
|
||||
const paidSelector = 'span.m-iconMember';
|
||||
|
||||
let list = listSelector.toArray().map((item) => {
|
||||
item = $(item);
|
||||
item.find('p a').remove();
|
||||
return {
|
||||
title: item.find('.m-miM09_titleL').text(),
|
||||
link: `${baseUrl}${item.find('.m-miM09_title a').attr('href')}`,
|
||||
image: item.find('.m-miM09_thumb img').removeAttr('style').removeAttr('width').removeAttr('height').parent().html(),
|
||||
category: item
|
||||
.find('.m-miM09_keyword a')
|
||||
.toArray()
|
||||
.map((item) => $(item).text()),
|
||||
paywall: !!item.find(paidSelector).length,
|
||||
};
|
||||
});
|
||||
|
||||
if (category === 'news') {
|
||||
categoryName = '総合';
|
||||
list = list.concat(
|
||||
$('div#CONTENTS_MAIN .m-miM32_itemTitle')
|
||||
.toArray()
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
const a = item.find('a').first();
|
||||
return {
|
||||
title: a.text(),
|
||||
link: `${baseUrl}${a.attr('href')}`,
|
||||
category: item
|
||||
.find('.m-miM32_itemkeyword a')
|
||||
.toArray()
|
||||
.map((item) => $(item).text()),
|
||||
paywall: !!item.find(paidSelector).length,
|
||||
};
|
||||
})
|
||||
);
|
||||
} else {
|
||||
categoryName = $('h1.l-miH11_title').text().trim();
|
||||
}
|
||||
|
||||
const items = await Promise.all(
|
||||
list.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const { data: response } = await got(item.link);
|
||||
const $ = cheerio.load(response);
|
||||
|
||||
$('.notFloated_n1oadkwi').remove();
|
||||
|
||||
item.pubDate = parseDate($('meta[property="article:published_time"]').attr('content'));
|
||||
item.description = art(path.join(__dirname, 'templates/news.art'), {
|
||||
item,
|
||||
description: $('section[class^=container_]').html(),
|
||||
});
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: '日本経済新聞 - ' + categoryName,
|
||||
description: $('meta[name="description"]').attr('content'),
|
||||
link: url,
|
||||
image: $('meta[property="og:image"]').attr('content'),
|
||||
language: 'ja',
|
||||
item: article_type === 'free' ? items.filter((item) => !item.paywall) : items,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
module.exports = {
|
||||
'nikkei.com': {
|
||||
_name: '日本经济新闻',
|
||||
asia: [
|
||||
{
|
||||
title: 'Latest News',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen',
|
||||
source: '/',
|
||||
target: '/nikkei/asia',
|
||||
},
|
||||
],
|
||||
cn: [
|
||||
{
|
||||
title: '中文版新闻',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen-zhong-wen-ban-xin-wen',
|
||||
source: ['/:category/:type', '/:category', '/'],
|
||||
target: (params) => {
|
||||
if (params.category && params.type) {
|
||||
return `/nikkei/cn/cn/${params.category}/${params.type.replace('.html', '')}`;
|
||||
} else if (params.category && !params.type) {
|
||||
return `/nikkei/cn/cn/${params.category.replace('.html', '')}`;
|
||||
} else {
|
||||
return `/nikkei/cn/cn`;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
www: [
|
||||
{
|
||||
title: 'ホームページ',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen',
|
||||
source: '/',
|
||||
target: '/nikkei/index',
|
||||
},
|
||||
{
|
||||
title: '新聞',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen',
|
||||
source: ['/:category/archive', '/:category'],
|
||||
target: '/nikkei/:category',
|
||||
},
|
||||
],
|
||||
'zh.cn': [
|
||||
{
|
||||
title: '中文版新聞',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#ri-ben-jing-ji-xin-wen-zhong-wen-ban-xin-wen',
|
||||
source: ['/:category/:type', '/:category', '/'],
|
||||
target: (params) => {
|
||||
if (params.category && params.type) {
|
||||
return `/nikkei/cn/zh/${params.category}/${params.type.replace('.html', '')}`;
|
||||
} else if (params.category && !params.type) {
|
||||
return `/nikkei/cn/zh/${params.category.replace('.html', '')}`;
|
||||
} else {
|
||||
return `/nikkei/cn/zh`;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = (router) => {
|
||||
router.get('/', require('./index'));
|
||||
router.get('/asia', require('./asia/index'));
|
||||
router.get(/\/cn([\w-/]+)?/, require('./cn/index'));
|
||||
router.get('/index', require('./index'));
|
||||
router.get('/:category/:article_type?', require('./news'));
|
||||
};
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{{ if item.paywall }}
|
||||
{{ if item.image }}{{@ item.image }}<br>{{ /if }}
|
||||
{{ /if }}
|
||||
{{@ description }}
|
||||
Loading…
Reference in New Issue