diff --git a/docs/multimedia.md b/docs/multimedia.md
index 58d699c72d..9a8b2833b4 100644
--- a/docs/multimedia.md
+++ b/docs/multimedia.md
@@ -4,6 +4,12 @@ pageClass: routes
# 音视频
+## 60-Second Science - Scientific American
+
+### Transcript
+
+
+
## 99% Invisible
### Transcript
diff --git a/docs/new-media.md b/docs/new-media.md
index a9321d41a9..e43896dce2 100644
--- a/docs/new-media.md
+++ b/docs/new-media.md
@@ -27,6 +27,20 @@ pageClass: routes
+## AEON
+
+
+
+支持以文体分类:
+| Ideas | Essays | Videos |
+| ----- | ------ | ------ |
+| ideas | essays | videos |
+
+同样支持以话题分类:
+| Culture | Philosophy | Psychology | Society | Science |
+| ------- | ---------- | ---------- | ------- | ------- |
+| culture | philosophy | psychology | society | science |
+
## BOF
### 首页
diff --git a/lib/router.js b/lib/router.js
index 9a97aa0e01..95f5d526f4 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -782,6 +782,9 @@ router.get('/laosiji/hot', require('./routes/laosiji/hot'));
router.get('/laosiji/feed', require('./routes/laosiji/feed'));
router.get('/laosiji/hotshow/:id', require('./routes/laosiji/hotshow'));
+// Scientific American 60-Second Science
+router.get('/60s-science/transcript', require('./routes/60s-science/transcript'));
+
// 99% Invisible
router.get('/99percentinvisible/transcript', require('./routes/99percentinvisible/transcript'));
@@ -1422,6 +1425,9 @@ router.get('/ningmeng/song', require('./routes/ningmeng/song'));
// 紫竹张
router.get('/zzz', require('./routes/zzz/index'));
+// AEON
+router.get('/aeon/:cid', require('./routes/aeon/category'));
+
// AlgoCasts
router.get('/algocasts', require('./routes/algocasts/all'));
diff --git a/lib/routes/60s-science/transcript.js b/lib/routes/60s-science/transcript.js
new file mode 100644
index 0000000000..13e2d90a99
--- /dev/null
+++ b/lib/routes/60s-science/transcript.js
@@ -0,0 +1,48 @@
+const cheerio = require('cheerio');
+const got = require('@/utils/got');
+
+module.exports = async (ctx) => {
+ const url = `https://www.scientificamerican.com/podcast/60-second-science/`;
+
+ const res = await got.get(url);
+ const $ = cheerio.load(res.data);
+ const list = $('.underlined_text.t_small').get();
+
+ const out = await Promise.all(
+ list.map(async (item) => {
+ const $ = cheerio.load(item);
+ const title = $(item).attr('aria-label');
+ const address = $(item).attr('href');
+ const cache = await ctx.cache.get(address);
+ if (cache) {
+ return Promise.resolve(JSON.parse(cache));
+ }
+ const res = await got.get(address);
+ const capture = cheerio.load(res.data);
+
+ const tStr = '.article-header__divider > ul > li > span:nth-child(2)';
+ const time = capture(tStr).text();
+ const aStr = '.article-header__divider > ul > li > span:nth-child(1) > span';
+ const author = capture(aStr).text();
+
+ capture('.transcript__close').remove();
+ const intro = capture('.article-media__object').html() + '
';
+ const contents = intro + capture('.transcript__inner').html();
+ const single = {
+ title,
+ description: contents,
+ link: address,
+ guid: address,
+ author: author,
+ pubDate: new Date(time).toUTCString(),
+ };
+ ctx.cache.set(address, JSON.stringify(single));
+ return Promise.resolve(single);
+ })
+ );
+ ctx.state.data = {
+ title: 'Transcripts of SA 60-Second Science',
+ link: url,
+ item: out,
+ };
+};
diff --git a/lib/routes/aeon/category.js b/lib/routes/aeon/category.js
new file mode 100644
index 0000000000..7afb8c32c5
--- /dev/null
+++ b/lib/routes/aeon/category.js
@@ -0,0 +1,86 @@
+const cheerio = require('cheerio');
+const got = require('@/utils/got');
+
+module.exports = async (ctx) => {
+ const url = `https://aeon.co/${ctx.params.cid}`;
+
+ const res = await got.get(url);
+ const $ = cheerio.load(res.data);
+ const list = $('.article-card').get();
+
+ const out = await Promise.all(
+ list.map(async (item) => {
+ const $ = cheerio.load(item);
+ const title = $('.article-card__title').text();
+ const partial = $('.article-card__title').attr('href');
+ const address = `https://aeon.co${partial}`;
+ const author = $('.article-card__authors__inner').text();
+
+ const cache = await ctx.cache.get(address);
+ if (cache) {
+ return Promise.resolve(JSON.parse(cache));
+ }
+
+ const res = await got.get(address);
+ const capture = cheerio.load(res.data);
+ const time = capture('.article__date.published').text();
+
+ capture('div.newsletter-signup').remove();
+ capture('div.pullquote').remove();
+ capture('div.article__related').remove();
+ capture('div.article__shares').remove();
+
+ let bio;
+ const authorInfo = '.article__body__author-details > p:nth-child(2)';
+ if (capture(authorInfo).html() !== null) {
+ bio =
+ `
` +
+ author.trim() +
+ ' ' +
+ capture(authorInfo)
+ .html()
+ .trim() +
+ `
`;
+ capture('.article__inline-sidebar').remove();
+ } else {
+ bio = '';
+ }
+
+ let banner;
+ if (capture('.article-card__image-wrap').html() !== null) {
+ const imgSty = capture('figure.responsive-image').attr('style');
+ const imgLink = imgSty.match(/url\(["']?([^"']*)["']?\)/)[1];
+ banner = `
`;
+ }
+ if (capture('.article__image__wrapper').html() !== null) {
+ banner = '';
+ capture('img').each((index, item) => {
+ item = $(item);
+ item.removeAttr('alt');
+ });
+ capture('.display-article').remove;
+ }
+ if (capture('.video__embed').html() !== null) {
+ banner = capture('div.video__embed').html();
+ capture('.article__header__subtitle').remove();
+ }
+
+ const contents = banner + capture('.article__body__content').html() + bio;
+ const single = {
+ title,
+ author: author,
+ pubDate: new Date(time).toUTCString(),
+ description: contents,
+ link: address,
+ guid: address,
+ };
+ ctx.cache.set(address, JSON.stringify(single));
+ return Promise.resolve(single);
+ })
+ );
+ ctx.state.data = {
+ title: $('title').text(),
+ link: url,
+ item: out,
+ };
+};