diff --git a/docs/study.md b/docs/study.md index 7ad3e3c27..fcfb5dcd6 100644 --- a/docs/study.md +++ b/docs/study.md @@ -4,6 +4,39 @@ pageClass: routes # 学习 +## 51VOA 美国之音 + +### 频道 + + + +| `:channel` | 对应网站栏目 | +| ----------- | -------------------------------------------- | +| standard | 常速英语(VOA Standard English ) | +| archive | 常速英语存档(VOA Standard English Archives ) | +| technology | 科技报道(Technology Report) | +| daily | 今日美国(This is America) | +| sciences | 科技报道(Science in the News) | +| health | 健康报道(Health Report) | +| education | 教育报道(Education Report) | +| economics | 经济报道(Economics Report) | +| culture | 文化艺术(American Mosaic) | +| events | 时事新闻(In the News) | +| stories | 美国故事(American Stories) | +| words | 词汇掌故(Words And Their Stories) | +| trending | 今日热点(Trending Today) | +| magazine | 新闻杂志(AS IT IS) | +| grammar | 日常语法(Everyday Grammar) | +| queries | 名师答疑(Ask a Teacher) | +| history | 美国历史(U.S. History) | +| park | 国家公园(America's National Parks) | +| president | 美国总统(America's Presidents) | +| agriculture | 农业报道(Agriculture Report) | +| exploration | 自然探索(Explorations) | +| people | 美国人物(People in America) | +| bilingual | 双语新闻(Bilingual News) | +| address | 总统演讲(President Address) | + ## CTFHub Calendar ### 查询国内外 CTF 赛事信息 diff --git a/lib/router.js b/lib/router.js index 1a597aa1a..85001dea9 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2540,6 +2540,9 @@ router.get('/girlimg/album/:tag?/:mode?', require('./routes/girlimg/album')); // etoland router.get('/etoland/:bo_table', require('./routes/etoland/board')); +// 51voa +router.get('/51voa/:channel', require('./routes/51voa/channel')); + // zhuixinfan router.get('/zhuixinfan/list', require('./routes/zhuixinfan/list')); diff --git a/lib/routes/51voa/channel.js b/lib/routes/51voa/channel.js new file mode 100644 index 000000000..277a11e99 --- /dev/null +++ b/lib/routes/51voa/channel.js @@ -0,0 +1,158 @@ +const got = require('@/utils/got'); +const date = require('@/utils/date'); +const cheerio = require('cheerio'); + +const HOST = 'https://www.51voa.com'; +const PAGE_ROUTER = { + standard: { + url: 'https://www.51voa.com/VOA_Standard_1.html', + title: '常速英语', + }, + archive: { + url: 'https://www.51voa.com/VOA_Standard_1_archiver.html', + title: '常速英语存档', + }, + + technology: { + url: 'https://www.51voa.com/Technology_Report_1.html', + title: '科技报道', + }, + daily: { + url: 'https://www.51voa.com/This_is_America_1.html', + title: '今日美国', + }, + sciences: { + url: 'https://www.51voa.com/Science_in_the_News_1.html', + title: '科学报道', + }, + health: { + url: 'https://www.51voa.com/Health_Report_1.html', + title: '健康报道', + }, + education: { + url: 'https://www.51voa.com/Education_Report_1.html', + title: '教育报道', + }, + economics: { + url: 'https://www.51voa.com/Economics_Report_1.html', + title: '经济报道', + }, + culture: { + url: 'https://www.51voa.com/American_Mosaic_1.html', + title: '文化艺术', + }, + events: { + url: 'https://www.51voa.com/In_the_News_1.html', + title: '时事新闻', + }, + stories: { + url: 'https://www.51voa.com/American_Stories_1.html', + title: '美国故事', + }, + words: { + url: 'https://www.51voa.com/Words_And_Their_Stories_1.html', + title: '词汇掌故', + }, + trending: { + url: 'https://www.51voa.com/Trending_Today_1.html', + title: '今日热点', + }, + magazine: { + url: 'https://www.51voa.com/as_it_is_1.html', + title: '新闻杂志', + }, + grammar: { + url: 'https://www.51voa.com/Everyday_Grammar_1.html', + title: '日常语法', + }, + queries: { + url: 'https://www.51voa.com/ask_a_teacher_1.html', + title: '名师答疑', + }, + history: { + url: 'https://www.51voa.com/The_Making_of_a_Nation_1.html', + title: '美国历史', + }, + park: { + url: 'https://www.51voa.com/National_Parks_1.html', + title: '国家公园', + }, + president: { + url: 'https://www.51voa.com/Americas_Presidents_1.html', + title: '美国总统', + }, + agriculture: { + url: 'https://www.51voa.com/Agriculture_Report_1.html', + title: '农业报道', + }, + exploration: { + url: 'https://www.51voa.com/Explorations_1.html', + title: '自然探索', + }, + people: { + url: 'https://www.51voa.com/People_in_America_1.html', + title: '美国人物', + }, + bilingual: { + url: 'https://www.51voa.com/Bilingual_News_1.html', + title: '双语新闻', + }, + address: { + url: 'https://www.51voa.com/President_Address_1.html', + title: '总统演讲', + }, +}; + +module.exports = async (ctx) => { + const { channel } = ctx.params; + const { url, title } = PAGE_ROUTER[channel] || {}; + + const response = await got({ + method: 'get', + url: url, + }); + + const $ = cheerio.load(response.data); + const list = $('div.List ul li>a') + .slice(0, 5) + .map((i, e) => $(e).attr('href')) + .get(); + + const out = await Promise.all( + list.map(async (link) => { + const pageUrl = HOST + link; + const cache = await ctx.cache.get(link); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + + const response = await got({ + method: 'get', + url: pageUrl, + headers: { + Referer: url, + }, + }); + + const $ = cheerio.load(response.data); + + const single = { + pubDate: date($('div.Content>span.datetime').text()), + link: $('div.title h1').text(), + title: title, + description: $('div.Content').html(), + category: ['study', 'English'], + }; + + ctx.cache.set(link, JSON.stringify(single)); + return Promise.resolve(single); + }) + ); + + ctx.state.data = { + title: title, + link: url, + description: '51voa - ' + channel, + item: out, + }; +};