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.
Files changed (335) hide show
  1. package/README.md +3 -3
  2. package/lib/config.js +1 -1
  3. package/lib/middleware/parameter.js +3 -3
  4. package/lib/radar-rules.js +0 -46
  5. package/lib/router.js +28 -28
  6. package/lib/routes/v2ex/post.js +3 -0
  7. package/lib/utils/puppeteer-utils.js +63 -0
  8. package/lib/utils/puppeteer.js +13 -8
  9. package/lib/utils/request-wrapper.js +38 -100
  10. package/lib/utils/unify-proxy.js +116 -0
  11. package/lib/utils/wechat-mp.js +2 -0
  12. package/lib/v2/18comic/utils.js +2 -2
  13. package/lib/v2/36kr/index.js +29 -24
  14. package/lib/v2/agora0/maintainer.js +1 -0
  15. package/lib/v2/agora0/pen0.js +43 -0
  16. package/lib/v2/agora0/radar.js +12 -1
  17. package/lib/v2/agora0/router.js +1 -0
  18. package/lib/v2/aiea/index.js +39 -0
  19. package/lib/v2/aiea/maintainer.js +3 -0
  20. package/lib/v2/aiea/radar.js +13 -0
  21. package/lib/v2/aiea/router.js +3 -0
  22. package/lib/v2/baidu/radar.js +6 -6
  23. package/lib/v2/bangumi/online/online.js +4 -2
  24. package/lib/v2/bangumi/tv/group/reply.js +13 -1
  25. package/lib/v2/bangumi/tv/group/topic.js +22 -9
  26. package/lib/v2/bilibili/cache.js +34 -1
  27. package/lib/v2/bilibili/userCollection.js +1 -2
  28. package/lib/v2/bilibili/utils.js +10 -0
  29. package/lib/v2/bilibili/video-all.js +5 -2
  30. package/lib/v2/bilibili/video.js +3 -1
  31. package/lib/v2/bytes/bytes.js +25 -0
  32. package/lib/v2/bytes/maintainer.js +4 -0
  33. package/lib/v2/bytes/radar.js +13 -0
  34. package/lib/v2/bytes/router.js +3 -0
  35. package/lib/v2/caijing/maintainer.js +3 -0
  36. package/lib/v2/caijing/radar.js +13 -0
  37. package/lib/v2/caijing/roll.js +46 -0
  38. package/lib/v2/caijing/router.js +3 -0
  39. package/lib/v2/cdzjryb/maintainer.js +3 -0
  40. package/lib/v2/cdzjryb/projectList.js +49 -0
  41. package/lib/v2/cdzjryb/radar.js +13 -0
  42. package/lib/v2/cdzjryb/router.js +3 -0
  43. package/lib/v2/cdzjryb/templates/projectList.art +23 -0
  44. package/lib/v2/chsi/kydt.js +51 -0
  45. package/lib/v2/chsi/maintainer.js +3 -0
  46. package/lib/v2/chsi/radar.js +13 -0
  47. package/lib/v2/chsi/router.js +3 -0
  48. package/lib/v2/cnbeta/radar.js +6 -6
  49. package/lib/v2/cnbeta/router.js +1 -1
  50. package/lib/v2/cnbeta/type.js +6 -12
  51. package/lib/v2/cnbeta/utils.js +5 -8
  52. package/lib/v2/cngal/entry.js +25 -0
  53. package/lib/v2/cngal/maintainer.js +4 -0
  54. package/lib/v2/cngal/radar.js +19 -0
  55. package/lib/v2/cngal/router.js +4 -0
  56. package/lib/v2/cngal/templates/entry-description.art +4 -0
  57. package/lib/v2/cngal/templates/weekly-description.art +4 -0
  58. package/lib/v2/cngal/weekly.js +20 -0
  59. package/lib/v2/cnki/author.js +45 -0
  60. package/lib/v2/cnki/journals.js +2 -23
  61. package/lib/v2/cnki/maintainer.js +1 -0
  62. package/lib/v2/cnki/radar.js +8 -0
  63. package/lib/v2/cnki/router.js +1 -0
  64. package/lib/v2/cnki/utils.js +26 -0
  65. package/lib/v2/codeforces/maintainer.js +1 -0
  66. package/lib/v2/codeforces/radar.js +8 -0
  67. package/lib/v2/codeforces/recent_actions.js +47 -0
  68. package/lib/v2/codeforces/router.js +1 -0
  69. package/lib/v2/curius/links.js +43 -0
  70. package/lib/v2/curius/maintainer.js +3 -0
  71. package/lib/v2/curius/radar.js +13 -0
  72. package/lib/v2/curius/router.js +3 -0
  73. package/lib/v2/curius/templates/description.art +16 -0
  74. package/lib/v2/douyin/hashtag.js +20 -19
  75. package/lib/v2/douyin/live.js +2 -21
  76. package/lib/v2/douyin/user.js +2 -17
  77. package/lib/v2/douyin/utils.js +85 -0
  78. package/lib/v2/{acm-ecnu → ecnu}/contest.js +1 -4
  79. package/lib/v2/ecnu/maintainer.js +4 -0
  80. package/lib/v2/ecnu/radar.js +30 -0
  81. package/lib/v2/ecnu/router.js +4 -0
  82. package/lib/v2/{acm-ecnu → ecnu}/templates/description.art +0 -0
  83. package/lib/v2/ecnu/yjs.js +37 -0
  84. package/lib/v2/ehentai/ehapi.js +23 -12
  85. package/lib/v2/foresightnews/index.js +8 -11
  86. package/lib/v2/foreverblog/feeds.js +36 -0
  87. package/lib/v2/foreverblog/maintainer.js +3 -0
  88. package/lib/v2/foreverblog/radar.js +13 -0
  89. package/lib/v2/foreverblog/router.js +3 -0
  90. package/lib/v2/freewechat/maintainer.js +3 -0
  91. package/lib/v2/freewechat/profile.js +61 -0
  92. package/lib/v2/freewechat/radar.js +13 -0
  93. package/lib/v2/freewechat/router.js +3 -0
  94. package/lib/v2/gcores/category.js +16 -6
  95. package/lib/v2/good/index.js +15 -14
  96. package/lib/v2/gov/customs/list.js +1 -1
  97. package/lib/v2/gov/dianbai/dianbai.js +18 -0
  98. package/lib/v2/gov/gaozhou/gaozhou.js +19 -0
  99. package/lib/v2/gov/general/general.js +250 -0
  100. package/lib/v2/gov/general/templates/zcjdpt.art +128 -0
  101. package/lib/v2/gov/gz/index.js +38 -0
  102. package/lib/v2/gov/huazhou/huazhou.js +19 -0
  103. package/lib/v2/gov/hunan/changsha/major-email.js +52 -0
  104. package/lib/v2/gov/maintainer.js +19 -2
  105. package/lib/v2/gov/maoming/maoming.js +417 -0
  106. package/lib/v2/gov/maonan/maonan.js +100 -0
  107. package/lib/v2/gov/mgs/mgs.js +19 -0
  108. package/lib/v2/gov/mmht/mmht.js +19 -0
  109. package/lib/v2/gov/nmpa/generic.js +1 -1
  110. package/lib/v2/gov/radar.js +197 -0
  111. package/lib/v2/gov/router.js +18 -2
  112. package/lib/v2/gov/sasac/generic.js +42 -0
  113. package/lib/v2/gov/sdb/sdb.js +19 -0
  114. package/lib/v2/gov/shanghai/yjj/index.js +3 -1
  115. package/lib/v2/gov/xinyi/xinyi.js +19 -0
  116. package/lib/v2/gov/zhengce/govall.js +55 -0
  117. package/lib/v2/gov/zhengce/wenjian.js +47 -0
  118. package/lib/v2/gov/zhengce/zhengceku.js +22 -0
  119. package/lib/v2/gov/zhengce/zuixin.js +39 -0
  120. package/lib/v2/guanhai/index.js +47 -0
  121. package/lib/v2/guanhai/maintainer.js +4 -0
  122. package/lib/v2/guanhai/radar.js +13 -0
  123. package/lib/v2/guanhai/router.js +3 -0
  124. package/lib/v2/hackernews/index.js +6 -0
  125. package/lib/v2/hellogithub/volume.js +15 -32
  126. package/lib/v2/{heu → hrbeu}/gx/card.js +5 -10
  127. package/lib/v2/{heu → hrbeu}/gx/list.js +12 -20
  128. package/lib/v2/hrbeu/job/bigemploy.js +25 -0
  129. package/lib/v2/{heu → hrbeu}/job/calendar.js +8 -16
  130. package/lib/v2/{heu → hrbeu}/job/list.js +11 -16
  131. package/lib/v2/{heu → hrbeu}/maintainer.js +2 -1
  132. package/lib/v2/{heu → hrbeu}/radar.js +18 -10
  133. package/lib/v2/{heu → hrbeu}/router.js +3 -2
  134. package/lib/v2/{heu → hrbeu}/uae/list.js +12 -17
  135. package/lib/v2/hrbeu/ugs/news.js +98 -0
  136. package/lib/v2/{heu → hrbeu}/yjsy/list.js +8 -16
  137. package/lib/v2/ieee-security/maintainer.js +3 -0
  138. package/lib/v2/ieee-security/radar.js +13 -0
  139. package/lib/v2/ieee-security/router.js +3 -0
  140. package/lib/v2/ieee-security/sp.js +36 -0
  141. package/lib/v2/javbus/index.js +8 -2
  142. package/lib/v2/javbus/templates/description.art +12 -1
  143. package/lib/v2/jike/user.js +1 -0
  144. package/lib/v2/lang/maintainer.js +3 -0
  145. package/lib/v2/lang/radar.js +13 -0
  146. package/lib/v2/lang/room.js +40 -0
  147. package/lib/v2/lang/router.js +3 -0
  148. package/lib/v2/lang/templates/room.art +1 -0
  149. package/lib/v2/liulinblog/utils.js +7 -4
  150. package/lib/v2/luogu/daily.js +1 -1
  151. package/lib/v2/mangadex/index.js +73 -0
  152. package/lib/v2/mangadex/maintainer.js +3 -0
  153. package/lib/v2/mangadex/radar.js +13 -0
  154. package/lib/v2/mangadex/router.js +3 -0
  155. package/lib/v2/mihoyo/ys/news.js +3 -2
  156. package/lib/v2/mirror/index.js +15 -8
  157. package/lib/v2/mrdx/daily.js +79 -0
  158. package/lib/v2/mrdx/maintainer.js +3 -0
  159. package/lib/v2/mrdx/radar.js +13 -0
  160. package/lib/v2/mrdx/router.js +3 -0
  161. package/lib/v2/mrdx/utils.js +17 -0
  162. package/lib/v2/mtime/news.js +1 -1
  163. package/lib/v2/nautil/maintainer.js +3 -0
  164. package/lib/v2/nautil/radar.js +13 -0
  165. package/lib/v2/nautil/router.js +3 -0
  166. package/lib/v2/nautil/templates/description.art +6 -0
  167. package/lib/v2/nautil/topics.js +57 -0
  168. package/lib/v2/ndss-symposium/maintainer.js +3 -0
  169. package/lib/v2/ndss-symposium/ndss.js +80 -0
  170. package/lib/v2/ndss-symposium/radar.js +13 -0
  171. package/lib/v2/ndss-symposium/router.js +3 -0
  172. package/lib/v2/nextapple/realtime.js +1 -1
  173. package/lib/v2/nintendo/direct.js +31 -0
  174. package/lib/v2/nintendo/eshop_cn.js +44 -0
  175. package/lib/v2/nintendo/eshop_hk.js +79 -0
  176. package/lib/v2/nintendo/eshop_jp.js +34 -0
  177. package/lib/v2/nintendo/eshop_us.js +32 -0
  178. package/lib/v2/nintendo/maintainer.js +7 -0
  179. package/lib/v2/nintendo/news.js +23 -0
  180. package/lib/v2/nintendo/news_china.js +35 -0
  181. package/lib/v2/nintendo/radar.js +70 -0
  182. package/lib/v2/nintendo/router.js +10 -0
  183. package/lib/{routes → v2}/nintendo/system-update.js +2 -2
  184. package/lib/v2/nintendo/templates/direct.art +6 -0
  185. package/lib/v2/nintendo/templates/eshop_cn.art +21 -0
  186. package/lib/v2/nintendo/templates/eshop_hk.art +61 -0
  187. package/lib/v2/nintendo/templates/eshop_jp.art +3 -0
  188. package/lib/v2/nintendo/templates/eshop_us.art +24 -0
  189. package/lib/{routes → v2}/nintendo/utils.js +34 -50
  190. package/lib/v2/njxzc/home.js +13 -9
  191. package/lib/v2/nmtv/column.js +53 -0
  192. package/lib/v2/nmtv/maintainer.js +3 -0
  193. package/lib/v2/nmtv/radar.js +13 -0
  194. package/lib/v2/nmtv/router.js +3 -0
  195. package/lib/v2/nmtv/templates/description.art +9 -0
  196. package/lib/v2/nua/lib.js +39 -0
  197. package/lib/v2/nua/maintainer.js +1 -0
  198. package/lib/v2/nua/radar.js +8 -0
  199. package/lib/v2/nua/router.js +1 -0
  200. package/lib/v2/nua/utils.js +7 -12
  201. package/lib/v2/nuaa/utils/pypasswaf.js +3 -2
  202. package/lib/v2/nyaa/main.js +16 -23
  203. package/lib/v2/nyaa/maintainer.js +7 -4
  204. package/lib/v2/nyaa/radar.js +27 -29
  205. package/lib/v2/nyaa/router.js +4 -2
  206. package/lib/v2/odaily/post.js +15 -20
  207. package/lib/v2/odaily/utils.js +1 -1
  208. package/lib/v2/paradigm/maintainer.js +3 -0
  209. package/lib/v2/paradigm/radar.js +13 -0
  210. package/lib/v2/paradigm/router.js +3 -0
  211. package/lib/v2/paradigm/writing.js +44 -0
  212. package/lib/v2/picuki/maintainer.js +1 -1
  213. package/lib/v2/picuki/profile.js +10 -8
  214. package/lib/v2/picuki/utils.js +21 -0
  215. package/lib/v2/pixiv/api/getRanking.js +1 -1
  216. package/lib/v2/pixiv/ranking.js +3 -0
  217. package/lib/v2/producthunt/templates/descImg.art +2 -2
  218. package/lib/v2/qlu/maintainer.js +3 -0
  219. package/lib/v2/qlu/notice.js +54 -0
  220. package/lib/v2/qlu/radar.js +13 -0
  221. package/lib/v2/qlu/router.js +3 -0
  222. package/lib/v2/reactnewsletter/maintainer.js +4 -0
  223. package/lib/v2/reactnewsletter/radar.js +13 -0
  224. package/lib/v2/reactnewsletter/reactnewsletter.js +25 -0
  225. package/lib/v2/reactnewsletter/router.js +3 -0
  226. package/lib/v2/researchgate/maintainer.js +3 -0
  227. package/lib/v2/researchgate/publications.js +70 -0
  228. package/lib/v2/researchgate/radar.js +13 -0
  229. package/lib/v2/researchgate/router.js +3 -0
  230. package/lib/v2/saraba1st/digest.js +79 -0
  231. package/lib/v2/saraba1st/maintainer.js +1 -0
  232. package/lib/v2/saraba1st/radar.js +12 -3
  233. package/lib/v2/saraba1st/router.js +1 -0
  234. package/lib/v2/saraba1st/templates/digest.art +5 -0
  235. package/lib/v2/sctv/maintainer.js +1 -1
  236. package/lib/v2/sctv/programme.js +39 -17
  237. package/lib/v2/sctv/router.js +1 -1
  238. package/lib/v2/shmtu/jwc.js +57 -0
  239. package/lib/v2/shmtu/maintainer.js +5 -0
  240. package/lib/v2/shmtu/portal.js +81 -0
  241. package/lib/v2/shmtu/radar.js +29 -0
  242. package/lib/v2/shmtu/router.js +5 -0
  243. package/lib/v2/shmtu/templates/portal.art +30 -0
  244. package/lib/v2/shmtu/www.js +58 -0
  245. package/lib/v2/sigsac/ccs.js +57 -0
  246. package/lib/v2/sigsac/maintainer.js +3 -0
  247. package/lib/v2/sigsac/radar.js +13 -0
  248. package/lib/v2/sigsac/router.js +3 -0
  249. package/lib/v2/simpleinfo/index.js +50 -0
  250. package/lib/v2/simpleinfo/maintainer.js +3 -0
  251. package/lib/v2/simpleinfo/radar.js +19 -0
  252. package/lib/v2/simpleinfo/router.js +3 -0
  253. package/lib/v2/simpleinfo/templates/description.art +6 -0
  254. package/lib/v2/sse/maintainer.js +1 -1
  255. package/lib/v2/telegram/channel.js +54 -38
  256. package/lib/v2/tencent/maintainer.js +2 -0
  257. package/lib/v2/tencent/news/coronavirus/data.js +71 -0
  258. package/lib/v2/tencent/news/coronavirus/total.js +34 -0
  259. package/lib/v2/tencent/news/coronavirus/utils.js +17 -0
  260. package/lib/v2/tencent/radar.js +8 -0
  261. package/lib/v2/tencent/router.js +2 -0
  262. package/lib/v2/tencent/templates/coronavirus/chinaTotal.art +6 -0
  263. package/lib/v2/tencent/templates/coronavirus/data.art +4 -0
  264. package/lib/v2/test/index.js +8 -0
  265. package/lib/v2/theverge/index.js +9 -1
  266. package/lib/v2/theverge/maintainer.js +1 -1
  267. package/lib/v2/theverge/radar.js +2 -2
  268. package/lib/v2/theverge/router.js +1 -1
  269. package/lib/v2/tingshuitz/changsha.js +43 -0
  270. package/lib/v2/tingshuitz/maintainer.js +1 -0
  271. package/lib/v2/tingshuitz/radar.js +10 -0
  272. package/lib/v2/tingshuitz/router.js +1 -0
  273. package/lib/v2/twitter/web-api/twitter-api.js +19 -15
  274. package/lib/v2/twreporter/category.js +17 -8
  275. package/lib/v2/uber/blog.js +59 -0
  276. package/lib/v2/uber/maintainer.js +3 -0
  277. package/lib/v2/uber/radar.js +13 -0
  278. package/lib/v2/uber/router.js +3 -0
  279. package/lib/v2/usenix/maintainer.js +3 -0
  280. package/lib/v2/usenix/radar.js +13 -0
  281. package/lib/v2/usenix/router.js +3 -0
  282. package/lib/v2/usenix/usenix.js +63 -0
  283. package/lib/v2/usepanda/index.js +26 -0
  284. package/lib/v2/usepanda/maintainer.js +3 -0
  285. package/lib/v2/usepanda/radar.js +11 -0
  286. package/lib/v2/usepanda/router.js +3 -0
  287. package/lib/v2/uw/gix/news.js +67 -0
  288. package/lib/v2/uw/maintainer.js +3 -0
  289. package/lib/v2/uw/radar.js +13 -0
  290. package/lib/v2/uw/router.js +3 -0
  291. package/lib/v2/verse/articles.js +42 -0
  292. package/lib/v2/verse/maintainer.js +3 -0
  293. package/lib/v2/verse/radar.js +13 -0
  294. package/lib/v2/verse/router.js +3 -0
  295. package/lib/{routes → v2}/weibo/keyword.js +2 -2
  296. package/lib/v2/weibo/maintainer.js +8 -0
  297. package/lib/v2/weibo/oasis/user.js +20 -0
  298. package/lib/v2/weibo/radar.js +48 -0
  299. package/lib/v2/weibo/router.js +8 -0
  300. package/lib/{routes → v2}/weibo/search/hot.js +2 -0
  301. package/lib/{routes → v2}/weibo/super_index.js +2 -2
  302. package/lib/{routes → v2}/weibo/timeline.js +2 -2
  303. package/lib/{routes → v2}/weibo/user.js +2 -2
  304. package/lib/{routes → v2}/weibo/utils.js +49 -14
  305. package/lib/v2/ymgal/article.js +61 -0
  306. package/lib/v2/ymgal/game.js +41 -0
  307. package/lib/v2/ymgal/maintainer.js +4 -0
  308. package/lib/v2/ymgal/radar.js +31 -0
  309. package/lib/v2/ymgal/router.js +4 -0
  310. package/lib/v2/ymgal/templates/description.art +7 -0
  311. package/lib/v2/zhihu/pin/utils.js +49 -41
  312. package/package.json +26 -27
  313. package/lib/routes/blogs/foreverblog.js +0 -33
  314. package/lib/routes/gov/zhengce/govall.js +0 -59
  315. package/lib/routes/gov/zhengce/wenjian.js +0 -53
  316. package/lib/routes/gov/zhengce/zuixin.js +0 -42
  317. package/lib/routes/langlive/room.js +0 -33
  318. package/lib/routes/nautilus/topics.js +0 -45
  319. package/lib/routes/nintendo/direct.js +0 -34
  320. package/lib/routes/nintendo/eshop_cn.js +0 -51
  321. package/lib/routes/nintendo/eshop_hk.js +0 -26
  322. package/lib/routes/nintendo/eshop_jp.js +0 -20
  323. package/lib/routes/nintendo/eshop_us.js +0 -36
  324. package/lib/routes/nintendo/news.js +0 -25
  325. package/lib/routes/nintendo/news_china.js +0 -41
  326. package/lib/routes/researchgate/publications.js +0 -60
  327. package/lib/routes/universities/ecnuyjs/ecnuyjs.js +0 -23
  328. package/lib/routes/universities/shmtu/jwc.js +0 -75
  329. package/lib/routes/universities/shmtu/www.js +0 -61
  330. package/lib/routes/weibo/oasis/user.js +0 -17
  331. package/lib/v2/acm-ecnu/maintainer.js +0 -3
  332. package/lib/v2/acm-ecnu/radar.js +0 -19
  333. package/lib/v2/acm-ecnu/router.js +0 -3
  334. package/lib/v2/cnbeta/index.js +0 -16
  335. package/lib/v2/heu/job/bigemploy.js +0 -42
