From a9d6957e607b3dde0651c830c846004f1d0e7258 Mon Sep 17 00:00:00 2001 From: Tony Date: Fri, 3 Mar 2023 01:59:45 +0800 Subject: [PATCH] feat(route): wxkol (#12010) * feat(route): wxkol * fix: use async pool --- docs/new-media.md | 16 ++++++-- lib/utils/wechat-mp.js | 2 +- lib/v2/wxkol/maintainer.js | 3 ++ lib/v2/wxkol/radar.js | 13 +++++++ lib/v2/wxkol/router.js | 3 ++ lib/v2/wxkol/show.js | 80 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 lib/v2/wxkol/maintainer.js create mode 100644 lib/v2/wxkol/radar.js create mode 100644 lib/v2/wxkol/router.js create mode 100644 lib/v2/wxkol/show.js diff --git a/docs/new-media.md b/docs/new-media.md index 9e0d4114c8..bda7cd64ae 100644 --- a/docs/new-media.md +++ b/docs/new-media.md @@ -3940,6 +3940,12 @@ column 为 third 时可选的 category: +## 微小领 + +### 微信公众号 + + + ## 微信 ::: tip 提示 @@ -3950,15 +3956,15 @@ column 为 third 时可选的 category: ### 公众号(CareerEngine 来源) - + ### 公众号(二十次幂来源) - + ### 公众号(Telegram 频道来源) - + | 搜索查询类型 | 将使用的搜索关键字 | 适用于 | | :----: | :-------: | :----------------------: | @@ -3992,6 +3998,10 @@ column 为 third 时可选的 category: +### 公众号(微小领来源) + +见 [#微小领](#wei-xiao-ling) + ### 公众号栏目 (非推送 & 历史消息) diff --git a/lib/utils/wechat-mp.js b/lib/utils/wechat-mp.js index c431cdf374..8afa9403e0 100644 --- a/lib/utils/wechat-mp.js +++ b/lib/utils/wechat-mp.js @@ -222,7 +222,7 @@ const fetchArticle = (ctx, url, bypassHostCheck = false) => { let mpName = $('.profile_nickname').first().text(); mpName = mpName && mpName.trim(); - return { title, author, description, summary, pubDate, mpName, link: url }; + return { title, author, description, summary, pubDate, mpName, link: response.url }; }); }; diff --git a/lib/v2/wxkol/maintainer.js b/lib/v2/wxkol/maintainer.js new file mode 100644 index 0000000000..ee6e5d6970 --- /dev/null +++ b/lib/v2/wxkol/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/show/:id': ['TonyRL'], +}; diff --git a/lib/v2/wxkol/radar.js b/lib/v2/wxkol/radar.js new file mode 100644 index 0000000000..bd23a82669 --- /dev/null +++ b/lib/v2/wxkol/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'wxkol.com': { + _name: '微小领', + '.': [ + { + title: '微信公众号', + docs: 'https://docs.rsshub.app/new-media.html#wei-xiao-ling', + source: ['/show/:id'], + target: (params) => `/wxkol/show/${params.id.replace('.html', '')}`, + }, + ], + }, +}; diff --git a/lib/v2/wxkol/router.js b/lib/v2/wxkol/router.js new file mode 100644 index 0000000000..d731515347 --- /dev/null +++ b/lib/v2/wxkol/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/show/:id', require('./show')); +}; diff --git a/lib/v2/wxkol/show.js b/lib/v2/wxkol/show.js new file mode 100644 index 0000000000..ee1554a4a1 --- /dev/null +++ b/lib/v2/wxkol/show.js @@ -0,0 +1,80 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { fetchArticle } = require('@/utils/wechat-mp'); +const config = require('@/config').value; +const asyncPool = require('tiny-async-pool'); + +module.exports = async (ctx) => { + const baseUrl = 'https://www.wxkol.com'; + const { id } = ctx.params; + const url = `${baseUrl}/show/${id}.html`; + + const asyncPoolAll = async (...args) => { + const results = []; + for await (const result of asyncPool(...args)) { + results.push(result); + } + return results; + }; + + const feedData = await ctx.cache.tryGet( + url, + async () => { + const { data: response } = await got(url); + const $ = cheerio.load(response); + + const list = $('.artlist li') + .toArray() + .map((item) => { + item = $(item); + const a = item.find('.title a'); + return { + title: a.attr('title'), + link: `${baseUrl}${a.attr('href')}`, + }; + }); + + return { + feedTitle: $('head title').text(), + feedDescription: $('head description').text(), + feedImage: $('.main .logo .avatar') + .attr('style') + .match(/url\('(.+)'\)/)[1], + feedItem: list, + }; + }, + config.cache.routeExpire, + false + ); + + const urlList = await asyncPoolAll(2, feedData.feedItem, (item) => + ctx.cache.tryGet(item.link, async () => { + const { data: response } = await got(item.link); + const $ = cheerio.load(response); + item.link = `${baseUrl}${$('.source a').attr('href')}`; + return item; + }) + ); + + const items = await asyncPoolAll(4, urlList, async (item) => { + const { title, author, description, summary, pubDate, mpName, link: itemLink } = await fetchArticle(ctx, item.link, true); + + item.title = title; + item.author = author; + item.description = description; + item.summary = summary; + item.pubDate = pubDate; + item.author = mpName; + item.link = itemLink; + + return item; + }); + + ctx.state.data = { + title: feedData.feedTitle, + description: feedData.feedDescription, + link: url, + image: feedData.feedImage, + item: items, + }; +};