rsshub 1.0.0-master.fe4f650 → 1.0.0-master.fe560d2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/config.js +1 -1
- package/lib/middleware/parameter.js +3 -3
- package/lib/radar-rules.js +0 -46
- package/lib/router.js +28 -28
- package/lib/routes/v2ex/post.js +3 -0
- package/lib/utils/puppeteer-utils.js +63 -0
- package/lib/utils/puppeteer.js +13 -8
- package/lib/utils/request-wrapper.js +38 -100
- package/lib/utils/unify-proxy.js +116 -0
- package/lib/utils/wechat-mp.js +2 -0
- package/lib/v2/18comic/utils.js +2 -2
- package/lib/v2/36kr/index.js +29 -24
- package/lib/v2/agora0/maintainer.js +1 -0
- package/lib/v2/agora0/pen0.js +43 -0
- package/lib/v2/agora0/radar.js +12 -1
- package/lib/v2/agora0/router.js +1 -0
- package/lib/v2/aiea/index.js +39 -0
- package/lib/v2/aiea/maintainer.js +3 -0
- package/lib/v2/aiea/radar.js +13 -0
- package/lib/v2/aiea/router.js +3 -0
- package/lib/v2/baidu/radar.js +6 -6
- package/lib/v2/bangumi/online/online.js +4 -2
- package/lib/v2/bangumi/tv/group/reply.js +13 -1
- package/lib/v2/bangumi/tv/group/topic.js +22 -9
- package/lib/v2/bilibili/cache.js +34 -1
- package/lib/v2/bilibili/userCollection.js +1 -2
- package/lib/v2/bilibili/utils.js +10 -0
- package/lib/v2/bilibili/video-all.js +5 -2
- package/lib/v2/bilibili/video.js +3 -1
- package/lib/v2/bytes/bytes.js +25 -0
- package/lib/v2/bytes/maintainer.js +4 -0
- package/lib/v2/bytes/radar.js +13 -0
- package/lib/v2/bytes/router.js +3 -0
- package/lib/v2/caijing/maintainer.js +3 -0
- package/lib/v2/caijing/radar.js +13 -0
- package/lib/v2/caijing/roll.js +46 -0
- package/lib/v2/caijing/router.js +3 -0
- package/lib/v2/cdzjryb/maintainer.js +3 -0
- package/lib/v2/cdzjryb/projectList.js +49 -0
- package/lib/v2/cdzjryb/radar.js +13 -0
- package/lib/v2/cdzjryb/router.js +3 -0
- package/lib/v2/cdzjryb/templates/projectList.art +23 -0
- package/lib/v2/chsi/kydt.js +51 -0
- package/lib/v2/chsi/maintainer.js +3 -0
- package/lib/v2/chsi/radar.js +13 -0
- package/lib/v2/chsi/router.js +3 -0
- package/lib/v2/cnbeta/radar.js +6 -6
- package/lib/v2/cnbeta/router.js +1 -1
- package/lib/v2/cnbeta/type.js +6 -12
- package/lib/v2/cnbeta/utils.js +5 -8
- package/lib/v2/cngal/entry.js +25 -0
- package/lib/v2/cngal/maintainer.js +4 -0
- package/lib/v2/cngal/radar.js +19 -0
- package/lib/v2/cngal/router.js +4 -0
- package/lib/v2/cngal/templates/entry-description.art +4 -0
- package/lib/v2/cngal/templates/weekly-description.art +4 -0
- package/lib/v2/cngal/weekly.js +20 -0
- package/lib/v2/cnki/author.js +45 -0
- package/lib/v2/cnki/journals.js +2 -23
- package/lib/v2/cnki/maintainer.js +1 -0
- package/lib/v2/cnki/radar.js +8 -0
- package/lib/v2/cnki/router.js +1 -0
- package/lib/v2/cnki/utils.js +26 -0
- package/lib/v2/codeforces/maintainer.js +1 -0
- package/lib/v2/codeforces/radar.js +8 -0
- package/lib/v2/codeforces/recent_actions.js +47 -0
- package/lib/v2/codeforces/router.js +1 -0
- package/lib/v2/curius/links.js +43 -0
- package/lib/v2/curius/maintainer.js +3 -0
- package/lib/v2/curius/radar.js +13 -0
- package/lib/v2/curius/router.js +3 -0
- package/lib/v2/curius/templates/description.art +16 -0
- package/lib/v2/douyin/hashtag.js +20 -19
- package/lib/v2/douyin/live.js +2 -21
- package/lib/v2/douyin/user.js +2 -17
- package/lib/v2/douyin/utils.js +85 -0
- package/lib/v2/{acm-ecnu → ecnu}/contest.js +1 -4
- package/lib/v2/ecnu/maintainer.js +4 -0
- package/lib/v2/ecnu/radar.js +30 -0
- package/lib/v2/ecnu/router.js +4 -0
- package/lib/v2/{acm-ecnu → ecnu}/templates/description.art +0 -0
- package/lib/v2/ecnu/yjs.js +37 -0
- package/lib/v2/ehentai/ehapi.js +23 -12
- package/lib/v2/foresightnews/index.js +8 -11
- package/lib/v2/foreverblog/feeds.js +36 -0
- package/lib/v2/foreverblog/maintainer.js +3 -0
- package/lib/v2/foreverblog/radar.js +13 -0
- package/lib/v2/foreverblog/router.js +3 -0
- package/lib/v2/freewechat/maintainer.js +3 -0
- package/lib/v2/freewechat/profile.js +61 -0
- package/lib/v2/freewechat/radar.js +13 -0
- package/lib/v2/freewechat/router.js +3 -0
- package/lib/v2/gcores/category.js +16 -6
- package/lib/v2/good/index.js +15 -14
- package/lib/v2/gov/customs/list.js +1 -1
- package/lib/v2/gov/dianbai/dianbai.js +18 -0
- package/lib/v2/gov/gaozhou/gaozhou.js +19 -0
- package/lib/v2/gov/general/general.js +250 -0
- package/lib/v2/gov/general/templates/zcjdpt.art +128 -0
- package/lib/v2/gov/gz/index.js +38 -0
- package/lib/v2/gov/huazhou/huazhou.js +19 -0
- package/lib/v2/gov/hunan/changsha/major-email.js +52 -0
- package/lib/v2/gov/maintainer.js +19 -2
- package/lib/v2/gov/maoming/maoming.js +417 -0
- package/lib/v2/gov/maonan/maonan.js +100 -0
- package/lib/v2/gov/mgs/mgs.js +19 -0
- package/lib/v2/gov/mmht/mmht.js +19 -0
- package/lib/v2/gov/nmpa/generic.js +1 -1
- package/lib/v2/gov/radar.js +197 -0
- package/lib/v2/gov/router.js +18 -2
- package/lib/v2/gov/sasac/generic.js +42 -0
- package/lib/v2/gov/sdb/sdb.js +19 -0
- package/lib/v2/gov/shanghai/yjj/index.js +3 -1
- package/lib/v2/gov/xinyi/xinyi.js +19 -0
- package/lib/v2/gov/zhengce/govall.js +55 -0
- package/lib/v2/gov/zhengce/wenjian.js +47 -0
- package/lib/v2/gov/zhengce/zhengceku.js +22 -0
- package/lib/v2/gov/zhengce/zuixin.js +39 -0
- package/lib/v2/guanhai/index.js +47 -0
- package/lib/v2/guanhai/maintainer.js +4 -0
- package/lib/v2/guanhai/radar.js +13 -0
- package/lib/v2/guanhai/router.js +3 -0
- package/lib/v2/hackernews/index.js +6 -0
- package/lib/v2/hellogithub/volume.js +15 -32
- package/lib/v2/{heu → hrbeu}/gx/card.js +5 -10
- package/lib/v2/{heu → hrbeu}/gx/list.js +12 -20
- package/lib/v2/hrbeu/job/bigemploy.js +25 -0
- package/lib/v2/{heu → hrbeu}/job/calendar.js +8 -16
- package/lib/v2/{heu → hrbeu}/job/list.js +11 -16
- package/lib/v2/{heu → hrbeu}/maintainer.js +2 -1
- package/lib/v2/{heu → hrbeu}/radar.js +18 -10
- package/lib/v2/{heu → hrbeu}/router.js +3 -2
- package/lib/v2/{heu → hrbeu}/uae/list.js +12 -17
- package/lib/v2/hrbeu/ugs/news.js +98 -0
- package/lib/v2/{heu → hrbeu}/yjsy/list.js +8 -16
- package/lib/v2/ieee-security/maintainer.js +3 -0
- package/lib/v2/ieee-security/radar.js +13 -0
- package/lib/v2/ieee-security/router.js +3 -0
- package/lib/v2/ieee-security/sp.js +36 -0
- package/lib/v2/javbus/index.js +8 -2
- package/lib/v2/javbus/templates/description.art +12 -1
- package/lib/v2/jike/user.js +1 -0
- package/lib/v2/lang/maintainer.js +3 -0
- package/lib/v2/lang/radar.js +13 -0
- package/lib/v2/lang/room.js +40 -0
- package/lib/v2/lang/router.js +3 -0
- package/lib/v2/lang/templates/room.art +1 -0
- package/lib/v2/liulinblog/utils.js +7 -4
- package/lib/v2/luogu/daily.js +1 -1
- package/lib/v2/mangadex/index.js +73 -0
- package/lib/v2/mangadex/maintainer.js +3 -0
- package/lib/v2/mangadex/radar.js +13 -0
- package/lib/v2/mangadex/router.js +3 -0
- package/lib/v2/mihoyo/ys/news.js +3 -2
- package/lib/v2/mirror/index.js +15 -8
- package/lib/v2/mrdx/daily.js +79 -0
- package/lib/v2/mrdx/maintainer.js +3 -0
- package/lib/v2/mrdx/radar.js +13 -0
- package/lib/v2/mrdx/router.js +3 -0
- package/lib/v2/mrdx/utils.js +17 -0
- package/lib/v2/mtime/news.js +1 -1
- package/lib/v2/nautil/maintainer.js +3 -0
- package/lib/v2/nautil/radar.js +13 -0
- package/lib/v2/nautil/router.js +3 -0
- package/lib/v2/nautil/templates/description.art +6 -0
- package/lib/v2/nautil/topics.js +57 -0
- package/lib/v2/ndss-symposium/maintainer.js +3 -0
- package/lib/v2/ndss-symposium/ndss.js +80 -0
- package/lib/v2/ndss-symposium/radar.js +13 -0
- package/lib/v2/ndss-symposium/router.js +3 -0
- package/lib/v2/nextapple/realtime.js +1 -1
- package/lib/v2/nintendo/direct.js +31 -0
- package/lib/v2/nintendo/eshop_cn.js +44 -0
- package/lib/v2/nintendo/eshop_hk.js +79 -0
- package/lib/v2/nintendo/eshop_jp.js +34 -0
- package/lib/v2/nintendo/eshop_us.js +32 -0
- package/lib/v2/nintendo/maintainer.js +7 -0
- package/lib/v2/nintendo/news.js +23 -0
- package/lib/v2/nintendo/news_china.js +35 -0
- package/lib/v2/nintendo/radar.js +70 -0
- package/lib/v2/nintendo/router.js +10 -0
- package/lib/{routes → v2}/nintendo/system-update.js +2 -2
- package/lib/v2/nintendo/templates/direct.art +6 -0
- package/lib/v2/nintendo/templates/eshop_cn.art +21 -0
- package/lib/v2/nintendo/templates/eshop_hk.art +61 -0
- package/lib/v2/nintendo/templates/eshop_jp.art +3 -0
- package/lib/v2/nintendo/templates/eshop_us.art +24 -0
- package/lib/{routes → v2}/nintendo/utils.js +34 -50
- package/lib/v2/njxzc/home.js +13 -9
- package/lib/v2/nmtv/column.js +53 -0
- package/lib/v2/nmtv/maintainer.js +3 -0
- package/lib/v2/nmtv/radar.js +13 -0
- package/lib/v2/nmtv/router.js +3 -0
- package/lib/v2/nmtv/templates/description.art +9 -0
- package/lib/v2/nua/lib.js +39 -0
- package/lib/v2/nua/maintainer.js +1 -0
- package/lib/v2/nua/radar.js +8 -0
- package/lib/v2/nua/router.js +1 -0
- package/lib/v2/nua/utils.js +7 -12
- package/lib/v2/nuaa/utils/pypasswaf.js +3 -2
- package/lib/v2/nyaa/main.js +16 -23
- package/lib/v2/nyaa/maintainer.js +7 -4
- package/lib/v2/nyaa/radar.js +27 -29
- package/lib/v2/nyaa/router.js +4 -2
- package/lib/v2/odaily/post.js +15 -20
- package/lib/v2/odaily/utils.js +1 -1
- package/lib/v2/paradigm/maintainer.js +3 -0
- package/lib/v2/paradigm/radar.js +13 -0
- package/lib/v2/paradigm/router.js +3 -0
- package/lib/v2/paradigm/writing.js +44 -0
- package/lib/v2/picuki/maintainer.js +1 -1
- package/lib/v2/picuki/profile.js +10 -8
- package/lib/v2/picuki/utils.js +21 -0
- package/lib/v2/pixiv/api/getRanking.js +1 -1
- package/lib/v2/pixiv/ranking.js +3 -0
- package/lib/v2/producthunt/templates/descImg.art +2 -2
- package/lib/v2/qlu/maintainer.js +3 -0
- package/lib/v2/qlu/notice.js +54 -0
- package/lib/v2/qlu/radar.js +13 -0
- package/lib/v2/qlu/router.js +3 -0
- package/lib/v2/reactnewsletter/maintainer.js +4 -0
- package/lib/v2/reactnewsletter/radar.js +13 -0
- package/lib/v2/reactnewsletter/reactnewsletter.js +25 -0
- package/lib/v2/reactnewsletter/router.js +3 -0
- package/lib/v2/researchgate/maintainer.js +3 -0
- package/lib/v2/researchgate/publications.js +70 -0
- package/lib/v2/researchgate/radar.js +13 -0
- package/lib/v2/researchgate/router.js +3 -0
- package/lib/v2/saraba1st/digest.js +79 -0
- package/lib/v2/saraba1st/maintainer.js +1 -0
- package/lib/v2/saraba1st/radar.js +12 -3
- package/lib/v2/saraba1st/router.js +1 -0
- package/lib/v2/saraba1st/templates/digest.art +5 -0
- package/lib/v2/sctv/maintainer.js +1 -1
- package/lib/v2/sctv/programme.js +39 -17
- package/lib/v2/sctv/router.js +1 -1
- package/lib/v2/shmtu/jwc.js +57 -0
- package/lib/v2/shmtu/maintainer.js +5 -0
- package/lib/v2/shmtu/portal.js +81 -0
- package/lib/v2/shmtu/radar.js +29 -0
- package/lib/v2/shmtu/router.js +5 -0
- package/lib/v2/shmtu/templates/portal.art +30 -0
- package/lib/v2/shmtu/www.js +58 -0
- package/lib/v2/sigsac/ccs.js +57 -0
- package/lib/v2/sigsac/maintainer.js +3 -0
- package/lib/v2/sigsac/radar.js +13 -0
- package/lib/v2/sigsac/router.js +3 -0
- package/lib/v2/simpleinfo/index.js +50 -0
- package/lib/v2/simpleinfo/maintainer.js +3 -0
- package/lib/v2/simpleinfo/radar.js +19 -0
- package/lib/v2/simpleinfo/router.js +3 -0
- package/lib/v2/simpleinfo/templates/description.art +6 -0
- package/lib/v2/sse/maintainer.js +1 -1
- package/lib/v2/telegram/channel.js +54 -38
- package/lib/v2/tencent/maintainer.js +2 -0
- package/lib/v2/tencent/news/coronavirus/data.js +71 -0
- package/lib/v2/tencent/news/coronavirus/total.js +34 -0
- package/lib/v2/tencent/news/coronavirus/utils.js +17 -0
- package/lib/v2/tencent/radar.js +8 -0
- package/lib/v2/tencent/router.js +2 -0
- package/lib/v2/tencent/templates/coronavirus/chinaTotal.art +6 -0
- package/lib/v2/tencent/templates/coronavirus/data.art +4 -0
- package/lib/v2/test/index.js +8 -0
- package/lib/v2/theverge/index.js +9 -1
- package/lib/v2/theverge/maintainer.js +1 -1
- package/lib/v2/theverge/radar.js +2 -2
- package/lib/v2/theverge/router.js +1 -1
- package/lib/v2/tingshuitz/changsha.js +43 -0
- package/lib/v2/tingshuitz/maintainer.js +1 -0
- package/lib/v2/tingshuitz/radar.js +10 -0
- package/lib/v2/tingshuitz/router.js +1 -0
- package/lib/v2/twitter/web-api/twitter-api.js +19 -15
- package/lib/v2/twreporter/category.js +17 -8
- package/lib/v2/uber/blog.js +59 -0
- package/lib/v2/uber/maintainer.js +3 -0
- package/lib/v2/uber/radar.js +13 -0
- package/lib/v2/uber/router.js +3 -0
- package/lib/v2/usenix/maintainer.js +3 -0
- package/lib/v2/usenix/radar.js +13 -0
- package/lib/v2/usenix/router.js +3 -0
- package/lib/v2/usenix/usenix.js +63 -0
- package/lib/v2/usepanda/index.js +26 -0
- package/lib/v2/usepanda/maintainer.js +3 -0
- package/lib/v2/usepanda/radar.js +11 -0
- package/lib/v2/usepanda/router.js +3 -0
- package/lib/v2/uw/gix/news.js +67 -0
- package/lib/v2/uw/maintainer.js +3 -0
- package/lib/v2/uw/radar.js +13 -0
- package/lib/v2/uw/router.js +3 -0
- package/lib/v2/verse/articles.js +42 -0
- package/lib/v2/verse/maintainer.js +3 -0
- package/lib/v2/verse/radar.js +13 -0
- package/lib/v2/verse/router.js +3 -0
- package/lib/{routes → v2}/weibo/keyword.js +2 -2
- package/lib/v2/weibo/maintainer.js +8 -0
- package/lib/v2/weibo/oasis/user.js +20 -0
- package/lib/v2/weibo/radar.js +48 -0
- package/lib/v2/weibo/router.js +8 -0
- package/lib/{routes → v2}/weibo/search/hot.js +2 -0
- package/lib/{routes → v2}/weibo/super_index.js +2 -2
- package/lib/{routes → v2}/weibo/timeline.js +2 -2
- package/lib/{routes → v2}/weibo/user.js +2 -2
- package/lib/{routes → v2}/weibo/utils.js +49 -14
- package/lib/v2/ymgal/article.js +61 -0
- package/lib/v2/ymgal/game.js +41 -0
- package/lib/v2/ymgal/maintainer.js +4 -0
- package/lib/v2/ymgal/radar.js +31 -0
- package/lib/v2/ymgal/router.js +4 -0
- package/lib/v2/ymgal/templates/description.art +7 -0
- package/lib/v2/zhihu/pin/utils.js +49 -41
- package/package.json +26 -27
- package/lib/routes/blogs/foreverblog.js +0 -33
- package/lib/routes/gov/zhengce/govall.js +0 -59
- package/lib/routes/gov/zhengce/wenjian.js +0 -53
- package/lib/routes/gov/zhengce/zuixin.js +0 -42
- package/lib/routes/langlive/room.js +0 -33
- package/lib/routes/nautilus/topics.js +0 -45
- package/lib/routes/nintendo/direct.js +0 -34
- package/lib/routes/nintendo/eshop_cn.js +0 -51
- package/lib/routes/nintendo/eshop_hk.js +0 -26
- package/lib/routes/nintendo/eshop_jp.js +0 -20
- package/lib/routes/nintendo/eshop_us.js +0 -36
- package/lib/routes/nintendo/news.js +0 -25
- package/lib/routes/nintendo/news_china.js +0 -41
- package/lib/routes/researchgate/publications.js +0 -60
- package/lib/routes/universities/ecnuyjs/ecnuyjs.js +0 -23
- package/lib/routes/universities/shmtu/jwc.js +0 -75
- package/lib/routes/universities/shmtu/www.js +0 -61
- package/lib/routes/weibo/oasis/user.js +0 -17
- package/lib/v2/acm-ecnu/maintainer.js +0 -3
- package/lib/v2/acm-ecnu/radar.js +0 -19
- package/lib/v2/acm-ecnu/router.js +0 -3
- package/lib/v2/cnbeta/index.js +0 -16
- package/lib/v2/heu/job/bigemploy.js +0 -42
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
> 🍰 Everything is RSSible
|
|
7
7
|
|
|
8
8
|
[](https://t.me/rsshub)
|
|
9
|
-
[](https://www.npmjs.com/package/rsshub)
|
|
10
|
+
[](https://hub.docker.com/r/diygod/rsshub)
|
|
11
|
+
[](https://github.com/DIYgod/RSSHub/actions/workflows/test.yml?query=event%3Apush+branch%3Amaster)
|
|
12
12
|
[](https://app.codecov.io/gh/DIYgod/RSSHub/branch/master)
|
|
13
13
|
[](https://docs.runforesight.com/)
|
|
14
14
|
|
package/lib/config.js
CHANGED
|
@@ -225,7 +225,7 @@ const calculateValue = () => {
|
|
|
225
225
|
bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false',
|
|
226
226
|
bypassCdnHostname: envs.PIXIV_BYPASS_HOSTNAME || 'public-api.secure.pixiv.net',
|
|
227
227
|
bypassCdnDoh: envs.PIXIV_BYPASS_DOH || 'https://1.1.1.1/dns-query',
|
|
228
|
-
imgProxy: envs.PIXIV_IMG_PROXY || 'https://i.pixiv.
|
|
228
|
+
imgProxy: envs.PIXIV_IMG_PROXY || 'https://i.pixiv.re',
|
|
229
229
|
},
|
|
230
230
|
pkubbs: {
|
|
231
231
|
cookie: envs.PKUBBS_COOKIE,
|
|
@@ -181,7 +181,7 @@ module.exports = async (ctx, next) => {
|
|
|
181
181
|
const title = item.title || '';
|
|
182
182
|
const description = item.description || title;
|
|
183
183
|
const author = item.author || '';
|
|
184
|
-
const category = item.category
|
|
184
|
+
const category = item.category ? (Array.isArray(item.category) ? item.category : [item.category]) : [];
|
|
185
185
|
const isFilter =
|
|
186
186
|
title.match(makeRegex(ctx.query.filter)) || description.match(makeRegex(ctx.query.filter)) || author.match(makeRegex(ctx.query.filter)) || category.some((c) => c.match(makeRegex(ctx.query.filter)));
|
|
187
187
|
return isFilter;
|
|
@@ -194,7 +194,7 @@ module.exports = async (ctx, next) => {
|
|
|
194
194
|
const title = item.title || '';
|
|
195
195
|
const description = item.description || title;
|
|
196
196
|
const author = item.author || '';
|
|
197
|
-
const category = item.category
|
|
197
|
+
const category = item.category ? (Array.isArray(item.category) ? item.category : [item.category]) : [];
|
|
198
198
|
let isFilter = true;
|
|
199
199
|
ctx.query.filter_title && (isFilter = title.match(makeRegex(ctx.query.filter_title)));
|
|
200
200
|
ctx.query.filter_description && (isFilter = isFilter && description.match(makeRegex(ctx.query.filter_description)));
|
|
@@ -213,7 +213,7 @@ module.exports = async (ctx, next) => {
|
|
|
213
213
|
const title = item.title;
|
|
214
214
|
const description = item.description || title;
|
|
215
215
|
const author = item.author || '';
|
|
216
|
-
const category = item.category
|
|
216
|
+
const category = item.category ? (Array.isArray(item.category) ? item.category : [item.category]) : [];
|
|
217
217
|
let isFilter = true;
|
|
218
218
|
ctx.query.filterout_title && (isFilter = !title.match(makeRegex(ctx.query.filterout_title)));
|
|
219
219
|
ctx.query.filterout_description && (isFilter = isFilter && !description.match(makeRegex(ctx.query.filterout_description)));
|
package/lib/radar-rules.js
CHANGED
|
@@ -1,50 +1,4 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
'weibo.com': {
|
|
3
|
-
_name: '微博',
|
|
4
|
-
'.': [
|
|
5
|
-
{
|
|
6
|
-
title: '博主',
|
|
7
|
-
docs: 'https://docs.rsshub.app/social-media.html#wei-bo',
|
|
8
|
-
source: ['/u/:id', '/:id'],
|
|
9
|
-
target: (params, url, document) => {
|
|
10
|
-
let uid = document?.documentElement.innerHTML.match(/\$CONFIG\['oid']='(\d+)'/)?.[1];
|
|
11
|
-
if (!uid && !isNaN(params.id)) {
|
|
12
|
-
uid = params.id;
|
|
13
|
-
}
|
|
14
|
-
return uid ? `/weibo/user/${uid}` : '';
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
title: '关键词',
|
|
19
|
-
docs: 'https://docs.rsshub.app/social-media.html#wei-bo',
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
title: '超话',
|
|
23
|
-
docs: 'https://docs.rsshub.app/social-media.html#wei-bo',
|
|
24
|
-
source: '/p/:id/super_index',
|
|
25
|
-
target: '/weibo/super_index/:id',
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
s: [
|
|
29
|
-
{
|
|
30
|
-
title: '热搜榜',
|
|
31
|
-
docs: 'https://docs.rsshub.app/social-media.html#wei-bo',
|
|
32
|
-
source: '/top/summary',
|
|
33
|
-
target: '/weibo/search/hot',
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
'weibo.cn': {
|
|
38
|
-
_name: '微博',
|
|
39
|
-
m: [
|
|
40
|
-
{
|
|
41
|
-
title: '博主',
|
|
42
|
-
docs: 'https://docs.rsshub.app/social-media.html#wei-bo',
|
|
43
|
-
source: ['/u/:uid', '/profile/:uid'],
|
|
44
|
-
target: '/weibo/user/:uid',
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
2
|
'ximalaya.com': {
|
|
49
3
|
_name: '喜马拉雅',
|
|
50
4
|
'.': [
|
package/lib/router.js
CHANGED
|
@@ -47,12 +47,12 @@ router.get('/benedictevans', lazyloadRouteHandler('./routes/benedictevans/recent
|
|
|
47
47
|
// router.get('/twreporter/photography', lazyloadRouteHandler('./routes/twreporter/photography'));
|
|
48
48
|
// router.get('/twreporter/category/:cid', lazyloadRouteHandler('./routes/twreporter/category'));
|
|
49
49
|
|
|
50
|
-
// 微博
|
|
51
|
-
router.get('/weibo/user/:uid/:routeParams?', lazyloadRouteHandler('./routes/weibo/user'));
|
|
52
|
-
router.get('/weibo/keyword/:keyword/:routeParams?', lazyloadRouteHandler('./routes/weibo/keyword'));
|
|
53
|
-
router.get('/weibo/search/hot', lazyloadRouteHandler('./routes/weibo/search/hot'));
|
|
54
|
-
router.get('/weibo/super_index/:id/:type?/:routeParams?', lazyloadRouteHandler('./routes/weibo/super_index'));
|
|
55
|
-
router.get('/weibo/oasis/user/:userid', lazyloadRouteHandler('./routes/weibo/oasis/user'));
|
|
50
|
+
// 微博 migrated to v2
|
|
51
|
+
// router.get('/weibo/user/:uid/:routeParams?', lazyloadRouteHandler('./routes/weibo/user'));
|
|
52
|
+
// router.get('/weibo/keyword/:keyword/:routeParams?', lazyloadRouteHandler('./routes/weibo/keyword'));
|
|
53
|
+
// router.get('/weibo/search/hot', lazyloadRouteHandler('./routes/weibo/search/hot'));
|
|
54
|
+
// router.get('/weibo/super_index/:id/:type?/:routeParams?', lazyloadRouteHandler('./routes/weibo/super_index'));
|
|
55
|
+
// router.get('/weibo/oasis/user/:userid', lazyloadRouteHandler('./routes/weibo/oasis/user'));
|
|
56
56
|
|
|
57
57
|
// 贴吧 migrated to v2
|
|
58
58
|
// router.get('/tieba/forum/:kw', lazyloadRouteHandler('./routes/tieba/forum'));
|
|
@@ -194,8 +194,8 @@ router.get('/dribbble/keyword/:keyword', lazyloadRouteHandler('./routes/dribbble
|
|
|
194
194
|
router.get('/huya/live/:id', lazyloadRouteHandler('./routes/huya/live'));
|
|
195
195
|
|
|
196
196
|
// 浪Play(原kingkong)直播
|
|
197
|
-
router.get('/kingkong/room/:id', lazyloadRouteHandler('./routes/langlive/room'));
|
|
198
|
-
router.get('/langlive/room/:id', lazyloadRouteHandler('./routes/langlive/room'));
|
|
197
|
+
// router.get('/kingkong/room/:id', lazyloadRouteHandler('./routes/langlive/room'));
|
|
198
|
+
// router.get('/langlive/room/:id', lazyloadRouteHandler('./routes/langlive/room'));
|
|
199
199
|
|
|
200
200
|
// SHOWROOM直播
|
|
201
201
|
router.get('/showroom/room/:id', lazyloadRouteHandler('./routes/showroom/room'));
|
|
@@ -569,9 +569,9 @@ router.get('/thu/:type', lazyloadRouteHandler('./routes/universities/thu/index')
|
|
|
569
569
|
// router.get('/pku/bbs/hot', lazyloadRouteHandler('./routes/universities/pku/bbs/hot'));
|
|
570
570
|
// router.get('/pku/scc/recruit/:type?', lazyloadRouteHandler('./routes/universities/pku/scc/recruit'));
|
|
571
571
|
|
|
572
|
-
// 上海海事大学
|
|
573
|
-
router.get('/shmtu/www/:type', lazyloadRouteHandler('./routes/universities/shmtu/www'));
|
|
574
|
-
router.get('/shmtu/jwc/:type', lazyloadRouteHandler('./routes/universities/shmtu/jwc'));
|
|
572
|
+
// 上海海事大学 migrated to v2
|
|
573
|
+
// router.get('/shmtu/www/:type', lazyloadRouteHandler('./routes/universities/shmtu/www'));
|
|
574
|
+
// router.get('/shmtu/jwc/:type', lazyloadRouteHandler('./routes/universities/shmtu/jwc'));
|
|
575
575
|
|
|
576
576
|
// 上海海洋大学
|
|
577
577
|
router.get('/shou/www/:type', lazyloadRouteHandler('./routes/universities/shou/www'));
|
|
@@ -1065,7 +1065,7 @@ router.get('/miniflux/:feeds/:parameters?', lazyloadRouteHandler('./routes/minif
|
|
|
1065
1065
|
// router.get('/nga/post/:tid', lazyloadRouteHandler('./routes/nga/post'));
|
|
1066
1066
|
|
|
1067
1067
|
// Nautilus
|
|
1068
|
-
router.get('/nautilus/topic/:tid', lazyloadRouteHandler('./routes/nautilus/topics'));
|
|
1068
|
+
// router.get('/nautilus/topic/:tid', lazyloadRouteHandler('./routes/nautilus/topics'));
|
|
1069
1069
|
|
|
1070
1070
|
// JavBus migrated to v2
|
|
1071
1071
|
// router.get('/javbus/home', lazyloadRouteHandler('./routes/javbus/home'));
|
|
@@ -1174,9 +1174,9 @@ router.get('/cyzone/author/:id', lazyloadRouteHandler('./routes/cyzone/author'))
|
|
|
1174
1174
|
router.get('/cyzone/label/:name', lazyloadRouteHandler('./routes/cyzone/label'));
|
|
1175
1175
|
|
|
1176
1176
|
// 政府
|
|
1177
|
-
router.get('/gov/zhengce/zuixin', lazyloadRouteHandler('./routes/gov/zhengce/zuixin'));
|
|
1178
|
-
router.get('/gov/zhengce/wenjian/:pcodeJiguan?', lazyloadRouteHandler('./routes/gov/zhengce/wenjian'));
|
|
1179
|
-
router.get('/gov/zhengce/govall/:advance?', lazyloadRouteHandler('./routes/gov/zhengce/govall'));
|
|
1177
|
+
// router.get('/gov/zhengce/zuixin', lazyloadRouteHandler('./routes/gov/zhengce/zuixin'));
|
|
1178
|
+
// router.get('/gov/zhengce/wenjian/:pcodeJiguan?', lazyloadRouteHandler('./routes/gov/zhengce/wenjian'));
|
|
1179
|
+
// router.get('/gov/zhengce/govall/:advance?', lazyloadRouteHandler('./routes/gov/zhengce/govall'));
|
|
1180
1180
|
router.get('/gov/province/:name/:category', lazyloadRouteHandler('./routes/gov/province'));
|
|
1181
1181
|
router.get('/gov/city/:name/:category', lazyloadRouteHandler('./routes/gov/city'));
|
|
1182
1182
|
router.get('/gov/statecouncil/briefing', lazyloadRouteHandler('./routes/gov/statecouncil/briefing'));
|
|
@@ -1533,15 +1533,15 @@ router.get('/ps/:lang?/product/:gridName', lazyloadRouteHandler('./routes/ps/pro
|
|
|
1533
1533
|
// Quanta Magazine
|
|
1534
1534
|
router.get('/quantamagazine/archive', lazyloadRouteHandler('./routes/quantamagazine/archive'));
|
|
1535
1535
|
|
|
1536
|
-
// Nintendo
|
|
1537
|
-
router.get('/nintendo/eshop/jp', lazyloadRouteHandler('./routes/nintendo/eshop_jp'));
|
|
1538
|
-
router.get('/nintendo/eshop/hk', lazyloadRouteHandler('./routes/nintendo/eshop_hk'));
|
|
1539
|
-
router.get('/nintendo/eshop/us', lazyloadRouteHandler('./routes/nintendo/eshop_us'));
|
|
1540
|
-
router.get('/nintendo/eshop/cn', lazyloadRouteHandler('./routes/nintendo/eshop_cn'));
|
|
1541
|
-
router.get('/nintendo/news', lazyloadRouteHandler('./routes/nintendo/news'));
|
|
1542
|
-
router.get('/nintendo/news/china', lazyloadRouteHandler('./routes/nintendo/news_china'));
|
|
1543
|
-
router.get('/nintendo/direct', lazyloadRouteHandler('./routes/nintendo/direct'));
|
|
1544
|
-
router.get('/nintendo/system-update', lazyloadRouteHandler('./routes/nintendo/system-update'));
|
|
1536
|
+
// Nintendo migrated to v2
|
|
1537
|
+
// router.get('/nintendo/eshop/jp', lazyloadRouteHandler('./routes/nintendo/eshop_jp'));
|
|
1538
|
+
// router.get('/nintendo/eshop/hk', lazyloadRouteHandler('./routes/nintendo/eshop_hk'));
|
|
1539
|
+
// router.get('/nintendo/eshop/us', lazyloadRouteHandler('./routes/nintendo/eshop_us'));
|
|
1540
|
+
// router.get('/nintendo/eshop/cn', lazyloadRouteHandler('./routes/nintendo/eshop_cn'));
|
|
1541
|
+
// router.get('/nintendo/news', lazyloadRouteHandler('./routes/nintendo/news'));
|
|
1542
|
+
// router.get('/nintendo/news/china', lazyloadRouteHandler('./routes/nintendo/news_china'));
|
|
1543
|
+
// router.get('/nintendo/direct', lazyloadRouteHandler('./routes/nintendo/direct'));
|
|
1544
|
+
// router.get('/nintendo/system-update', lazyloadRouteHandler('./routes/nintendo/system-update'));
|
|
1545
1545
|
|
|
1546
1546
|
// 世界卫生组织 migrated to v2
|
|
1547
1547
|
// router.get('/who/news-room/:category?/:language?', lazyloadRouteHandler('./routes/who/news-room'));
|
|
@@ -2086,7 +2086,7 @@ router.get('/haimaoba/:id?', lazyloadRouteHandler('./routes/haimaoba/comics'));
|
|
|
2086
2086
|
router.get('/pgyer/:app?', lazyloadRouteHandler('./routes/pgyer/app'));
|
|
2087
2087
|
|
|
2088
2088
|
// 微博个人时间线
|
|
2089
|
-
router.get('/weibo/timeline/:uid/:feature?/:routeParams?', lazyloadRouteHandler('./routes/weibo/timeline'));
|
|
2089
|
+
// router.get('/weibo/timeline/:uid/:feature?/:routeParams?', lazyloadRouteHandler('./routes/weibo/timeline'));
|
|
2090
2090
|
|
|
2091
2091
|
// TAPTAP migrated to v2
|
|
2092
2092
|
// router.get('/taptap/topic/:id/:label?', lazyloadRouteHandler('./routes/taptap/topic'));
|
|
@@ -2578,8 +2578,8 @@ router.get('/zkyyjs', lazyloadRouteHandler('./routes/universities/zkyyjs/zkyyjs'
|
|
|
2578
2578
|
// 中国海洋大学信电学院
|
|
2579
2579
|
router.get('/outele', lazyloadRouteHandler('./routes/universities/outele/outele'));
|
|
2580
2580
|
|
|
2581
|
-
// 华东师范大学研究生院
|
|
2582
|
-
router.get('/ecnuyjs', lazyloadRouteHandler('./routes/universities/ecnuyjs/ecnuyjs'));
|
|
2581
|
+
// 华东师范大学研究生院 migrated to v2
|
|
2582
|
+
// router.get('/ecnuyjs', lazyloadRouteHandler('./routes/universities/ecnuyjs/ecnuyjs'));
|
|
2583
2583
|
|
|
2584
2584
|
// 考研帮调剂信息
|
|
2585
2585
|
router.get('/kaoyan', lazyloadRouteHandler('./routes/kaoyan/kaoyan'));
|
|
@@ -4028,7 +4028,7 @@ router.get('/sbs/chinese/:category?/:id?/:dialect?/:language?', lazyloadRouteHan
|
|
|
4028
4028
|
// router.get('/asiantolick/:category?/:keyword?', lazyloadRouteHandler('./routes/asiantolick'));
|
|
4029
4029
|
|
|
4030
4030
|
// Research Gate
|
|
4031
|
-
router.get('/researchgate/publications/:id', lazyloadRouteHandler('./routes/researchgate/publications'));
|
|
4031
|
+
// router.get('/researchgate/publications/:id', lazyloadRouteHandler('./routes/researchgate/publications'));
|
|
4032
4032
|
|
|
4033
4033
|
// QuestMobile
|
|
4034
4034
|
router.get('/questmobile/report/:category?/:label?', lazyloadRouteHandler('./routes/questmobile/report'));
|
package/lib/routes/v2ex/post.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const got = require('@/utils/got');
|
|
2
2
|
const cheerio = require('cheerio');
|
|
3
|
+
const { parseDate } = require('@/utils/parse-date');
|
|
3
4
|
|
|
4
5
|
module.exports = async (ctx) => {
|
|
5
6
|
const postid = ctx.params.postid;
|
|
@@ -29,8 +30,10 @@ module.exports = async (ctx) => {
|
|
|
29
30
|
guid: post.attr('id'),
|
|
30
31
|
link: `${pageUrl}#${post.attr('id')}`,
|
|
31
32
|
author: post.find('.dark').first().text(),
|
|
33
|
+
pubDate: parseDate(post.find('.ago').attr('title')),
|
|
32
34
|
};
|
|
33
35
|
})
|
|
34
36
|
.reverse(),
|
|
37
|
+
allowEmpty: true,
|
|
35
38
|
};
|
|
36
39
|
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get Cookie-header-style cookie string from a puppeteer-style cookie array
|
|
3
|
+
*
|
|
4
|
+
* @param {import('puppeteer').Protocol.Network.CookieParam[]} cookies Puppeteer-style cookie array
|
|
5
|
+
* @param {RegExp | string} domainFilter Filter cookies by domain or RegExp
|
|
6
|
+
* @return {string} Cookie-header-style cookie string (e.g. "foobar; foo=bar; baz=qux")
|
|
7
|
+
*/
|
|
8
|
+
const parseCookieArray = (cookies, domainFilter = null) => {
|
|
9
|
+
if (typeof domainFilter === 'string') {
|
|
10
|
+
const dotDomain = '.' + domainFilter;
|
|
11
|
+
cookies = cookies.filter(({ domain }) => domain === domainFilter || domain.endsWith(dotDomain));
|
|
12
|
+
} else if (domainFilter && domainFilter.test !== undefined) {
|
|
13
|
+
cookies = cookies.filter(({ domain }) => domainFilter.test(domain));
|
|
14
|
+
}
|
|
15
|
+
// {name: '', value: 'foobar'} => 'foobar' // https://stackoverflow.com/questions/42531198/cookie-without-a-name
|
|
16
|
+
// {name: 'foo', value: 'bar'} => 'foo=bar'
|
|
17
|
+
return cookies.map(({ name, value }) => (name ? `${name}=${value}` : value)).join('; ');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Construct a puppeteer-style cookie array from a Cookie-header-style cookie string
|
|
22
|
+
*
|
|
23
|
+
* @param {string} cookieStr Cookie-header-style cookie string (e.g. "foobar; foo=bar; baz=qux")
|
|
24
|
+
* @param {string} domain Domain to set for each cookie
|
|
25
|
+
* @return {import('puppeteer').Protocol.Network.CookieParam[]} Puppeteer-style cookie array
|
|
26
|
+
*/
|
|
27
|
+
const constructCookieArray = (cookieStr, domain) =>
|
|
28
|
+
cookieStr.split('; ').map((item) => {
|
|
29
|
+
const [name, value] = item.split('=');
|
|
30
|
+
return value === undefined ? { name: '', value: name, domain } : { name, value, domain };
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Set cookies for a page
|
|
35
|
+
*
|
|
36
|
+
* @param {import('puppeteer').Page} page Puppeteer Page object
|
|
37
|
+
* @param {string} cookieStr Cookie-header-style cookie string (e.g. "foobar; foo=bar; baz=qux")
|
|
38
|
+
* @param {string} domain Domain to set for each cookie
|
|
39
|
+
* @return {Promise<void>}
|
|
40
|
+
*/
|
|
41
|
+
const setCookies = async (page, cookieStr, domain) => {
|
|
42
|
+
const cookies = constructCookieArray(cookieStr, domain);
|
|
43
|
+
await page.setCookie(...cookies);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get Cookie-header-style cookie string from a page
|
|
48
|
+
*
|
|
49
|
+
* @param {import('puppeteer').Page} page Puppeteer Page object
|
|
50
|
+
* @param {RegExp | string} domainFilter Filter cookies by domain or RegExp
|
|
51
|
+
* @return {Promise<string>} Cookie-header-style cookie string
|
|
52
|
+
*/
|
|
53
|
+
const getCookies = async (page, domainFilter = null) => {
|
|
54
|
+
const cookies = await page.cookies();
|
|
55
|
+
return parseCookieArray(cookies, domainFilter);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
module.exports = {
|
|
59
|
+
parseCookieArray,
|
|
60
|
+
constructCookieArray,
|
|
61
|
+
setCookies,
|
|
62
|
+
getCookies,
|
|
63
|
+
};
|
package/lib/utils/puppeteer.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const config = require('@/config').value;
|
|
2
|
+
const { proxyUri, proxyUrlHandler } = require('./unify-proxy');
|
|
2
3
|
let puppeteer = require('puppeteer');
|
|
3
4
|
const proxyChain = require('proxy-chain');
|
|
5
|
+
const logger = require('./logger');
|
|
4
6
|
|
|
5
7
|
const options = {
|
|
6
8
|
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-infobars', '--window-position=0,0', '--ignore-certificate-errors', '--ignore-certificate-errors-spki-list', `--user-agent=${config.ua}`],
|
|
@@ -8,13 +10,6 @@ const options = {
|
|
|
8
10
|
ignoreHTTPSErrors: true,
|
|
9
11
|
};
|
|
10
12
|
|
|
11
|
-
let proxyUri;
|
|
12
|
-
if (config.proxyUri && typeof config.proxyUri === 'string') {
|
|
13
|
-
proxyUri = config.proxyUri;
|
|
14
|
-
} else if (config.proxy && config.proxy.protocol && config.proxy.host && config.proxy.port) {
|
|
15
|
-
proxyUri = `${config.proxy.protocol}://${config.proxy.host}:${config.proxy.port}`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
13
|
/**
|
|
19
14
|
* @param {Object} extraOptions
|
|
20
15
|
* @param {boolean} extraOptions.stealth - Use puppeteer-extra-plugin-stealth
|
|
@@ -50,7 +45,17 @@ module.exports = async (extraOptions = {}) => {
|
|
|
50
45
|
}
|
|
51
46
|
let browser;
|
|
52
47
|
if (proxyUri) {
|
|
53
|
-
|
|
48
|
+
if (proxyUrlHandler.username || proxyUrlHandler.password) {
|
|
49
|
+
// only proxies with authentication need to be anonymized
|
|
50
|
+
if (proxyUrlHandler.protocol === 'http:') {
|
|
51
|
+
options.args.push(`--proxy-server=${await proxyChain.anonymizeProxy(proxyUri)}`);
|
|
52
|
+
} else {
|
|
53
|
+
logger.warn('SOCKS/HTTPS proxy with authentication is not supported by puppeteer, continue without proxy');
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
// Chromium cannot recognize socks5h and socks4a, so we need to trim their postfixes
|
|
57
|
+
options.args.push(`--proxy-server=${proxyUri.replace('socks5h://', 'socks5://').replace('socks4a://', 'socks4://')}`);
|
|
58
|
+
}
|
|
54
59
|
}
|
|
55
60
|
if (config.puppeteerWSEndpoint) {
|
|
56
61
|
browser = await puppeteer.connect({
|
|
@@ -1,127 +1,65 @@
|
|
|
1
1
|
const config = require('@/config').value;
|
|
2
|
+
const { proxyUri, proxyObj, proxyUrlHandler } = require('./unify-proxy');
|
|
2
3
|
const logger = require('./logger');
|
|
3
4
|
const http = require('http');
|
|
4
5
|
const https = require('https');
|
|
5
6
|
|
|
6
|
-
let tunnel;
|
|
7
|
-
let HttpsProxyAgent;
|
|
8
|
-
let SocksProxyAgent;
|
|
9
|
-
|
|
10
7
|
let agent = null;
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
proxy = new SocksProxyAgent(config.proxyUri);
|
|
19
|
-
} else {
|
|
20
|
-
throw 'Unknown proxy-uri format';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
agent = {
|
|
24
|
-
http: proxy,
|
|
25
|
-
https: proxy,
|
|
26
|
-
};
|
|
27
|
-
} else if (config.proxy && config.proxy.protocol && config.proxy.host && config.proxy.port) {
|
|
28
|
-
agent = {};
|
|
29
|
-
const proxyUrl = `${config.proxy.protocol}://${config.proxy.host}:${config.proxy.port}`;
|
|
30
|
-
|
|
31
|
-
switch (config.proxy.protocol) {
|
|
32
|
-
case 'socks':
|
|
33
|
-
SocksProxyAgent = SocksProxyAgent || require('socks-proxy-agent').SocksProxyAgent;
|
|
34
|
-
agent.http = new SocksProxyAgent(proxyUrl);
|
|
35
|
-
agent.https = new SocksProxyAgent(proxyUrl);
|
|
36
|
-
break;
|
|
37
|
-
case 'http':
|
|
38
|
-
tunnel = tunnel || require('tunnel');
|
|
39
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
|
|
40
|
-
agent.http = tunnel.httpOverHttp({
|
|
41
|
-
proxy: {
|
|
42
|
-
host: config.proxy.host,
|
|
43
|
-
port: parseInt(config.proxy.port),
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
agent.https = tunnel.httpsOverHttp({
|
|
47
|
-
proxy: {
|
|
48
|
-
host: config.proxy.host,
|
|
49
|
-
port: parseInt(config.proxy.port),
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
break;
|
|
53
|
-
case 'https':
|
|
54
|
-
tunnel = tunnel || require('tunnel');
|
|
55
|
-
agent.http = tunnel.httpOverHttps({
|
|
56
|
-
proxy: {
|
|
57
|
-
host: config.proxy.host,
|
|
58
|
-
port: parseInt(config.proxy.port),
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
agent.https = tunnel.httpsOverHttps({
|
|
62
|
-
proxy: {
|
|
63
|
-
host: config.proxy.host,
|
|
64
|
-
port: parseInt(config.proxy.port),
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
break;
|
|
8
|
+
if (proxyUri) {
|
|
9
|
+
if (proxyUri.startsWith('http')) {
|
|
10
|
+
const HttpsProxyAgent = require('https-proxy-agent');
|
|
11
|
+
agent = new HttpsProxyAgent(proxyUri);
|
|
12
|
+
} else if (proxyUri.startsWith('socks')) {
|
|
13
|
+
const SocksProxyAgent = require('socks-proxy-agent').SocksProxyAgent;
|
|
14
|
+
agent = new SocksProxyAgent(proxyUri);
|
|
68
15
|
}
|
|
69
16
|
}
|
|
70
17
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
agentResult = agent[(options.protocol || url.match(/(^https?:)/)[1]).slice(0, -1)];
|
|
77
|
-
} catch (error) {
|
|
78
|
-
agentResult = null;
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
if (new URL(url).host !== new URL(config.proxyUri).host) {
|
|
82
|
-
options.agent = agentResult;
|
|
83
|
-
}
|
|
84
|
-
} catch (error) {
|
|
85
|
-
options.agent = agentResult;
|
|
86
|
-
}
|
|
18
|
+
let proxyWrapper = () => false;
|
|
19
|
+
if (agent) {
|
|
20
|
+
const proxyRegex = new RegExp(proxyObj.url_regex);
|
|
21
|
+
const protocolMatch = (protocolLike) => protocolLike && protocolLike.toLowerCase().startsWith('http');
|
|
87
22
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
23
|
+
proxyWrapper = (url, options, urlHandler) => {
|
|
24
|
+
if (proxyRegex.test(url)) {
|
|
25
|
+
if ((protocolMatch(options.protocol) || protocolMatch(url)) && (!urlHandler || urlHandler.host !== proxyUrlHandler.host)) {
|
|
26
|
+
options.agent = agent;
|
|
27
|
+
if (proxyObj.auth) {
|
|
28
|
+
options.headers['Proxy-Authorization'] = `Basic ${proxyObj.auth}`;
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
91
31
|
}
|
|
92
|
-
options.headers['Proxy-Authorization'] = `Basic ${config.proxy.auth}`;
|
|
93
32
|
}
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const requestWrapper = (url, options) => {
|
|
38
|
+
let urlHandler;
|
|
39
|
+
try {
|
|
40
|
+
urlHandler = new URL(url);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
// ignore
|
|
97
43
|
}
|
|
44
|
+
options.headers = options.headers || {};
|
|
45
|
+
const headersLowerCaseKeys = Object.keys(options.headers).map((key) => key.toLowerCase());
|
|
46
|
+
|
|
47
|
+
proxyWrapper(url, options, urlHandler) ? logger.info(`Proxy for ${url}`) : logger.debug(`Requesting ${url}`);
|
|
98
48
|
|
|
99
49
|
// ua
|
|
100
|
-
|
|
101
|
-
for (const header in options.headers) {
|
|
102
|
-
if (header.toLowerCase() === 'user-agent') {
|
|
103
|
-
hasUA = true;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (!hasUA) {
|
|
107
|
-
if (!options.headers) {
|
|
108
|
-
options.headers = {};
|
|
109
|
-
}
|
|
50
|
+
if (!headersLowerCaseKeys.includes('user-agent')) {
|
|
110
51
|
options.headers['user-agent'] = config.ua;
|
|
111
52
|
}
|
|
112
53
|
|
|
113
|
-
|
|
114
|
-
const urlHandler = new URL(url);
|
|
54
|
+
if (urlHandler) {
|
|
115
55
|
// referer
|
|
116
|
-
if (!
|
|
56
|
+
if (!headersLowerCaseKeys.includes('referer')) {
|
|
117
57
|
options.headers.referer = urlHandler.origin;
|
|
118
58
|
}
|
|
119
59
|
// host
|
|
120
|
-
if (!
|
|
60
|
+
if (!headersLowerCaseKeys.includes('host')) {
|
|
121
61
|
options.headers.host = urlHandler.host;
|
|
122
62
|
}
|
|
123
|
-
} catch (e) {
|
|
124
|
-
// do nothing
|
|
125
63
|
}
|
|
126
64
|
};
|
|
127
65
|
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
const config = require('@/config').value;
|
|
2
|
+
const logger = require('./logger');
|
|
3
|
+
|
|
4
|
+
const defaultProtocol = 'http';
|
|
5
|
+
const possibleProtocol = ['http', 'https', 'socks', 'socks4', 'socks4a', 'socks5', 'socks5h'];
|
|
6
|
+
|
|
7
|
+
const unifyProxy = (proxyUri, proxyObj) => {
|
|
8
|
+
proxyObj = proxyObj || {};
|
|
9
|
+
const [oriProxyUri, oriProxyObj] = [proxyUri, proxyObj];
|
|
10
|
+
proxyObj = { ...proxyObj };
|
|
11
|
+
|
|
12
|
+
let proxyUrlHandler;
|
|
13
|
+
|
|
14
|
+
// PROXY_URI
|
|
15
|
+
if (proxyUri && typeof proxyUri === 'string') {
|
|
16
|
+
if (!proxyUri.includes('://')) {
|
|
17
|
+
logger.warn(`PROXY_URI contains no protocol, assuming ${defaultProtocol}`);
|
|
18
|
+
proxyUri = `${defaultProtocol}://${proxyUri}`;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
proxyUrlHandler = new URL(proxyUri);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
logger.error(`Parse PROXY_URI error: ${e.stack}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// PROXY_{PROTOCOL,HOST,PORT}
|
|
28
|
+
if (proxyObj.protocol || proxyObj.host || proxyObj.port) {
|
|
29
|
+
if (proxyUrlHandler) {
|
|
30
|
+
logger.warn('PROXY_URI is set, ignoring PROXY_{PROTOCOL,HOST,PORT}');
|
|
31
|
+
} else if (proxyObj.host) {
|
|
32
|
+
let tempProxyStr = proxyObj.host;
|
|
33
|
+
|
|
34
|
+
if (tempProxyStr.includes('://')) {
|
|
35
|
+
logger.warn('PROXY_HOST contains protocol, ignoring PROXY_PROTOCOL');
|
|
36
|
+
} else if (!proxyObj.protocol) {
|
|
37
|
+
logger.warn(`PROXY_PROTOCOL is not set, assuming '${defaultProtocol}'`);
|
|
38
|
+
tempProxyStr = `${defaultProtocol}://${tempProxyStr}`;
|
|
39
|
+
} else {
|
|
40
|
+
tempProxyStr = `${proxyObj.protocol}://${tempProxyStr}`;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
proxyUrlHandler = new URL(tempProxyStr);
|
|
44
|
+
if (proxyUrlHandler.port && proxyObj.port) {
|
|
45
|
+
logger.warn('PROXY_HOST contains port, ignoring PROXY_PORT');
|
|
46
|
+
} else if (proxyObj.port) {
|
|
47
|
+
if (!parseInt(proxyObj.port)) {
|
|
48
|
+
logger.warn(`PROXY_PORT is not a number, ignoring`);
|
|
49
|
+
} else {
|
|
50
|
+
proxyUrlHandler.port = proxyObj.port;
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
logger.warn('PROXY_PORT is not set, leaving proxy agent to determine');
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
logger.error(`Parse PROXY_HOST error: ${e.stack}`);
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
logger.warn('Either PROXY_{PROTOCOL,PORT} is set, but PROXY_HOST is missing, ignoring');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// PROXY_AUTH
|
|
64
|
+
if (proxyObj.auth && proxyUrlHandler) {
|
|
65
|
+
let promptProxyUri = false;
|
|
66
|
+
if (proxyUrlHandler.username || proxyUrlHandler.password) {
|
|
67
|
+
logger.warn('PROXY_URI contains username and/or password, ignoring PROXY_AUTH');
|
|
68
|
+
proxyObj.auth = undefined;
|
|
69
|
+
} else if (!['http:', 'https:'].includes(proxyUrlHandler.protocol)) {
|
|
70
|
+
logger.warn(`PROXY_AUTH is only supported by HTTP(S) proxies, but got ${proxyUrlHandler.protocol}, ignoring`);
|
|
71
|
+
proxyObj.auth = undefined;
|
|
72
|
+
promptProxyUri = true;
|
|
73
|
+
} else {
|
|
74
|
+
logger.info('PROXY_AUTH is set and will be used for requests from Node.js. However, requests from puppeteer will not use it');
|
|
75
|
+
promptProxyUri = true;
|
|
76
|
+
}
|
|
77
|
+
if (promptProxyUri) {
|
|
78
|
+
logger.info('To get rid of this, set PROXY_URI like protocol://username:password@host:port and clear PROXY_{AUTH,PROTOCOL,HOST,PORT}');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// is proxy enabled and valid?
|
|
83
|
+
let isProxyValid = false;
|
|
84
|
+
if (proxyUrlHandler) {
|
|
85
|
+
const protocol = proxyUrlHandler.protocol.replace(':', '');
|
|
86
|
+
if (possibleProtocol.includes(protocol)) {
|
|
87
|
+
if (protocol !== 'http' && (proxyUrlHandler.username || proxyUrlHandler.password)) {
|
|
88
|
+
logger.warn("PROXY_URI is an HTTPS/SOCKS proxy with authentication, which is not supported by puppeteer (ignore if you don't need it)");
|
|
89
|
+
logger.info('To get rid of this, consider using an HTTP proxy instead');
|
|
90
|
+
}
|
|
91
|
+
proxyObj.protocol = protocol;
|
|
92
|
+
proxyObj.host = proxyUrlHandler.hostname;
|
|
93
|
+
proxyObj.port = parseInt(proxyUrlHandler.port) || undefined;
|
|
94
|
+
// trailing slash will cause puppeteer to throw net::ERR_NO_SUPPORTED_PROXIES, trim it
|
|
95
|
+
proxyUri = proxyUrlHandler.href.endsWith('/') ? proxyUrlHandler.href.slice(0, -1) : proxyUrlHandler.href;
|
|
96
|
+
isProxyValid = true;
|
|
97
|
+
} else {
|
|
98
|
+
logger.error(`Unsupported proxy protocol: ${protocol}, expect one of ${possibleProtocol.join(', ')}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!isProxyValid) {
|
|
102
|
+
if ((oriProxyUri && typeof oriProxyUri === 'string') || oriProxyObj.protocol || oriProxyObj.host || oriProxyObj.port || oriProxyObj.auth) {
|
|
103
|
+
logger.error('Proxy is disabled due to misconfiguration');
|
|
104
|
+
}
|
|
105
|
+
proxyObj.protocol = proxyObj.host = proxyObj.port = proxyObj.auth = undefined;
|
|
106
|
+
proxyUri = null;
|
|
107
|
+
proxyUrlHandler = null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return { proxyUri, proxyObj, proxyUrlHandler };
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
unifyProxy,
|
|
115
|
+
...unifyProxy(config.proxyUri, config.proxy),
|
|
116
|
+
};
|