fix(route): Futubull Headlines (#12562)
This commit is contained in:
parent
c802e041a0
commit
d824a628a3
|
|
@ -53,6 +53,12 @@ pageClass: routes
|
|||
|
||||
<RouteEn author="HenryQW" example="/finviz/news/AAPL" path="/finviz/news/:ticker" :paramsDesc="['The stock ticker']"/>
|
||||
|
||||
## Futubull
|
||||
|
||||
### Headlines
|
||||
|
||||
<RouteEn author="Wsine nczitzk" example="/futunn/main" path="/futunn/main" />
|
||||
|
||||
## FX Markets
|
||||
|
||||
### Channel
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ TokenInsight 官方亦有提供 RSS,可参考 <https://api.tokeninsight.com/re
|
|||
|
||||
### 要闻
|
||||
|
||||
<Route author="Wsine" example="/futunn/highlights" path="/futunn/highlights" />
|
||||
<Route author="Wsine nczitzk" example="/futunn/main" path="/futunn/main" />
|
||||
|
||||
## 格隆汇
|
||||
|
||||
|
|
|
|||
|
|
@ -2882,7 +2882,7 @@ router.get('/gov/chinatax/latest', lazyloadRouteHandler('./routes/gov/chinatax/l
|
|||
router.get('/lizhi/user/:id', lazyloadRouteHandler('./routes/lizhi/user'));
|
||||
|
||||
// 富途牛牛
|
||||
router.get('/futunn/highlights', lazyloadRouteHandler('./routes/futunn/highlights'));
|
||||
// router.get('/futunn/highlights', lazyloadRouteHandler('./routes/futunn/highlights'));
|
||||
|
||||
// 即刻 migrated to v2
|
||||
// router.get('/jike/topic/:id', lazyloadRouteHandler('./routes/jike/topic'));
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const timezone = require('@/utils/timezone');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const link = `https://news.futunn.com/main`;
|
||||
|
||||
const response = await got.get(link);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const contents = $('script:not([src]):contains("window._params")');
|
||||
const params = contents.html().trim().slice(17, -1);
|
||||
|
||||
const newslist = JSON.parse(params).preList;
|
||||
|
||||
const out = await Promise.all(
|
||||
newslist
|
||||
.filter((info) => {
|
||||
const url = new URL(info.url);
|
||||
if (url.hostname !== 'news.futunn.com') {
|
||||
// ignore videos.futunn.com
|
||||
return false;
|
||||
} else if (url.searchParams.get('src') !== '3') {
|
||||
// ignore src=12 redirecting to mp.weixin.qq.com
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((info) =>
|
||||
ctx.cache.tryGet(info.url, async () => {
|
||||
const response = await got({
|
||||
url: info.url,
|
||||
method: 'get',
|
||||
headers: {
|
||||
Referer: link,
|
||||
},
|
||||
});
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
const description = $('div.newsDetailBox div.main div.inner').html();
|
||||
const date = $('div.timeBar').children().remove().end().text().trim();
|
||||
|
||||
info.link = info.url;
|
||||
info.description = description;
|
||||
info.pubDate = timezone(parseDate(date, 'YYYY/MM/DD HH:mm'), +8);
|
||||
|
||||
return info;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `富途牛牛要闻`,
|
||||
link,
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
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 limit = ctx.query.limit ? parseInt(ctx.query.limit) : 50;
|
||||
|
||||
const rootUrl = 'https://news.futunn.com';
|
||||
const currentUrl = `${rootUrl}/main`;
|
||||
const apiUrl = `${rootUrl}/news-site-api/main/get-market-list?size=${limit}`;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: apiUrl,
|
||||
});
|
||||
|
||||
let items = response.data.data.list.map((item) => ({
|
||||
title: item.title,
|
||||
link: item.url.split('?')[0],
|
||||
author: item.source,
|
||||
pubDate: parseDate(item.timestamp * 1000),
|
||||
description: art(path.join(__dirname, 'templates/description.art'), {
|
||||
abs: item.abs,
|
||||
pic: item.pic,
|
||||
}),
|
||||
}));
|
||||
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
if (/news\.futunn\.com/.test(item.link)) {
|
||||
const detailResponse = await got({
|
||||
method: 'get',
|
||||
url: item.link,
|
||||
});
|
||||
|
||||
const content = cheerio.load(detailResponse.data);
|
||||
|
||||
content('.futu-news-time-stamp').remove();
|
||||
content('.nnstock').each(function () {
|
||||
content(this).replaceWith(`<a href="${content(this).attr('href')}">${content(this).text().replace(/\$/g, '')}</a>`);
|
||||
});
|
||||
|
||||
item.description = content('.origin_content').html();
|
||||
item.category = [
|
||||
...content('.news__from-topic__title')
|
||||
.toArray()
|
||||
.map((a) => content(a).text()),
|
||||
...content('#relatedStockWeb .stock-name')
|
||||
.toArray()
|
||||
.map((s) => content(s).text().trim()),
|
||||
];
|
||||
}
|
||||
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: 'Futubull - Headlines',
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
'/main': ['Wsine', 'nczitzk'],
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
'futunn.com': {
|
||||
_name: '富途牛牛',
|
||||
news: [
|
||||
{
|
||||
title: '要闻',
|
||||
docs: 'https://docs.rsshub.app/finance.html#fu-tu-niu-niu',
|
||||
source: ['/main', '/'],
|
||||
target: '/futunn/main',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/highlights', require('./main'));
|
||||
router.get('/main', require('./main'));
|
||||
router.get('/', require('./main'));
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{{ if pic }}
|
||||
<img src="{{ pic }}">
|
||||
{{ /if }}
|
||||
{{ if abs }}
|
||||
<p>{{ abs }}</p>
|
||||
{{ /if }}
|
||||
Loading…
Reference in New Issue