fix(route): apnews without puppeteer (#10006)

This commit is contained in:
Tony
2022-06-22 17:59:36 +08:00
committed by GitHub
parent 1cf6925187
commit 8a6c54054a
11 changed files with 80 additions and 62 deletions
-1
View File
@@ -485,7 +485,6 @@
},
],
},
'apnews.com': { _name: 'AP News', '.': [{ title: '话题', docs: 'https://docs.rsshub.app/traditional-media.html#ap-news', source: '/:topic', target: '/apnews/topics/:topic' }] },
'biquge5200.com': { www: [{ title: 'biquge5200.com', docs: 'https://docs.rsshub.app/reading.html#bi-qu-ge-biquge5200-com', source: '/:id', target: '/novel/biquge/:id' }] },
'biquge.info': { www: [{ title: 'biquge.info', docs: 'https://docs.rsshub.app/reading.html#bi-qu-ge-biquge-info', source: '/:id', target: '/novel/biqugeinfo/:id' }] },
'matters.news': {
+1 -1
View File
@@ -60,7 +60,7 @@ The following are some of the supported Channel and Topic ids.
### Topics
<RouteEn author="zoenglinghou mjysci" example="/apnews/topics/apf-topnews" path="/apnews/topics/:topic" :paramsDesc="['Topic namecan be found in URL. For example: the topic name of AP Top News [https://apnews.com/apf-topnews](https://apnews.com/apf-topnews) is `apf-topnews`']" radar="1" rssbud="1" anticrawler="1" puppeteer="1"/>
<RouteEn author="zoenglinghou mjysci TonyRL" example="/apnews/topics/apf-topnews" path="/apnews/topics/:topic?" :paramsDesc="['Topic namecan be found in URL. For example: the topic name of AP Top News [https://apnews.com/apf-topnews](https://apnews.com/apf-topnews) is `apf-topnews`, `trending-news` by default']" radar="1" rssbud="1" />
## BBC
+1 -5
View File
@@ -66,11 +66,7 @@ pageClass: routes
### 话题
<Route author="zoenglinghou mjysci" example="/apnews/topics/ap-top-news" path="/apnews/topics/:topic" :paramsDesc="['话题名称,可在 URL 中找到,例如 AP Top News [https://apnews.com/hub/ap-top-news](https://apnews.com/hub/ap-top-news) 的话题为 `ap-top-news`']" radar="1" rssbud="1" anticrawler="1" puppeteer="1">
采用了 `puppeteer` 规避 `Project Shield`,无全文抓取,建议自建。
</Route>
<Route author="zoenglinghou mjysci TonyRL" example="/apnews/topics/ap-top-news" path="/apnews/topics/:topic?" :paramsDesc="['话题名称,可在 URL 中找到,例如 AP Top News [https://apnews.com/hub/ap-top-news](https://apnews.com/hub/ap-top-news) 的话题为 `ap-top-news`,默认为 `trending-news`']" radar="1" rssbud="1" />
## BBC
-11
View File
@@ -1135,17 +1135,6 @@ module.exports = {
},
],
},
'apnews.com': {
_name: 'AP News',
'.': [
{
title: '话题',
docs: 'https://docs.rsshub.app/traditional-media.html#ap-news',
source: '/:topic',
target: '/apnews/topics/:topic',
},
],
},
'csc.edu.cn': {
_name: '国家留学网',
www: [
+1 -1
View File
@@ -2364,7 +2364,7 @@ router.get('/xinquji/today/internal', lazyloadRouteHandler('./routes/xinquji/int
router.get('/gbcc/trust', lazyloadRouteHandler('./routes/gbcc/trust'));
// Associated Press
router.get('/apnews/topics/:topic', lazyloadRouteHandler('./routes/apnews/topics'));
// router.get('/apnews/topics/:topic', lazyloadRouteHandler('./routes/apnews/topics'));
// CBC
router.get('/cbc/topics/:topic?', lazyloadRouteHandler('./routes/cbc/topics'));
-43
View File
@@ -1,43 +0,0 @@
const cheerio = require('cheerio');
const HOME_PAGE = 'https://apnews.com';
module.exports = async (ctx) => {
const topic = ctx.params.topic;
const browser = await require('@/utils/puppeteer')();
const page = await browser.newPage();
const url_link = `${HOME_PAGE}/hub/${topic}`;
await page.goto(url_link);
const html = await page.evaluate(() => document.documentElement.innerHTML);
browser.close();
const $ = cheerio.load(html);
const list = $('div.FeedCard');
ctx.state.data = {
title: $('.Body div').find('h1[class^=hubTitle]').text(),
link: HOME_PAGE,
item: list
.slice(0, 5)
.map((index, item) => {
item = $(item);
const title = item.find('h3[class^=Component-heading-]').text();
const link = item.find('a[class^=Component-headline-]').attr('href');
const pubDate = item.find('span[class^=Timestamp]').attr('title');
const text = item.find('div[class^=content]').text();
const imageUrl = item.find('img[class^=image-]').attr('src');
const author = item.find('span[class^=Component-bylines-]').text().slice(3);
return {
title,
description: `<img src="${imageUrl}">` + text,
link: `${HOME_PAGE}${link}`,
pubDate,
author,
};
})
.get(),
};
};
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
'/topics/:topic?': ['zoenglinghou', 'mjysci', 'TonyRL'],
};
+13
View File
@@ -0,0 +1,13 @@
module.exports = {
'apnews.com': {
_name: 'AP News',
'.': [
{
title: '话题',
docs: 'https://docs.rsshub.app/traditional-media.html#ap-news',
source: '/hub/:topic',
target: '/apnews/topics/:topic',
},
],
},
};
+3
View File
@@ -0,0 +1,3 @@
module.exports = (router) => {
router.get('/topics/:topic?', require('./topics'));
};
+14
View File
@@ -0,0 +1,14 @@
{{ if media }}
{{ each media }}
{{ if $value.type === 'Photo' }}
<figure>
<img src="{{ $value.gcsBaseUrl + $value.imageRenderedSizes[0] + $value.imageFileExtension }}" alt="{{ $value.flattenedCaption }}">
<figcaption>{{@ $value.caption }}</figcaption>
</figure>
{{ else if $value.type === 'YouTube' }}
<iframe id="ytplayer" type="text/html" width="640" height="360" src="https://www.youtube-nocookie.com/embed/{{ $value.externalId }}" frameborder="0" allowfullscreen></iframe>
{{ if $value.caption }}{{@ $value.caption }}{{ /if }}
{{ /if }}
{{ /each }}
{{ /if }}
{{@ description }}
+44
View File
@@ -0,0 +1,44 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
const { art } = require('@/utils/render');
const path = require('path');
const HOME_PAGE = 'https://apnews.com';
module.exports = async (ctx) => {
const { topic = 'trending-news' } = ctx.params;
const urlLink = `${HOME_PAGE}/hub/${topic}`;
const response = await got(urlLink);
const $ = cheerio.load(response.data);
const data = JSON.parse(
$('script')
.not('[src], [type]')
.text()
.match(/window\['titanium-state'\] = (.*)\nwindow\['titanium-cacheConfig'\]/)[1]
);
const meta = data.hub.data[`/${topic}`];
const items = meta.cards.map((item) => {
const description = cheerio.load(item.contents[0].storyHTML, null, false);
description('.ad-placeholder').remove();
return {
title: item.contents[0].headline,
description: art(path.join(__dirname, 'templates/description.art'), {
media: item.contents[0].media,
description: description.html(),
}),
link: `${HOME_PAGE}/article/${item.contents[0].canonicalUrl}-${item.contents[0].shortId}`,
author: item.contents[0].bylines ? item.contents[0].bylines.slice(3) : null,
pubDate: parseDate(item.contents[0].published),
category: item.contents[0].tagObjs.map((tag) => tag.name),
};
});
ctx.state.data = {
title: meta.tagObjs[0].seoTitle,
description: meta.tagObjs[0].seoDescription,
link: urlLink,
item: items,
language: $('html').attr('lang'),
};
};