diff --git a/docs/game.md b/docs/game.md
index 35a1e2827..6db10bcbc 100644
--- a/docs/game.md
+++ b/docs/game.md
@@ -252,6 +252,20 @@ Example: `https://store.steampowered.com/search/?specials=1&term=atelier` 中的
| ------ | ---- | -------- |
| update | hot | spent |
+## 巴哈姆特
+
+### GNN 新闻
+
+
+
+暂无图片
+
+| 首页 | PC | TV 掌機 | 手機遊戲 | 動漫畫 | 主題報導 | 活動展覽 | 電競 |
+| ---- | -- | ------- | -------- | ------ | -------- | -------- | ---- |
+| 缺省 | 1 | 3 | 4 | 5 | 9 | 11 | 13 |
+
+
+
## 二柄 APP
### 新闻
diff --git a/docs/traditional-media.md b/docs/traditional-media.md
index bbe5d4cf4..e914ff81b 100644
--- a/docs/traditional-media.md
+++ b/docs/traditional-media.md
@@ -239,6 +239,18 @@ Category 列表:
+## 読売新聞
+
+### 新聞
+
+
+
+| 総合 | 社会 | 政治 | 経済 | スポーツ | 国際 | 科学・IT | 選挙・世論調査 | エンタメ・文化 | 囲碁・将棋 | ライフ | 地域 | 社説 |
+| ---- | -------- | -------- | ------- | -------- | ----- | ---------- | -------------- | -------------- | ---------- | ------ | ----- | --------- |
+| news | national | politics | economy | sports | world | science | election | culture | igoshougi | life | local | editorial |
+
+
+
## 端传媒
通过提取文章全文,以提供比官方源更佳的阅读体验。
diff --git a/lib/router.js b/lib/router.js
index 20ac5b037..fdba10a88 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -3282,6 +3282,13 @@ router.get('/nobelprize/:caty?', require('./routes/nobelprize/index'));
// 中華民國國防部
router.get('/gov/taiwan/mnd', require('./routes/gov/taiwan/mnd'));
+// 読売新聞
+router.get('/yomiuri/:category?', require('./routes/yomiuri/news'));
+
+// 巴哈姆特
+// GNN新闻
+router.get('/gamer/gnn/:category?', require('./routes/gamer/gnn_index'));
+
// 中国人大网
router.get('/npc/:caty', require('./routes/npc/index'));
diff --git a/lib/routes/gamer/gnn_index.js b/lib/routes/gamer/gnn_index.js
new file mode 100644
index 000000000..b924e0035
--- /dev/null
+++ b/lib/routes/gamer/gnn_index.js
@@ -0,0 +1,99 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+module.exports = async (ctx) => {
+ const category = ctx.params.category;
+ let url = '';
+ let category_name = '';
+ if (!category) {
+ url = 'https://gnn.gamer.com.tw/';
+ category_name = '首页';
+ } else {
+ url = `https://gnn.gamer.com.tw/index.php?k=${category}`;
+ switch (category) {
+ case '1':
+ category_name = 'PC';
+ break;
+ case '3':
+ category_name = 'TV 掌機';
+ break;
+ case '4':
+ category_name = '手機遊戲';
+ break;
+ case '5':
+ category_name = '動漫畫';
+ break;
+ case '9':
+ category_name = '主題報導';
+ break;
+ case '11':
+ category_name = '活動展覽';
+ break;
+ case '13':
+ category_name = '電競';
+ break;
+ default:
+ category_name = '首页';
+ }
+ }
+
+ const response = await got({
+ method: 'get',
+ url: url,
+ });
+
+ const data = response.data;
+ const $ = cheerio.load(data);
+ const list = $('div.BH-lbox.GN-lbox2')
+ .children()
+ .not('.GN-lbox2A,.GN-lbox2G')
+ .map((index, item) => {
+ item = $(item);
+ const position = item.attr('class') === 'GN-lbox2F' ? 0 : 1;
+ const element_a = item.find('a').eq(position);
+ const tag_table = {
+ 'IMG-Gmuti': 'General',
+ 'IMG-GA19': 'PC',
+ 'IMG-GB3': 'NS',
+ 'IMG-GB4': 'PS5',
+ 'IMG-GB1': 'PS4',
+ 'IMG-GA14': 'ARC',
+ 'IMG-GAC': 'AC',
+ 'IMG-GA13': 'ETC',
+ 'IMG-GA1': 'OLG',
+ 'IMG-Gmobi': 'MOBI',
+ 'IMG-GA20': 'WEB',
+ 'IMG-GA25': 'Google',
+ 'IMG-GA24': 'Apple',
+ 'IMG-GA28': 'Facebook',
+ 'IMG-GA17': 'Other',
+ 'IMG-Gother': 'Other',
+ };
+ const key = item.find('img').eq(position).attr('class');
+ const value = tag_table[key];
+ const tag = value ? value : 'Unclassified';
+ return {
+ title: '[' + tag + '] ' + element_a.text(),
+ link: element_a.attr('href').replace('//', 'https://'),
+ };
+ })
+ .get();
+
+ const items = await Promise.all(
+ list.map(async (item) => {
+ // 图片延迟加载无法获取源地址;
+ item.description = await ctx.cache.tryGet(item.link, async () => {
+ const response = await got.get(item.link);
+ const $ = cheerio.load(response.data);
+ return $('div.GN-lbox3B').children('div').html();
+ });
+ return item;
+ })
+ );
+
+ ctx.state.data = {
+ title: '巴哈姆特-GNN新闻-' + category_name,
+ link: url,
+ item: items,
+ };
+};
diff --git a/lib/routes/yomiuri/news.js b/lib/routes/yomiuri/news.js
new file mode 100644
index 000000000..80c2b755e
--- /dev/null
+++ b/lib/routes/yomiuri/news.js
@@ -0,0 +1,49 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+module.exports = async (ctx) => {
+ const category = ctx.params.category;
+ const url = `https://www.yomiuri.co.jp/${category}`;
+
+ const response = await got({
+ method: 'get',
+ url: url,
+ });
+ const data = response.data;
+ const $ = cheerio.load(data);
+
+ let category_name = '';
+ let list = null;
+ if (category === 'news') {
+ category_name = '総合';
+ list = $('ul.news-top-upper-content-topics-content-list.p-list').children('li').not('.p-member-only');
+ } else {
+ category_name = $('h1.p-header-category-current-title').text();
+ list = $('div.p-category-organization,.p-category-time-series').find('li').not('.p-member-only').not('.p-ad-list-item');
+ }
+
+ const items = await Promise.all(
+ list
+ .map(async (index, item) => {
+ item = $(item);
+ const link = item.find('a').attr('href');
+ const description = await ctx.cache.tryGet(link, async () => {
+ const response = await got.get(link);
+ const $ = cheerio.load(response.data);
+ return $('div.p-main-contents').html();
+ });
+ return {
+ title: item.find('a').text(),
+ description,
+ link,
+ };
+ })
+ .get()
+ );
+
+ ctx.state.data = {
+ title: '読売新聞-' + category_name,
+ link: url,
+ item: items,
+ };
+};