@@ -0,0 +1,16 @@
1
+ {{ if item.metadata.full_text }}
2
+ 原文:{{@ item.metadata.full_text.replace(/\n/gm, '<br>') }}<br><br>
3
+ {{ /if }}
4
+ {{ if item.comments.length }}
5
+ 评论:{{ item.comments[0].text.substring(0, 100) }}<br><br>
6
+ {{ /if }}
7
+ {{ if item.highlights.length }}
8
+ 评论:
9
+ {{ each item.highlights highlight }}
10
+ {{ if highlight.comment }}
11
+ {{ highlight.highlight }}<br>评论:{{ highlight.comment.text }}<br>
12
+ {{ else }}
13
+ <br>标注:{{ highlight.highlight }}<br>
14
+ {{ /if }}
15
+ {{ /each }}
16
+ {{ /if }}
@@ -1,4 +1,3 @@
1
- const cheerio = require('cheerio');
2
1
  const { parseDate } = require('@/utils/parse-date');
3
2
  const { art } = require('@/utils/render');
4
3
  const config = require('@/config').value;
@@ -23,19 +22,26 @@ module.exports = async (ctx) => {
23
22
  const browser = await require('@/utils/puppeteer')();
24
23
  const page = await browser.newPage();
25
24
  await page.setRequestInterception(true);
25
+ let awemeList = '';
26
26
  page.on('request', (request) => {
27
- request.resourceType() === 'document' ? request.continue() : request.abort();
27
+ request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' ? request.continue() : request.abort();
28
+ });
29
+ page.on('response', async (response) => {
30
+ const request = response.request();
31
+ if (request.url().includes('/v1/web/challenge/aweme')) {
32
+ awemeList = await response.json();
33
+ }
28
34
  });
29
35
  await page.goto(tagUrl, {
30
- waitUntil: 'domcontentloaded',
36
+ waitUntil: 'networkidle2',
31
37
  });
32
38
  await page.waitForSelector('#RENDER_DATA');
33
- const html = await page.evaluate(() => document.documentElement.innerHTML);
39
+ const html = await page.evaluate(() => document.getElementById('RENDER_DATA').innerText);
34
40
  await browser.close();
35
41
 
36
- const $ = cheerio.load(html);
37
- const renderData = JSON.parse(decodeURIComponent($('script#RENDER_DATA').text()));
38
- const dataKey = Object.keys(renderData).find((key) => renderData[key].topicDetail && renderData[key].defaultData);
42
+ const renderData = JSON.parse(decodeURIComponent(html));
43
+ const dataKey = Object.keys(renderData).find((key) => renderData[key].topicDetail);
44
+ renderData[dataKey].defaultData = awemeList.aweme_list;
39
45
  return renderData[dataKey];
40
46
  },
41
47
  config.cache.routeExpire,
@@ -49,7 +55,7 @@ module.exports = async (ctx) => {
49
55
  const posts = tagData.defaultData;
50
56
  const items = posts.map((post) => {
51
57
  // parse video
52
- let videoList = post.video && post.video.bitRateList && post.video.bitRateList.map((item) => resolveUrl(item.playApi));
58
+ let videoList = post.video && post.video.bit_rate && post.video.bit_rate.map((bit_rate) => resolveUrl(bit_rate.play_addr.url_list[0]));
53
59
  if (relay) {
54
60
  videoList = videoList.map((item) => proxyVideo(item, relay));
55
61
  }
@@ -57,14 +63,9 @@ module.exports = async (ctx) => {
57
63
  duration = duration && duration / 1000;
58
64
  let img;
59
65
  // if (!embed) {
60
- // img = post.video && post.video.dynamicCover; // dynamic cover (webp)
66
+ // img = post.video && post.video.dynamic_cover && post.video.dynamic_cover.url_list[post.video.dynamic_cover.url_list.length - 1]; // dynamic cover (webp)
61
67
  // }
62
- img =
63
- img ||
64
- (post.video &&
65
- ((post.video.coverUrlList && post.video.coverUrlList[post.video.coverUrlList.length - 1]) || // HD
66
- post.video.originCover || // LD
67
- post.video.cover)); // even more LD
68
+ img = img || (post.video && post.video.origin_cover && post.video.origin_cover.url_list[post.video.origin_cover.url_list.length - 1]);
68
69
  img = img && resolveUrl(img);
69
70
 
70
71
  // render description
@@ -76,10 +77,10 @@ module.exports = async (ctx) => {
76
77
  return {
77
78
  title: post.desc,
78
79
  description,
79
- link: `https://www.douyin.com/video/${post.awemeId}`,
80
- pubDate: parseDate(post.createTime * 1000),
81
- category: post.textExtra.map((extra) => extra.hashtagName),
82
- author: post.authorInfo.nickname,
80
+ link: `https://www.douyin.com/video/${post.aweme_id}`,
81
+ pubDate: parseDate(post.create_time, 'X'),
82
+ category: post.text_extra.map((extra) => extra.hashtag_name),
83
+ author: post.author.nickname,
83
84
  };
84
85
  });
85
86
 
@@ -1,5 +1,5 @@
1
1
  const config = require('@/config').value;
2
- const { getOriginAvatar } = require('./utils');
2
+ const { getOriginAvatar, universalGet } = require('./utils');
3
3
 
4
4
  module.exports = async (ctx) => {
5
5
  const { rid } = ctx.params;
@@ -9,26 +9,7 @@ module.exports = async (ctx) => {
9
9
 
10
10
  const pageUrl = `https://live.douyin.com/${rid}`;
11
11
 
12
- const renderData = await ctx.cache.tryGet(
13
- `douyin:live:${rid}`,
14
- async () => {
15
- const browser = await require('@/utils/puppeteer')();
16
- const page = await browser.newPage();
17
- await page.setRequestInterception(true);
18
- page.on('request', (request) => {
19
- request.resourceType() === 'document' ? request.continue() : request.abort();
20
- });
21
- await page.goto(pageUrl, {
22
- waitUntil: 'domcontentloaded',
23
- });
24
- const data = JSON.parse(decodeURIComponent(await page.evaluate(() => document.querySelector('#RENDER_DATA').innerText)));
25
- browser.close();
26
-
27
- return data;
28
- },
29
- config.cache.routeExpire,
30
- false
31
- );
12
+ const renderData = await ctx.cache.tryGet(`douyin:live:${rid}`, () => universalGet(pageUrl, 'live', ctx), config.cache.routeExpire, false);
32
13
 
33
14
  if (renderData[Object.keys(renderData).find((k) => renderData[k].status_code)].status_code !== '0') {
34
15
  throw `Status code ${renderData[Object.keys(renderData).find((k) => renderData[k].status_code)].status_code}`;
@@ -1,9 +1,8 @@
1
- const cheerio = require('cheerio');
2
1
  const { parseDate } = require('@/utils/parse-date');
3
2
  const { art } = require('@/utils/render');
4
3
  const config = require('@/config').value;
5
4
  const { fallback, queryToBoolean } = require('@/utils/readable-social');
6
- const { templates, resolveUrl, proxyVideo, getOriginAvatar } = require('./utils');
5
+ const { templates, resolveUrl, proxyVideo, getOriginAvatar, universalGet } = require('./utils');
7
6
 
8
7
  module.exports = async (ctx) => {
9
8
  const uid = ctx.params.uid;
@@ -20,27 +19,13 @@ module.exports = async (ctx) => {
20
19
  const pageData = await ctx.cache.tryGet(
21
20
  `douyin:user:${uid}`,
22
21
  async () => {
23
- const browser = await require('@/utils/puppeteer')();
24
- const page = await browser.newPage();
25
- await page.setRequestInterception(true);
26
- page.on('request', (request) => {
27
- request.resourceType() === 'document' ? request.continue() : request.abort();
28
- });
29
- await page.goto(pageUrl, {
30
- waitUntil: 'domcontentloaded',
31
- });
32
- const html = await page.evaluate(() => document.documentElement.innerHTML);
33
- await browser.close();
34
-
35
- const $ = cheerio.load(html);
36
- const renderData = JSON.parse(decodeURIComponent($('script#RENDER_DATA').html()));
22
+ const renderData = await universalGet(pageUrl, 'user', ctx);
37
23
  const dataKey = Object.keys(renderData).filter((key) => renderData[key].user && renderData[key].post)[0];
38
24
  return renderData[dataKey];
39
25
  },
40
26
  config.cache.routeExpire,
41
27
  false
42
28
  );
43
-
44
29
  const userInfo = pageData.user.user;
45
30
  const userNickName = userInfo.nickname;
46
31
  const userDescription = userInfo.desc;
@@ -1,4 +1,8 @@
1
1
  const path = require('path');
2
+ const got = require('@/utils/got');
3
+ const cheerio = require('cheerio');
4
+ const logger = require('@/utils/logger');
5
+ const config = require('@/config').value;
2
6
 
3
7
  const templates = {
4
8
  desc: path.join(__dirname, 'templates/desc.art'),
@@ -42,9 +46,90 @@ const getOriginAvatar = (url) =>
42
46
  .replace(/^(.*\.douyinpic\.com\/).*(\/aweme-avatar\/)([^?]*)(\?.*)?$/, '$1origin$2$3')
43
47
  .replace(/~\w+_\d+x\d+/g, '');
44
48
 
49
+ const extractRenderData = (html) => {
50
+ if (!html) {
51
+ throw Error('Empty html. The request may be filtered by WAF.');
52
+ }
53
+
54
+ const $ = cheerio.load(html);
55
+ const renderData = JSON.parse(decodeURIComponent($('script#RENDER_DATA').html()));
56
+ if (!renderData) {
57
+ const title = $('title').text();
58
+ if (title.includes('验证')) {
59
+ throw Error(title);
60
+ } else if ($('#captcha_container').length > 0) {
61
+ throw Error('Captcha required.');
62
+ }
63
+ throw Error('Failed to get render data.');
64
+ } else if (renderData.isSpider) {
65
+ throw Error('The request was considered to be from a spider.');
66
+ } else {
67
+ return renderData;
68
+ }
69
+ };
70
+
71
+ const gotGet = async (url, ua) => {
72
+ const response = await got(url, {
73
+ headers: {
74
+ 'User-Agent': ua, // magic!
75
+ },
76
+ });
77
+ return extractRenderData(response.data);
78
+ };
79
+
80
+ const puppeteerGet = async (pageUrl) => {
81
+ const browser = await require('@/utils/puppeteer')();
82
+ const page = await browser.newPage();
83
+ await page.setRequestInterception(true);
84
+ page.on('request', (request) => {
85
+ request.resourceType() === 'document' ? request.continue() : request.abort();
86
+ });
87
+ await page.goto(pageUrl, {
88
+ waitUntil: 'domcontentloaded',
89
+ });
90
+ const html = await page.evaluate(() => document.documentElement.innerHTML);
91
+ await browser.close();
92
+ return extractRenderData(html);
93
+ };
94
+
95
+ const universalGet = async (url, route, ctx) => {
96
+ const cacheKey = `douyin:utils:universalGet:gotFirst:${route}`;
97
+ const gotFirst = await ctx.cache.tryGet(
98
+ cacheKey,
99
+ () => '1',
100
+ config.cache.contentExpire,
101
+ false // no refresh now
102
+ );
103
+
104
+ const ua = route === 'live' ? 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' : 'curl/7.86.0';
105
+
106
+ let data;
107
+ if (gotFirst === '1') {
108
+ try {
109
+ data = await gotGet(url, ua);
110
+ ctx.cache.set(cacheKey, '1', config.cache.contentExpire); // refresh if success
111
+ } catch (e) {
112
+ logger.warn('Failed to get data with got, trying puppeteer: ' + e.message);
113
+ data = await puppeteerGet(url);
114
+ ctx.cache.set(cacheKey, '0', config.cache.contentExpire); // only set if success
115
+ }
116
+ } else {
117
+ try {
118
+ data = await puppeteerGet(url);
119
+ ctx.cache.set(cacheKey, '0', config.cache.contentExpire); // refresh if success
120
+ } catch (e) {
121
+ logger.warn('Failed to get data with puppeteer, trying got: ' + e.message);
122
+ data = await gotGet(url, ua);
123
+ ctx.cache.set(cacheKey, '1', config.cache.contentExpire); // only set if success
124
+ }
125
+ }
126
+ return data;
127
+ };
128
+
45
129
  module.exports = {
46
130
  templates,
47
131
  resolveUrl,
48
132
  proxyVideo,
49
133
  getOriginAvatar,
134
+ universalGet,
50
135
  };
@@ -9,10 +9,7 @@ module.exports = async (ctx) => {
9
9
  const rootUrl = 'https://acm.ecnu.edu.cn';
10
10
  const currentUrl = `${rootUrl}/contest/`;
11
11
 
12
- const response = await got({
13
- method: 'get',
14
- url: currentUrl,
15
- });
12
+ const response = await got(currentUrl);
16
13
 
17
14
  const $ = cheerio.load(response.data);
18
15
  const $trList = $('div > div > table > tbody > tr');
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ '/acm/contest/:category?': ['a180285'],
3
+ '/yjs': ['shengmaosu'],
4
+ };
@@ -0,0 +1,30 @@
1
+ module.exports = {
2
+ 'ecnu.edu.cn': {
3
+ _name: '华东师范大学',
4
+ acm: [
5
+ {
6
+ title: '所有比赛列表',
7
+ docs: 'https://docs.rsshub.app/university.html#hua-dong-shi-fan-da-xue',
8
+ source: ['/contest/', '/'],
9
+ target: '/ecnu/acm/contest/',
10
+ },
11
+ {
12
+ title: '仅公开比赛列表',
13
+ docs: 'https://docs.rsshub.app/university.html#hua-dong-shi-fan-da-xue',
14
+ source: ['/contest/', '/'],
15
+ target: '/ecnu/acm/contest/public',
16
+ },
17
+ ],
18
+ },
19
+ 'kaoyan.com': {
20
+ _name: '华东师范大学',
21
+ yz: [
22
+ {
23
+ title: '研究生院',
24
+ docs: 'https://docs.rsshub.app/university.html#hua-dong-shi-fan-da-xue',
25
+ source: ['/ecnu/tiaoji', '/'],
26
+ target: '/ecnu/yjs',
27
+ },
28
+ ],
29
+ },
30
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = function (router) {
2
+ router.get('/acm/contest/:category?', require('./contest'));
3
+ router.get('/yjs', require('./yjs'));
4
+ };
@@ -0,0 +1,37 @@
1
+ const got = require('@/utils/got');
2
+ const cheerio = require('cheerio');
3
+ const { parseDate } = require('@/utils/parse-date');
4
+
5
+ module.exports = async (ctx) => {
6
+ const link = 'https://yz.kaoyan.com/ecnu/tiaoji/';
7
+ const response = await got(link);
8
+ const $ = cheerio.load(response.data);
9
+ const list = $('.subList li')
10
+ .toArray()
11
+ .map((item) => {
12
+ item = $(item);
13
+ return {
14
+ title: item.find('li a').text(),
15
+ link: item.find('li a').attr('href').replace('http:', 'https:'),
16
+ };
17
+ });
18
+
19
+ const items = await Promise.all(
20
+ list.map((item) =>
21
+ ctx.cache.tryGet(item.link, async () => {
22
+ const { data: response } = await got(item.link);
23
+ const $ = cheerio.load(response);
24
+ item.description = $('.articleCon').html();
25
+ item.pubDate = parseDate($('.outer_utime').text());
26
+ return item;
27
+ })
28
+ )
29
+ );
30
+
31
+ ctx.state.data = {
32
+ title: '华东师范大学研究生院',
33
+ link,
34
+ description: '华东师范大学研究生调剂信息',
35
+ item: items,
36
+ };
37
+ };
@@ -50,15 +50,27 @@ async function parsePage(cache, data, get_bittorrent = false, embed_thumb = fals
50
50
  // "l" for Compact
51
51
  // "e" for Extended
52
52
  // "t" for Thumbnail
53
- const layout = $('div#dms option[selected]').attr('value');
54
-
55
- let galleries;
56
- if (layout !== 't') {
57
- galleries = $('table[class^="itg glt"] tbody');
58
- } else {
59
- // Thumbnail layout has different page structure
60
- // resolve it here
61
- galleries = $('div[class^="itg gld"]');
53
+ let layout = 't';
54
+
55
+ // "itg gld" for Thumbnail
56
+ let galleries = $('div[class^="itg gld"]');
57
+ // "itg gltm" for Minimal or Minimal+
58
+ if (galleries.length <= 0) {
59
+ galleries = $('table[class^="itg gltm"] tbody');
60
+ layout = 'm';
61
+ }
62
+ // "itg gltc" for Compact
63
+ if (galleries.length <= 0) {
64
+ galleries = $('table[class^="itg gltc"] tbody');
65
+ layout = 'l';
66
+ }
67
+ // "itg glte" for Extended
68
+ if (galleries.length <= 0) {
69
+ galleries = $('table[class^="itg glte"] tbody');
70
+ layout = 'e';
71
+ }
72
+ if (galleries.length <= 0) {
73
+ return [];
62
74
  }
63
75
 
64
76
  async function parseElement(cache, element) {
@@ -108,12 +120,11 @@ async function parsePage(cache, data, get_bittorrent = false, embed_thumb = fals
108
120
  if ('le'.includes(layout)) {
109
121
  // artist tags will only show in Compact or Extended layout
110
122
  // get artist names as author
111
- const artist = $(el)
123
+ item.author = $(el)
112
124
  .find('div.gt[title^="artist:"]')
113
125
  .toArray()
114
- .map((i, tag) => $(tag).text())
126
+ .map((tag) => $(tag).text())
115
127
  .join(' / ');
116
- item.author = artist;
117
128
  }
118
129
  return item;
119
130
  }
@@ -1,6 +1,7 @@
1
1
  const got = require('@/utils/got');
2
2
  const cheerio = require('cheerio');
3
3
  const { parseDate } = require('@/utils/parse-date');
4
+ const zlib = require('zlib');
4
5
 
5
6
  const categories = {
6
7
  '': {
@@ -28,12 +29,11 @@ module.exports = async (ctx) => {
28
29
  const rootUrl = 'https://foresightnews.pro';
29
30
  const currentUrl = `${rootUrl}/v1/${categories[category].id}?page=1&size=${ctx.query.limit ?? 30}${category === 'column' ? `&column_id=${id}` : ''}`;
30
31
 
31
- const response = await got({
32
- method: 'get',
33
- url: currentUrl,
34
- });
32
+ const response = await got(currentUrl);
35
33
 
36
- let items = response.data.data.list.map((item) =>
34
+ const list = JSON.parse(zlib.inflateSync(Buffer.from(response.data.data.list, 'base64')).toString());
35
+
36
+ let items = list.map((item) =>
37
37
  item.source_type
38
38
  ? {
39
39
  type: item.source_type,
@@ -47,8 +47,8 @@ module.exports = async (ctx) => {
47
47
  : {
48
48
  type: category,
49
49
  title: item.title,
50
- author: item?.author?.username ?? undefined,
51
- link: `${rootUrl}/${category === 'article' ? 'article' : 'news'}/detail/${item.id}`,
50
+ author: item.author?.username ?? undefined,
51
+ link: `${rootUrl}/${category === 'article' || category === 'column' ? 'article' : 'news'}/detail/${item.id}`,
52
52
  category: item.tags ? item.tags.map((tag) => tag.name) : undefined,
53
53
  description: item.content ?? '',
54
54
  pubDate: parseDate(item.publishDate),
@@ -63,10 +63,7 @@ module.exports = async (ctx) => {
63
63
  items.map((item) =>
64
64
  ctx.cache.tryGet(item.link, async () => {
65
65
  if (item.type !== 'news') {
66
- const detailResponse = await got({
67
- method: 'get',
68
- url: item.link,
69
- });
66
+ const detailResponse = await got(item.link);
70
67
 
71
68
  const content = cheerio.load(detailResponse.data);
72
69
 
@@ -0,0 +1,36 @@
1
+ const got = require('@/utils/got');
2
+ const cheerio = require('cheerio');
3
+ const { parseDate } = require('@/utils/parse-date');
4
+ const timezone = require('@/utils/timezone');
5
+
6
+ module.exports = async (ctx) => {
7
+ const currentUrl = 'https://www.foreverblog.cn/feeds.html';
8
+
9
+ const response = await got(currentUrl);
10
+
11
+ const $ = cheerio.load(response.data);
12
+ const $articles = $('article[class="post post-type-normal"]');
13
+ const items = $articles
14
+ .map((_, el) => {
15
+ const $titleDiv = $(el).find('h1[class="post-title"]');
16
+ const title = $titleDiv.text().trim();
17
+ const link = $titleDiv.find('a').eq(0).attr('href');
18
+ const author = $(el).find('div[class="post-author"]').text().trim();
19
+ const postDate = $(el).find('time').text().trim();
20
+ const pubDate = timezone(parseDate(postDate, 'MM-DD'), +8);
21
+ const description = `${author}: ${title}`;
22
+ return {
23
+ title: description,
24
+ description,
25
+ link,
26
+ pubDate,
27
+ };
28
+ })
29
+ .toArray();
30
+
31
+ ctx.state.data = {
32
+ title: '十年之约——专题展示',
33
+ link: currentUrl,
34
+ item: items,
35
+ };
36
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ '/feeds': ['7Wate', 'a180285'],
3
+ };
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ 'foreverblog.cn': {
3
+ _name: '十年之约',
4
+ www: [
5
+ {
6
+ title: '专题展示',
7
+ docs: 'https://docs.rsshub.app/blog.html#shi-nian-zhi-yue',
8
+ source: ['/feeds.html'],
9
+ target: '/foreverblog/feeds',
10
+ },
11
+ ],
12
+ },
13
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = function (router) {
2
+ router.get('/feeds', require('./feeds'));
3
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ '/profile/:id': ['TonyRL'],
3
+ };
@@ -0,0 +1,61 @@
1
+ const got = require('@/utils/got');
2
+ const cheerio = require('cheerio');
3
+ const { parseDate } = require('@/utils/parse-date');
4
+ const timezone = require('@/utils/timezone');
5
+ const { fixArticleContent } = require('@/utils/wechat-mp');
6
+ const baseUrl = 'https://freewechat.com';
7
+
8
+ module.exports = async (ctx) => {
9
+ const { id } = ctx.params;
10
+ const url = `${baseUrl}/profile/${id}`;
11
+ const { data: response } = await got(url);
12
+ const $ = cheerio.load(response);
13
+ const author = $('h2').text().trim();
14
+
15
+ const list = $('.main')
16
+ .toArray()
17
+ .slice(0, -1) // last item is a template
18
+ .map((item) => {
19
+ item = $(item);
20
+ return {
21
+ title: item.find('a').text(),
22
+ author,
23
+ link: `${baseUrl}${item.find('a').attr('href')}`,
24
+ description: item.find('.preview').text(),
25
+ };
26
+ });
27
+
28
+ const items = await Promise.all(
29
+ list.map((item) =>
30
+ ctx.cache.tryGet(item.link, async () => {
31
+ const response = await got(item.link, {
32
+ headers: {
33
+ Referer: url,
34
+ },
35
+ });
36
+ const $ = cheerio.load(response.data);
37
+
38
+ $('.js_img_placeholder').remove();
39
+ $('amp-img').each((_, e) => {
40
+ e = $(e);
41
+ e.replaceWith(`<img src="${new URL(e.attr('src'), response.url).href}" width="${e.attr('width')}" height="${e.attr('height')}" decoding="async">`);
42
+ });
43
+ $('amp-video').each((_, e) => {
44
+ e = $(e);
45
+ e.replaceWith(`<video width="${e.attr('width')}" height="${e.attr('height')}" controls poster="${e.attr('poster')}">${e.html()}</video>`);
46
+ });
47
+
48
+ item.description = fixArticleContent($('#js_content'));
49
+ item.pubDate = timezone(parseDate($('#publish_time').text()), +8);
50
+ return item;
51
+ })
52
+ )
53
+ );
54
+
55
+ ctx.state.data = {
56
+ title: $('head title').text(),
57
+ link: url,
58
+ image: 'https://freewechat.com/favicon.ico',
59
+ item: items,
60
+ };
61
+ };
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ 'freewechat.com': {
3
+ _name: '自由微信',
4
+ '.': [
5
+ {
6
+ title: '公众号',
7
+ docs: 'https://docs.rsshub.app/new-media.html#zi-you-wei-xin',
8
+ source: ['/profile/:id'],
9
+ target: '/freewechat/profile/:id',
10
+ },
11
+ ],
12
+ },
13
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = (router) => {
2
+ router.get('/profile/:id', require('./profile'));
3
+ };
@@ -12,16 +12,26 @@ module.exports = async (ctx) => {
12
12
  const $ = cheerio.load(data);
13
13
  const feedTitle = $('title').text();
14
14
 
15
- const list = $('.original.am_card.original-normal')
16
- .map(function () {
15
+ let list;
16
+ if (category === 'news') {
17
+ list = $('a.news').map(function () {
18
+ const item = {
19
+ url: $(this).attr('href'),
20
+ title: $(this).find('.news_content>h3').text(),
21
+ };
22
+ return item;
23
+ });
24
+ } else {
25
+ list = $('.original.am_card.original-normal').map(function () {
17
26
  const item = {
18
27
  url: $(this).find('.am_card_inner>a').attr('href'),
19
28
  title: $(this).find('h3.am_card_title').text(),
20
29
  category: $(this).find('span.original_category>a').text(),
21
30
  };
22
31
  return item;
23
- })
24
- .get();
32
+ });
33
+ }
34
+ list = list.get();
25
35
 
26
36
  if (list.length > 0 && list.every((item) => item.url === undefined)) {
27
37
  throw new Error('Article URL not found! Please submit an issue on GitHub.');
@@ -85,13 +95,13 @@ module.exports = async (ctx) => {
85
95
  $('.story_hidden').replaceWith('');
86
96
 
87
97
  const content = $('.story.story-show').html();
88
- return {
98
+ const basicItem = {
89
99
  title: item.title,
90
100
  description: cover + content,
91
- category: item.category,
92
101
  link: articleUrl,
93
102
  guid: articleUrl,
94
103
  };
104
+ return category === 'news' ? basicItem : { ...basicItem, category: item.category };
95
105
  });
96
106
  })
97
107
  );