rsshub 1.0.0-master.ff3a9ce → 1.0.0-master.ff3ea5a

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.

Potentially problematic release.


This version of rsshub might be problematic. Click here for more details.

Files changed (388) hide show
  1. package/lib/config.ts +38 -0
  2. package/lib/errors/index.tsx +3 -2
  3. package/lib/middleware/debug.ts +6 -4
  4. package/lib/middleware/header.ts +4 -2
  5. package/lib/registry.test.ts +24 -1
  6. package/lib/registry.ts +40 -11
  7. package/lib/router.js +1 -1
  8. package/lib/routes/121/namespace.ts +9 -0
  9. package/lib/routes/121/templates/description.art +17 -0
  10. package/lib/routes/121/weather-live.ts +104 -0
  11. package/lib/routes/141jav/index.ts +3 -0
  12. package/lib/routes/141ppv/index.ts +3 -0
  13. package/lib/routes/163/news/rank.ts +1 -1
  14. package/lib/routes/18comic/album.ts +59 -64
  15. package/lib/routes/18comic/index.ts +1 -0
  16. package/lib/routes/18comic/search.ts +53 -4
  17. package/lib/routes/18comic/utils.ts +70 -1
  18. package/lib/routes/2048/index.ts +1 -0
  19. package/lib/routes/30secondsofcode/utils.ts +0 -1
  20. package/lib/routes/6park/index.ts +1 -1
  21. package/lib/routes/7mmtv/index.ts +1 -0
  22. package/lib/routes/91porn/index.ts +1 -0
  23. package/lib/routes/95mm/tab.ts +1 -0
  24. package/lib/routes/agefans/detail.ts +1 -1
  25. package/lib/routes/aliyun/database-month.ts +1 -1
  26. package/lib/routes/anthropic/research.ts +112 -0
  27. package/lib/routes/apnews/topics.ts +2 -1
  28. package/lib/routes/apnews/utils.ts +1 -1
  29. package/lib/routes/apple/design.ts +54 -0
  30. package/lib/routes/apple/namespace.ts +1 -1
  31. package/lib/routes/aqara/post.ts +1 -1
  32. package/lib/routes/augmentcode/blog.ts +161 -0
  33. package/lib/routes/augmentcode/namespace.ts +9 -0
  34. package/lib/routes/augmentcode/templates/description.art +17 -0
  35. package/lib/routes/azul/namespace.ts +9 -0
  36. package/lib/routes/azul/packages.ts +105 -0
  37. package/lib/routes/banshujiang/index.ts +763 -0
  38. package/lib/routes/banshujiang/namespace.ts +9 -0
  39. package/lib/routes/banshujiang/templates/description.art +17 -0
  40. package/lib/routes/bfl/announcements.ts +1 -1
  41. package/lib/routes/bilibili/cache.ts +78 -0
  42. package/lib/routes/bilibili/danmaku.ts +1 -1
  43. package/lib/routes/bilibili/dynamic.ts +8 -2
  44. package/lib/routes/bilibili/video.ts +31 -73
  45. package/lib/routes/biquge/index.ts +1 -1
  46. package/lib/routes/bsky/keyword.ts +15 -10
  47. package/lib/routes/capitalmind/insights.ts +40 -0
  48. package/lib/routes/capitalmind/namespace.ts +8 -0
  49. package/lib/routes/capitalmind/podcasts.ts +41 -0
  50. package/lib/routes/capitalmind/utils.ts +122 -0
  51. package/lib/routes/cartoonmad/comic.ts +1 -1
  52. package/lib/routes/chikubi/index.ts +1 -0
  53. package/lib/routes/chikubi/tag.ts +1 -0
  54. package/lib/routes/chocolatey/namespace.ts +9 -0
  55. package/lib/routes/chocolatey/packages.ts +122 -0
  56. package/lib/routes/cmde/index.ts +1 -1
  57. package/lib/routes/cockroachlabs/blog.ts +113 -0
  58. package/lib/routes/cockroachlabs/namespace.ts +7 -0
  59. package/lib/routes/cool18/index.ts +4 -1
  60. package/lib/routes/coomer/index.ts +12 -6
  61. package/lib/routes/coomer/namespace.ts +1 -1
  62. package/lib/routes/copymanga/comic.ts +7 -9
  63. package/lib/routes/css-tricks/articles.ts +48 -0
  64. package/lib/routes/css-tricks/collections.ts +62 -0
  65. package/lib/routes/css-tricks/namespace.ts +8 -0
  66. package/lib/routes/css-tricks/popular.ts +39 -0
  67. package/lib/routes/css-tricks/utils.ts +103 -0
  68. package/lib/routes/cursor/changelog.ts +26 -17
  69. package/lib/routes/cursor/namespace.ts +1 -1
  70. package/lib/routes/cw/utils.ts +6 -13
  71. package/lib/routes/dealstreetasia/home.ts +1 -1
  72. package/lib/routes/dedao/index.ts +3 -3
  73. package/lib/routes/deepl/blog.ts +422 -0
  74. package/lib/routes/deepl/namespace.ts +9 -0
  75. package/lib/routes/deepl/templates/description.art +21 -0
  76. package/lib/routes/deeplearning/the-batch.ts +1 -1
  77. package/lib/routes/dev.to/guides.ts +100 -0
  78. package/lib/routes/dev.to/namespace.ts +8 -0
  79. package/lib/routes/dev.to/top.ts +105 -0
  80. package/lib/routes/dgut/jwb.ts +73 -0
  81. package/lib/routes/dgut/namespace.ts +9 -0
  82. package/lib/routes/digitalpolicyalert/activity-tracker.ts +135 -0
  83. package/lib/routes/digitalpolicyalert/namespace.ts +9 -0
  84. package/lib/routes/dnaindia/common.ts +26 -8
  85. package/lib/routes/douban/other/list.ts +3 -3
  86. package/lib/routes/e-hentai/index.ts +4 -1
  87. package/lib/routes/ehentai/tag.ts +1 -0
  88. package/lib/routes/englishhome/index.ts +55 -0
  89. package/lib/routes/englishhome/namespace.ts +6 -0
  90. package/lib/routes/epicgames/index.ts +2 -2
  91. package/lib/routes/espn/news.ts +1 -1
  92. package/lib/routes/expats/czech-news.ts +272 -0
  93. package/lib/routes/expats/namespace.ts +9 -0
  94. package/lib/routes/fanbox/index.ts +1 -0
  95. package/lib/routes/fanbox/utils.ts +1 -1
  96. package/lib/routes/fansly/tag.ts +1 -0
  97. package/lib/routes/fantia/search.ts +1 -1
  98. package/lib/routes/fantube/creator.ts +69 -0
  99. package/lib/routes/fantube/namespace.ts +7 -0
  100. package/lib/routes/fantube/templates/post.art +17 -0
  101. package/lib/routes/fantube/types.ts +100 -0
  102. package/lib/routes/fantube/utils.ts +268 -0
  103. package/lib/routes/follow/profile.ts +1 -1
  104. package/lib/routes/followin/news.ts +1 -1
  105. package/lib/routes/foresightnews/util.ts +1 -1
  106. package/lib/routes/freexcomic/book.ts +4 -1
  107. package/lib/routes/gamer/hot.ts +5 -5
  108. package/lib/routes/gaoyu/blog.ts +145 -0
  109. package/lib/routes/gaoyu/namespace.ts +9 -0
  110. package/lib/routes/gaoyu/templates/description.art +7 -0
  111. package/lib/routes/geocaching/blogs.ts +2 -2
  112. package/lib/routes/github/namespace.ts +1 -1
  113. package/lib/routes/github/private-feed.ts +229 -0
  114. package/lib/routes/github/star.ts +1 -1
  115. package/lib/routes/google/extension.ts +9 -10
  116. package/lib/routes/gov/beijing/bphc/index.ts +1 -1
  117. package/lib/routes/gov/ccdi/index.ts +1 -1
  118. package/lib/routes/gov/chongqing/sydwgkzp.ts +22 -6
  119. package/lib/routes/gov/customs/list.ts +1 -1
  120. package/lib/routes/gov/general/general.ts +1 -1
  121. package/lib/routes/gov/hangzhou/zwfw.ts +1 -1
  122. package/lib/routes/gov/pbc/goutongjiaoliu.ts +1 -1
  123. package/lib/routes/gov/shenzhen/szlh/index.ts +77 -0
  124. package/lib/routes/gov/shenzhen/szlh/namespace.ts +8 -0
  125. package/lib/routes/grist/utils.ts +5 -4
  126. package/lib/routes/hanime1/search.ts +4 -2
  127. package/lib/routes/hellogithub/report.ts +1 -1
  128. package/lib/routes/hit/hitgs.ts +240 -54
  129. package/lib/routes/hit/templates/description.art +7 -0
  130. package/lib/routes/hlju/namespace.ts +8 -0
  131. package/lib/routes/hlju/news.ts +141 -0
  132. package/lib/routes/hostmonit/cloudflareyes.ts +1 -1
  133. package/lib/routes/hotukdeals/index.ts +1 -1
  134. package/lib/routes/hyperdash/namespace.ts +7 -0
  135. package/lib/routes/hyperdash/templates/description.art +34 -0
  136. package/lib/routes/hyperdash/top-traders.ts +84 -0
  137. package/lib/routes/hyperdash/utils.ts +49 -0
  138. package/lib/routes/hypergryph/arknights/announce.ts +1 -1
  139. package/lib/routes/ielts/index.ts +1 -1
  140. package/lib/routes/infoq/topic.ts +16 -13
  141. package/lib/routes/instagram/web-api/index.ts +17 -13
  142. package/lib/routes/instagram/web-api/utils.ts +46 -63
  143. package/lib/routes/jamesclear/book-summaries.ts +40 -0
  144. package/lib/routes/jamesclear/great-speeches.ts +40 -0
  145. package/lib/routes/jamesclear/namespace.ts +8 -0
  146. package/lib/routes/jamesclear/quotes.ts +40 -0
  147. package/lib/routes/jamesclear/three-two-one.ts +41 -0
  148. package/lib/routes/jamesclear/utils.ts +22 -0
  149. package/lib/routes/japanpost/utils.ts +2 -2
  150. package/lib/routes/javbus/index.ts +3 -0
  151. package/lib/routes/javdb/tags.ts +1 -0
  152. package/lib/routes/javlibrary/star.ts +1 -0
  153. package/lib/routes/javtiful/actress.ts +3 -0
  154. package/lib/routes/javtiful/channel.ts +3 -0
  155. package/lib/routes/javtrailers/casts.ts +3 -0
  156. package/lib/routes/jetbrains/comments.ts +99 -0
  157. package/lib/routes/jetbrains/namespace.ts +8 -0
  158. package/lib/routes/jimmyspa/books.ts +1 -1
  159. package/lib/routes/jimmyspa/news.ts +1 -1
  160. package/lib/routes/jpxgmn/tab.ts +3 -0
  161. package/lib/routes/kakuyomu/works.ts +3 -0
  162. package/lib/routes/kaopu/news.ts +1 -1
  163. package/lib/routes/kemono/const.ts +1 -1
  164. package/lib/routes/kemono/index.ts +12 -11
  165. package/lib/routes/kemono/namespace.ts +1 -1
  166. package/lib/routes/kiro/blog.ts +131 -0
  167. package/lib/routes/kiro/changelog.ts +128 -0
  168. package/lib/routes/kiro/namespace.ts +9 -0
  169. package/lib/routes/konachan/post.ts +3 -0
  170. package/lib/routes/kovidgoyal/kitty/changelog.ts +83 -0
  171. package/lib/routes/kovidgoyal/namespace.ts +7 -0
  172. package/lib/routes/kunchengblog/essay.ts +1 -1
  173. package/lib/routes/landiannews/category.ts +1 -1
  174. package/lib/routes/landiannews/index.ts +1 -1
  175. package/lib/routes/landiannews/tag.ts +1 -1
  176. package/lib/routes/line/utils.ts +1 -1
  177. package/lib/routes/lineageos/changes.ts +79 -0
  178. package/lib/routes/lineageos/namespace.ts +9 -0
  179. package/lib/routes/linkedin/cn/renderer.ts +1 -1
  180. package/lib/routes/liquipedia/cs-matches.ts +42 -14
  181. package/lib/routes/literotica/new.ts +1 -0
  182. package/lib/routes/lofter/tag.ts +27 -3
  183. package/lib/routes/makerworld/contest.ts +51 -0
  184. package/lib/routes/makerworld/namespace.ts +7 -0
  185. package/lib/routes/makerworld/trending.ts +45 -0
  186. package/lib/routes/makerworld/user-upload.ts +54 -0
  187. package/lib/routes/makerworld/utils.ts +18 -0
  188. package/lib/routes/manhuagui/comic.ts +1 -1
  189. package/lib/routes/manus/blog.ts +77 -0
  190. package/lib/routes/manus/namespace.ts +7 -0
  191. package/lib/routes/mastodon/tag.ts +48 -0
  192. package/lib/routes/mathpix/blog.ts +155 -0
  193. package/lib/routes/mathpix/namespace.ts +9 -0
  194. package/lib/routes/mathpix/templates/description.art +21 -0
  195. package/lib/routes/mckinsey/cn/category-map.ts +9 -15
  196. package/lib/routes/mckinsey/cn/index.ts +77 -40
  197. package/lib/routes/melonbooks/search.ts +1 -0
  198. package/lib/routes/metacritic/index.ts +2 -2
  199. package/lib/routes/meteoblue/namespace.ts +8 -0
  200. package/lib/routes/meteoblue/weathernews.ts +75 -0
  201. package/lib/routes/meteor/index.ts +1 -1
  202. package/lib/routes/microsoft/addon.ts +7 -9
  203. package/lib/routes/mihoyo/zzz/news.ts +106 -0
  204. package/lib/routes/missav/new.ts +2 -1
  205. package/lib/routes/mit/hanlab.ts +61 -0
  206. package/lib/routes/mit/namespace.ts +6 -0
  207. package/lib/routes/mittrchina/index.ts +3 -3
  208. package/lib/routes/mixcloud/config.ts +129 -0
  209. package/lib/routes/mixcloud/index.ts +163 -107
  210. package/lib/routes/mixcloud/user-playlist.ts +31 -0
  211. package/lib/routes/mixi2/community.ts +72 -0
  212. package/lib/routes/mixi2/discovery.ts +52 -0
  213. package/lib/routes/mixi2/home.ts +51 -0
  214. package/lib/routes/mixi2/namespace.ts +8 -0
  215. package/lib/routes/mixi2/user.ts +77 -0
  216. package/lib/routes/mixi2/utils.ts +56 -0
  217. package/lib/routes/modelscope/learn.ts +94 -0
  218. package/lib/routes/moodysmismicrosite/report.ts +1 -1
  219. package/lib/routes/musify/index.ts +130 -0
  220. package/lib/routes/musify/namespace.ts +9 -0
  221. package/lib/routes/musikguru/namespace.ts +9 -0
  222. package/lib/routes/musikguru/news.ts +146 -0
  223. package/lib/routes/musikguru/templates/description.art +21 -0
  224. package/lib/routes/myfans/post.ts +1 -0
  225. package/lib/routes/nankai/cc-notice.ts +114 -0
  226. package/lib/routes/nankai/jwc.ts +131 -0
  227. package/lib/routes/nankai/namespace.ts +7 -0
  228. package/lib/routes/nankai/notice.ts +84 -0
  229. package/lib/routes/nankai/yzb.ts +97 -0
  230. package/lib/routes/neu/yz.ts +172 -0
  231. package/lib/routes/newslaundry/explainer.ts +30 -0
  232. package/lib/routes/newslaundry/namespace.ts +8 -0
  233. package/lib/routes/newslaundry/nl-cheatsheet.ts +30 -0
  234. package/lib/routes/newslaundry/nl-collaborations.ts +30 -0
  235. package/lib/routes/newslaundry/podcast.ts +61 -0
  236. package/lib/routes/newslaundry/reports.ts +30 -0
  237. package/lib/routes/newslaundry/shot.ts +30 -0
  238. package/lib/routes/newslaundry/subscriber-only.ts +30 -0
  239. package/lib/routes/newslaundry/templates/description.art +28 -0
  240. package/lib/routes/newslaundry/utils.ts +108 -0
  241. package/lib/routes/newswav/latest.ts +100 -0
  242. package/lib/routes/newswav/namespace.ts +7 -0
  243. package/lib/routes/nhentai/index.ts +1 -0
  244. package/lib/routes/nifd/research.ts +16 -0
  245. package/lib/routes/nio/namespace.ts +9 -0
  246. package/lib/routes/nio/nioradio.ts +75 -0
  247. package/lib/routes/njust/cs.ts +58 -0
  248. package/lib/routes/njust/utils.ts +1 -1
  249. package/lib/routes/ntdm/video.ts +1 -1
  250. package/lib/routes/nuaa/utils/pypasswaf.ts +1 -1
  251. package/lib/routes/oilchem/index.ts +1 -1
  252. package/lib/routes/oncc/money18.ts +1 -1
  253. package/lib/routes/openai/cookbook.ts +1 -1
  254. package/lib/routes/paulgraham/article.ts +2 -2
  255. package/lib/routes/picuki/profile.ts +4 -0
  256. package/lib/routes/pixiv/bookmarks.ts +1 -1
  257. package/lib/routes/pixiv/novel-api/series/sfw.ts +1 -1
  258. package/lib/routes/pixiv/novels.ts +2 -2
  259. package/lib/routes/pixiv/user.ts +1 -1
  260. package/lib/routes/playno1/av.ts +1 -0
  261. package/lib/routes/pornhub/model.ts +3 -7
  262. package/lib/routes/pornhub/pornstar.ts +2 -7
  263. package/lib/routes/pornhub/users.ts +2 -7
  264. package/lib/routes/pornhub/utils.ts +12 -1
  265. package/lib/routes/qingting/podcast.ts +2 -1
  266. package/lib/routes/qipamaijia/index.ts +1 -0
  267. package/lib/routes/questmobile/report.ts +1 -1
  268. package/lib/routes/railway/index.ts +73 -0
  269. package/lib/routes/railway/namespace.ts +8 -0
  270. package/lib/routes/reuters/common.ts +0 -3
  271. package/lib/routes/rockthejvm/articles.ts +167 -0
  272. package/lib/routes/rockthejvm/namespace.ts +9 -0
  273. package/lib/routes/rockthejvm/templates/description.art +7 -0
  274. package/lib/routes/samrdprc/namespace.ts +7 -0
  275. package/lib/routes/samrdprc/news.ts +79 -0
  276. package/lib/routes/sankei/namespace.ts +7 -0
  277. package/lib/routes/sankei/news.ts +68 -0
  278. package/lib/routes/sankei/topics.ts +71 -0
  279. package/lib/routes/sciencenet/user.ts +1 -1
  280. package/lib/routes/scoop/apps.ts +188 -0
  281. package/lib/routes/scoop/namespace.ts +9 -0
  282. package/lib/routes/scoop/templates/description.art +56 -0
  283. package/lib/routes/scpta/namespace.ts +8 -0
  284. package/lib/routes/scpta/news.ts +101 -0
  285. package/lib/routes/seekingalpha/index.ts +1 -1
  286. package/lib/routes/sehuatang/index.ts +29 -31
  287. package/lib/routes/setn/index.ts +11 -2
  288. package/lib/routes/seu/cyber/index.ts +78 -0
  289. package/lib/routes/sicau/jiaowu.ts +42 -34
  290. package/lib/routes/sis001/forum.ts +1 -0
  291. package/lib/routes/sjtu/seiee/icisee.ts +67 -0
  292. package/lib/routes/sketis/isabelle-dev/blog/index.ts +1 -1
  293. package/lib/routes/smartlink/index.ts +13 -3
  294. package/lib/routes/sohu/mp.ts +17 -6
  295. package/lib/routes/sotwe/namespace.ts +1 -0
  296. package/lib/routes/sotwe/user.ts +98 -0
  297. package/lib/routes/spankbang/new-videos.ts +1 -0
  298. package/lib/routes/spglobal/ratings.ts +1 -1
  299. package/lib/routes/stanford/blog.ts +77 -0
  300. package/lib/routes/stanford/namespace.ts +7 -0
  301. package/lib/routes/syosetu/index.ts +1 -1
  302. package/lib/routes/t66y/index.ts +1 -0
  303. package/lib/routes/taobao/mysql.ts +157 -0
  304. package/lib/routes/taobao/namespace.ts +2 -2
  305. package/lib/routes/techcrunch/category.ts +48 -0
  306. package/lib/routes/telegram/channel.ts +2 -2
  307. package/lib/routes/tesla/cx.ts +1 -1
  308. package/lib/routes/test/index.ts +1 -1
  309. package/lib/routes/themoviedb/episodes.ts +1 -1
  310. package/lib/routes/thewirehindi/category.ts +78 -0
  311. package/lib/routes/thewirehindi/index.ts +43 -0
  312. package/lib/routes/thewirehindi/namespace.ts +7 -0
  313. package/lib/routes/thewirehindi/templates/description.art +9 -0
  314. package/lib/routes/thewirehindi/utils.ts +33 -0
  315. package/lib/routes/threads/utils.ts +2 -2
  316. package/lib/routes/tidb/blog.ts +314 -0
  317. package/lib/routes/tidb/namespace.ts +9 -0
  318. package/lib/routes/tumblr/namespace.ts +17 -0
  319. package/lib/routes/tumblr/posts.ts +74 -0
  320. package/lib/routes/tumblr/utils.ts +110 -0
  321. package/lib/routes/tver/namespace.ts +7 -0
  322. package/lib/routes/tver/series.ts +98 -0
  323. package/lib/routes/twitter/api/web-api/login.ts +1 -3
  324. package/lib/routes/twitter/api/web-api/utils.ts +23 -1
  325. package/lib/routes/twitter/utils.ts +21 -21
  326. package/lib/routes/udn/breaking-news.ts +2 -2
  327. package/lib/routes/uestc/auto.ts +1 -1
  328. package/lib/routes/uestc/cqe.ts +1 -1
  329. package/lib/routes/uestc/scse.ts +1 -1
  330. package/lib/routes/uestc/sice.ts +1 -1
  331. package/lib/routes/uestc/sise.ts +1 -1
  332. package/lib/routes/upc/jwc.ts +32 -46
  333. package/lib/routes/uptimerobot/rss.ts +1 -1
  334. package/lib/routes/visionias/daily-news-summary.ts +65 -0
  335. package/lib/routes/visionias/monthly-magazine.ts +68 -0
  336. package/lib/routes/visionias/news-today.ts +3 -13
  337. package/lib/routes/visionias/utils.ts +5 -5
  338. package/lib/routes/visionias/weekly-focus.ts +2 -2
  339. package/lib/routes/wdfxw/bookfree.ts +528 -0
  340. package/lib/routes/wdfxw/namespace.ts +8 -0
  341. package/lib/routes/wdfxw/templates/description.art +13 -0
  342. package/lib/routes/whu/swrh.ts +1 -1
  343. package/lib/routes/windsurf/blog.ts +118 -0
  344. package/lib/routes/windsurf/changelog.ts +100 -0
  345. package/lib/routes/windsurf/namespace.ts +9 -0
  346. package/lib/routes/windsurf/templates/description.art +21 -0
  347. package/lib/routes/x6d/index.ts +1 -1
  348. package/lib/routes/xbookcn/blog.ts +1 -0
  349. package/lib/routes/xiaohongshu/util.ts +1 -3
  350. package/lib/routes/xiaoyuzhou/pickup.ts +1 -1
  351. package/lib/routes/ximalaya/album.ts +32 -70
  352. package/lib/routes/ximalaya/types.ts +48 -0
  353. package/lib/routes/ximalaya/utils.ts +9 -7
  354. package/lib/routes/xmanhua/index.ts +1 -0
  355. package/lib/routes/xueqiu/cookies.ts +1 -1
  356. package/lib/routes/xueqiu/user.ts +1 -1
  357. package/lib/routes/xwenming/index.ts +184 -0
  358. package/lib/routes/xwenming/namespace.ts +9 -0
  359. package/lib/routes/yahoo/news/utils.ts +1 -1
  360. package/lib/routes/yande/post.ts +3 -0
  361. package/lib/routes/ymgal/game.ts +1 -0
  362. package/lib/routes/youtube/api/google.ts +27 -0
  363. package/lib/routes/youtube/api/youtubei.ts +70 -20
  364. package/lib/routes/youtube/community.ts +3 -1
  365. package/lib/routes/youtube/utils.ts +16 -14
  366. package/lib/routes/zaobao/util.ts +8 -5
  367. package/lib/routes/zhihu/activities.ts +3 -0
  368. package/lib/routes/zhihu/execlib/x-zse-96-v3.ts +5 -5
  369. package/lib/routes/zhizhuan100/namespace.ts +7 -0
  370. package/lib/routes/zhizhuan100/report.ts +79 -0
  371. package/lib/routes/zimuxia/portfolio.ts +1 -1
  372. package/lib/routes/zju/sis/index.ts +161 -0
  373. package/lib/server.ts +5 -0
  374. package/lib/types.ts +58 -54
  375. package/lib/utils/helpers.ts +1 -1
  376. package/lib/utils/logger.ts +1 -1
  377. package/lib/utils/proxy/index.ts +102 -18
  378. package/lib/utils/proxy/multi-proxy.ts +139 -0
  379. package/lib/utils/proxy/unify-proxy.ts +3 -1
  380. package/lib/utils/puppeteer-utils.test.ts +1 -1
  381. package/lib/utils/puppeteer.test.ts +14 -27
  382. package/lib/utils/puppeteer.ts +51 -37
  383. package/lib/utils/readable-social.test.ts +65 -0
  384. package/lib/utils/readable-social.ts +15 -1
  385. package/lib/utils/request-rewriter/fetch.ts +42 -4
  386. package/package.json +54 -56
  387. package/lib/routes/mixcloud/queries.ts +0 -2274
  388. package/lib/routes-deprecated/dev.to/top.js +0 -40
@@ -0,0 +1,68 @@
1
+ import { Route, Data, DataItem } from '@/types';
2
+
3
+ import cache from '@/utils/cache';
4
+ import got from '@/utils/got';
5
+ import { load } from 'cheerio';
6
+ import { parseDate } from '@/utils/parse-date';
7
+ import { Context } from 'hono';
8
+
9
+ export const route: Route = {
10
+ path: '/news/:category',
11
+ categories: ['traditional-media'],
12
+ example: '/sankei/news/flash',
13
+ parameters: { category: 'Category name (as it will appear in URLs). For example, for "Breaking News" https://www.sankei.com/flash/, the category name would be "flash".' },
14
+ radar: [
15
+ {
16
+ source: ['www.sankei.com/:category'],
17
+ target: '/news/:category',
18
+ },
19
+ ],
20
+ name: 'News',
21
+ maintainers: ['yuikisaito'],
22
+ handler,
23
+ };
24
+
25
+ async function handler(ctx: Context): Promise<Data> {
26
+ const baseUrl = 'https://www.sankei.com';
27
+ const { category } = ctx.req.param();
28
+ const url = `${baseUrl}/${category}/`;
29
+
30
+ const response = await got(url);
31
+ const $ = load(response.body);
32
+ const categoryName = $('header.story-card-header:first-of-type > h1').text();
33
+ const listSelector = $('div.story-card-feed.grid.hide_on_mobile > div > article');
34
+
35
+ const items: DataItem[] = await Promise.all(
36
+ listSelector.toArray().map((el) => {
37
+ const item = $(el);
38
+ item.find('p a').remove();
39
+
40
+ const title = item.find('div.story-card-flex > h2.headline > a').text();
41
+ const link = baseUrl + (item.find('div.story-card-flex > h2.headline > a').attr('href') || '');
42
+ const pubDate = parseDate(item.find('div.story-card-flex > div > time').attr('datetime') || '');
43
+
44
+ return cache.tryGet(link, async () => {
45
+ const detail = await got(link);
46
+ const $ = load(detail.body);
47
+ $('.inline-gptAd, .figure_image_sizer').remove();
48
+ const articleHTML = $('div.article-body').html() || '';
49
+
50
+ return {
51
+ title,
52
+ link,
53
+ pubDate,
54
+ description: articleHTML,
55
+ };
56
+ });
57
+ })
58
+ );
59
+
60
+ return {
61
+ title: '産経ニュース - ' + categoryName,
62
+ description: $('meta[name="description"]').attr('content'),
63
+ link: url,
64
+ image: $('meta[property="og:image"]').attr('content'),
65
+ language: 'ja',
66
+ item: items,
67
+ };
68
+ }
@@ -0,0 +1,71 @@
1
+ import { Route, Data, DataItem } from '@/types';
2
+
3
+ import cache from '@/utils/cache';
4
+ import got from '@/utils/got';
5
+ import { load } from 'cheerio';
6
+ import { parseDate } from '@/utils/parse-date';
7
+ import { Context } from 'hono';
8
+
9
+ export const route: Route = {
10
+ path: ['/topics/:topic'],
11
+ categories: ['traditional-media'],
12
+ example: '/sankei/topics/etc_100',
13
+ parameters: {
14
+ topic: 'Topic name (format included in URL). For example, for "Expo 2025 Osaka, Kansai, Japan Special Feature" https://www.sankei.com/tag/topic/etc_100, the value would be etc_100.',
15
+ },
16
+ radar: [
17
+ {
18
+ source: ['www.sankei.com/tag/topic/:topic'],
19
+ target: '/topics/:topic',
20
+ },
21
+ ],
22
+ name: 'Topic',
23
+ maintainers: ['yuikisaito'],
24
+ handler,
25
+ };
26
+
27
+ async function handler(ctx: Context): Promise<Data> {
28
+ const baseUrl = 'https://www.sankei.com';
29
+ const { topic } = ctx.req.param();
30
+ const url = `${baseUrl}/tag/topic/${topic}/`;
31
+
32
+ const response = await got(url);
33
+ const $ = load(response.body);
34
+ const categoryName = $('li.breadcrumb-list-item:nth-of-type(3) > a').text();
35
+
36
+ const listSelector = $('div.story-card-feed.grid.hide_on_mobile > div > article');
37
+
38
+ const items: DataItem[] = await Promise.all(
39
+ listSelector.toArray().map((el) => {
40
+ const item = $(el);
41
+ item.find('p a').remove();
42
+
43
+ const title = item.find('div.story-card-flex > h3.headline > a').text();
44
+ const link = baseUrl + (item.find('div.story-card-flex > h3.headline > a').attr('href') || '');
45
+ const pubDate = parseDate(item.find('div.story-card-flex > div > time').attr('datetime') || '');
46
+
47
+ return cache.tryGet(link, async () => {
48
+ const detail = await got(link);
49
+ const $ = load(detail.body);
50
+ $('.inline-gptAd, .figure_image_sizer').remove();
51
+ const articleHTML = $('div.article-body').html() || '';
52
+
53
+ return {
54
+ title,
55
+ link,
56
+ pubDate,
57
+ description: articleHTML,
58
+ };
59
+ });
60
+ })
61
+ );
62
+
63
+ return {
64
+ title: '産経ニュース - ' + categoryName,
65
+ description: $('meta[name="description"]').attr('content'),
66
+ link: url,
67
+ image: $('meta[property="og:image"]').attr('content'),
68
+ language: 'ja',
69
+ item: items,
70
+ };
71
+ }
@@ -54,7 +54,7 @@ async function handler(ctx) {
54
54
  let items = $('item')
55
55
  .slice(-limit)
56
56
  .toArray()
57
- .reverse()
57
+ .toReversed()
58
58
  .map((item) => {
59
59
  item = $(item);
60
60
 
@@ -0,0 +1,188 @@
1
+ import { type Data, type DataItem, type Route, ViewType } from '@/types';
2
+
3
+ import { art } from '@/utils/render';
4
+ import ofetch from '@/utils/ofetch';
5
+ import { parseDate } from '@/utils/parse-date';
6
+
7
+ import { type CheerioAPI, load } from 'cheerio';
8
+ import { type Context } from 'hono';
9
+ import path from 'node:path';
10
+
11
+ const orderbys = (desc: string) => {
12
+ const base = {
13
+ 0: 'search.score() desc, Metadata/OfficialRepositoryNumber desc, NameSortable asc',
14
+ 1: 'NameSortable asc, Metadata/OfficialRepositoryNumber desc, Metadata/RepositoryStars desc, Metadata/Committed desc',
15
+ 2: 'Metadata/Committed desc, Metadata/OfficialRepositoryNumber desc, Metadata/RepositoryStars desc',
16
+ };
17
+
18
+ if (desc === '1') {
19
+ return base;
20
+ }
21
+
22
+ const inverted = {};
23
+ for (const key in base) {
24
+ const orderStr = base[key];
25
+ inverted[key] = orderStr.replaceAll(/\b(desc|asc)\b/gi, (match) => (match.toLowerCase() === 'desc' ? 'asc' : 'desc'));
26
+ }
27
+ return inverted;
28
+ };
29
+
30
+ const filters = {
31
+ o: 'Metadata/OfficialRepositoryNumber eq 1', // offical buckets only
32
+ dm: 'Metadata/DuplicateOf eq null', // distinct manifests only
33
+ };
34
+
35
+ export const handler = async (ctx: Context): Promise<Data> => {
36
+ const { query = 's=2&d=1&n=true&dm=true&o=true' } = ctx.req.param();
37
+ const limit: number = Number.parseInt(ctx.req.query('limit') ?? '50', 10);
38
+
39
+ const baseUrl: string = 'https://scoop.sh';
40
+ const apiBaseUrl: string = 'https://scoopsearch.search.windows.net';
41
+ const targetUrl: string = new URL(`/#/apps?${query}`, baseUrl).href;
42
+ const apiUrl: string = new URL('indexes/apps/docs/search', apiBaseUrl).href;
43
+
44
+ const targetResponse = await ofetch(targetUrl);
45
+ const $: CheerioAPI = load(targetResponse);
46
+ const language = $('html').attr('lang') ?? 'en';
47
+
48
+ const scriptRegExp: RegExp = /<script type="module" crossorigin src="(.*?)"><\/script>/;
49
+ const scriptUrl: string = scriptRegExp.test(targetResponse) ? new URL(targetResponse.match(scriptRegExp)?.[1], baseUrl).href : '';
50
+
51
+ if (!scriptUrl) {
52
+ throw new Error('JavaScript file not found.');
53
+ }
54
+
55
+ const scriptResponse = await ofetch(scriptUrl, {
56
+ parseResponse: (txt) => txt,
57
+ });
58
+
59
+ const key: string = scriptResponse.match(/VITE_APP_AZURESEARCH_KEY:"(.*?)"/)?.[1];
60
+
61
+ if (!key) {
62
+ throw new Error('Key not found.');
63
+ }
64
+
65
+ const isOffcial: boolean = !query.includes('o=false');
66
+ const isDistinct: boolean = !query.includes('dm=false');
67
+ const sort: string = query.match(/s=(\d+)/)?.[1] ?? '2';
68
+ const desc: string = query.match(/d=(\d+)/)?.[1] ?? '1';
69
+
70
+ const response = await ofetch(apiUrl, {
71
+ method: 'post',
72
+ query: {
73
+ 'api-version': '2020-06-30',
74
+ },
75
+ headers: {
76
+ 'api-key': key,
77
+ origin: baseUrl,
78
+ referer: baseUrl,
79
+ },
80
+ body: {
81
+ count: true,
82
+ search: '',
83
+ searchMode: 'all',
84
+ filter: [isOffcial ? filters.o : undefined, isDistinct ? filters.dm : undefined].filter(Boolean).join(' and '),
85
+ orderby: orderbys(desc)[sort],
86
+ skip: 0,
87
+ top: limit,
88
+ select: 'Id,Name,NamePartial,NameSuffix,Description,Notes,Homepage,License,Version,Metadata/Repository,Metadata/FilePath,Metadata/OfficialRepository,Metadata/RepositoryStars,Metadata/Committed,Metadata/Sha',
89
+ highlight: 'Name,NamePartial,NameSuffix,Description,Version,License,Metadata/Repository',
90
+ highlightPreTag: '<mark>',
91
+ highlightPostTag: '</mark>',
92
+ },
93
+ });
94
+
95
+ let items: DataItem[] = [];
96
+
97
+ items = response.value.slice(0, limit).map((item): DataItem => {
98
+ const repositorySplits: string[] = item.Metadata.Repository.split(/\//);
99
+ const repositoryName: string = repositorySplits.slice(-2).join('/');
100
+ const title: string = `${item.Name} ${item.Version} in ${repositoryName}`;
101
+ const description: string | undefined = art(path.join(__dirname, 'templates/description.art'), {
102
+ item,
103
+ });
104
+ const pubDate: number | string = item.Metadata.Committed;
105
+ const linkUrl: string | undefined = item.Homepage;
106
+ const authors: DataItem['author'] = [
107
+ {
108
+ name: repositoryName,
109
+ url: item.Metadata.Repository,
110
+ avatar: undefined,
111
+ },
112
+ ];
113
+ const guid: string = `scoop-${item.Name}-${item.Version}-${item.Metadata.Sha}`;
114
+ const updated: number | string = pubDate;
115
+
116
+ const processedItem: DataItem = {
117
+ title,
118
+ description,
119
+ pubDate: pubDate ? parseDate(pubDate) : undefined,
120
+ link: linkUrl,
121
+ author: authors,
122
+ guid,
123
+ id: guid,
124
+ content: {
125
+ html: description,
126
+ text: description,
127
+ },
128
+ updated: updated ? parseDate(updated) : undefined,
129
+ language,
130
+ };
131
+
132
+ return processedItem;
133
+ });
134
+
135
+ const author: string = 'Scoop';
136
+
137
+ return {
138
+ title: `${author} - Apps`,
139
+ description: undefined,
140
+ link: targetUrl,
141
+ item: items,
142
+ allowEmpty: true,
143
+ author,
144
+ language,
145
+ id: targetUrl,
146
+ };
147
+ };
148
+
149
+ export const route: Route = {
150
+ path: '/apps/:query?',
151
+ name: 'Apps',
152
+ url: 'scoop.sh',
153
+ maintainers: ['nczitzk'],
154
+ handler,
155
+ example: '/scoop/apps',
156
+ parameters: {
157
+ query: {
158
+ description: 'Query, `s=2&d=1&n=true&dm=true&o=true` by default',
159
+ },
160
+ },
161
+ description: `:::tip
162
+ To subscribe to [Apps](https://scoop.sh/#/apps?s=2&d=1&n=true&dm=true&o=true), where the source URL is \`https://scoop.sh/#/apps?s=2&d=1&n=true&dm=true&o=true\`, extract the certain parts from this URL to be used as parameters, resulting in the route as [\`/scoop/apps/s=2&d=1&n=true&dm=true&o=true\`](https://rsshub.app/scoop/apps/s=2&d=1&n=true&dm=true&o=true).
163
+
164
+ :::
165
+ `,
166
+ categories: ['program-update'],
167
+ features: {
168
+ requireConfig: false,
169
+ requirePuppeteer: false,
170
+ antiCrawler: false,
171
+ supportRadar: true,
172
+ supportBT: false,
173
+ supportPodcast: false,
174
+ supportScihub: false,
175
+ },
176
+ radar: [
177
+ {
178
+ source: ['scoop.sh/#/apps', 'scoop.sh'],
179
+ target: (_, url) => {
180
+ const urlObj: URL = new URL(url);
181
+ const query: string | undefined = urlObj.searchParams.toString() ?? undefined;
182
+
183
+ return `/scoop/apps${query ? `/${query}` : ''}`;
184
+ },
185
+ },
186
+ ],
187
+ view: ViewType.Notifications,
188
+ };
@@ -0,0 +1,9 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: 'Scoop',
5
+ url: 'scoop.sh',
6
+ categories: ['program-update'],
7
+ description: '',
8
+ lang: 'en',
9
+ };
@@ -0,0 +1,56 @@
1
+ {{ if item }}
2
+ <table>
3
+ <tbody>
4
+ {{ if item.Name }}
5
+ <tr>
6
+ <th>Name</th>
7
+ <td>{{ item.Name }}</td>
8
+ </tr>
9
+ {{ /if }}
10
+ {{ if item.Repository }}
11
+ <tr>
12
+ <th>Repository</th>
13
+ <td>
14
+ <a href="{{ item.Metadata.Repository }}">{{ item.Metadata.Repository.split(/\//).slice(-2).join('/') }}</a>
15
+ </td>
16
+ </tr>
17
+ {{ /if }}
18
+ {{ if item.Committed }}
19
+ <tr>
20
+ <th>Committed</th>
21
+ <td><a href="{{ item.Metadata.Repository }}/commit/{{ item.Metadata.Sha }}">{{ item.Metadata.Committed }}</a></td>
22
+ </tr>
23
+ {{ /if }}
24
+ {{ if item.Version }}
25
+ <tr>
26
+ <th>Version</th>
27
+ <td><a href="{{ item.Metadata.Repository }}/blob/{{ item.Metadata.FilePath }}">v{{ item.Version }}</a></td>
28
+ </tr>
29
+ {{ /if }}
30
+ {{ if item.Description }}
31
+ <tr>
32
+ <th>Description</th>
33
+ <td>{{ item.Description }}</td>
34
+ </tr>
35
+ {{ /if }}
36
+ {{ if item.Homepage }}
37
+ </tr>
38
+ <th>Homepage</th>
39
+ <td><a href="{{ item.Homepage }}">{{ item.Homepage }}</a></td>
40
+ </tr>
41
+ {{ /if }}
42
+ {{ if item.License }}
43
+ <tr>
44
+ <th>License</th>
45
+ <td>{{ item.License }}</td>
46
+ </tr>
47
+ {{ /if }}
48
+ {{ if item.Note }}
49
+ <tr>
50
+ <th>Note</th>
51
+ <td>{{ item.Note }}</td>
52
+ </tr>
53
+ {{ /if }}
54
+ </tbody>
55
+ </table>
56
+ {{ /if }}
@@ -0,0 +1,8 @@
1
+ import type { Namespace } from '@/types';
2
+
3
+ export const namespace: Namespace = {
4
+ name: '四川省人力资源和社会保障厅人事考试专栏',
5
+ url: 'www.scpta.com.cn',
6
+ categories: ['government'],
7
+ lang: 'zh-CN',
8
+ };
@@ -0,0 +1,101 @@
1
+ import { Route } from '@/types';
2
+ import got from '@/utils/got';
3
+ import { load } from 'cheerio';
4
+ import { parseDate } from '@/utils/parse-date';
5
+ import cache from '@/utils/cache';
6
+
7
+ export const route: Route = {
8
+ path: '/news/:category',
9
+ categories: ['government'],
10
+ example: '/scpta/news/33',
11
+ parameters: {
12
+ category: {
13
+ description: '分类ID,默认为`33`(工作动态)',
14
+ default: '33',
15
+ },
16
+ },
17
+ features: {
18
+ requireConfig: false,
19
+ requirePuppeteer: false,
20
+ antiCrawler: false,
21
+ supportBT: false,
22
+ supportPodcast: false,
23
+ supportScihub: false,
24
+ },
25
+ radar: [
26
+ {
27
+ source: ['www.scpta.com.cn/front/News/List'],
28
+ target: '/news',
29
+ },
30
+ ],
31
+ name: '通知公告',
32
+ maintainers: ['Yeye-0426'], // github ID
33
+ handler,
34
+ description: `| 分类 | category_id |
35
+ |----------------------|-------------|
36
+ | 工作动态 | 33 |
37
+ | 公务员考试 | 56 |
38
+ | 专业技术人员资格考试 | 57 |
39
+ | 事业单位考试 | 67 |
40
+ | 其它 | 72 |`,
41
+ };
42
+
43
+ async function handler(ctx) {
44
+ const category = ctx.req.param('category');
45
+ const baseUrl = 'https://www.scpta.com.cn';
46
+
47
+ // 构建请求URL
48
+ const url = `${baseUrl}/front/News/List/${category}`;
49
+
50
+ // 发送请求
51
+ const response = await got(url);
52
+
53
+ const $ = load(response.data);
54
+
55
+ // 解析搜索结果
56
+ const list = $('div.wrap-content li')
57
+ .toArray()
58
+ .map((item) => {
59
+ item = $(item);
60
+ return {
61
+ title: item.find('a').attr('title'),
62
+ link: `${baseUrl}${item.find('a').attr('href')}`,
63
+ pubDate: parseDate(item.find('span').text().trim()),
64
+ };
65
+ });
66
+ // 获取公告详情
67
+ const items = await Promise.all(
68
+ list.map((item) =>
69
+ cache.tryGet(item.link, async () => {
70
+ let description = '';
71
+ try {
72
+ const contentResponse = await got(item.link);
73
+ const content = load(contentResponse.data);
74
+
75
+ // 提取公告正文
76
+ description = content('div.wrap-content.news-content').html();
77
+ } catch {
78
+ // 如果详情页获取失败,使用默认描述
79
+ description = '公告内容获取失败';
80
+ }
81
+ item.description = description;
82
+ return item;
83
+ })
84
+ )
85
+ );
86
+
87
+ // 生成RSS输出
88
+ const categoryNames = {
89
+ '33': '工作动态',
90
+ '56': '公务员考试',
91
+ '57': '专业技术人员资格考试',
92
+ '67': '事业单位考试',
93
+ '72': '其它',
94
+ };
95
+
96
+ return {
97
+ title: `通知公告 - ${categoryNames[category] || '未知分类'}`,
98
+ link: url,
99
+ item: items,
100
+ };
101
+ }
@@ -64,7 +64,7 @@ async function handler(ctx) {
64
64
  'filter[until]': 0,
65
65
  id: symbol.toLowerCase(),
66
66
  include: 'author,primaryTickers,secondaryTickers,sentiments',
67
- 'page[size]': ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : (category === 'news' ? 40 : 20),
67
+ 'page[size]': ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : category === 'news' ? 40 : 20,
68
68
  'page[number]': 1,
69
69
  },
70
70
  });
@@ -1,10 +1,10 @@
1
1
  import { Route } from '@/types';
2
2
  import cache from '@/utils/cache';
3
+ import ofetch from '@/utils/ofetch';
3
4
  import { load } from 'cheerio';
4
5
  import { parseDate } from '@/utils/parse-date';
5
6
  import timezone from '@/utils/timezone';
6
- import logger from '@/utils/logger';
7
- import puppeteer from '@/utils/puppeteer';
7
+ import { config } from '@/config';
8
8
 
9
9
  const host = 'https://www.sehuatang.net/';
10
10
 
@@ -42,10 +42,10 @@ export const route: Route = {
42
42
  path: ['/bt/:subforumid?', '/picture/:subforumid', '/:subforumid?/:type?', '/:subforumid?', ''],
43
43
  name: 'Forum',
44
44
  maintainers: ['qiwihui', 'junfengP', 'nczitzk'],
45
+ handler,
45
46
  features: {
46
- requirePuppeteer: true,
47
+ nsfw: true,
47
48
  },
48
- handler,
49
49
  description: `**原创 BT 电影**
50
50
 
51
51
  | 国产原创 | 亚洲无码原创 | 亚洲有码原创 | 高清中文字幕 | 三级写真 | VR 视频 | 素人有码 | 欧美无码 | 韩国主播 | 动漫原创 | 综合讨论 |
@@ -59,29 +59,34 @@ export const route: Route = {
59
59
  | yczp | ztzp | hrjp | yzxa | omxa | ktdm | ttxz |`,
60
60
  };
61
61
 
62
+ const getSafeId = () =>
63
+ cache.tryGet(
64
+ 'sehuatang:safeid',
65
+ async () => {
66
+ const response = await ofetch(host);
67
+ const $ = load(response);
68
+ const safeId = $('script:contains("safeid")')
69
+ .text()
70
+ .match(/safeid\s*=\s*'(.+)';/)?.[1];
71
+ return safeId;
72
+ },
73
+ config.cache.routeExpire,
74
+ false
75
+ );
76
+
62
77
  async function handler(ctx) {
63
78
  const subformName = ctx.req.param('subforumid') ?? 'gqzwzm';
64
79
  const subformId = subformName in forumIdMaps ? forumIdMaps[subformName] : subformName;
65
80
  const type = ctx.req.param('type');
66
81
  const typefilter = type ? `&filter=typeid&typeid=${type}` : '';
67
82
  const link = `${host}forum.php?mod=forumdisplay&orderby=dateline&fid=${subformId}${typefilter}`;
83
+ const headers = {
84
+ Cookie: `_safe=${await getSafeId()};`,
85
+ };
68
86
 
69
- const browser = await puppeteer();
70
- const page = await browser.newPage();
71
- await page.setRequestInterception(true);
72
- page.on('request', (request) => {
73
- request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
74
- });
75
- logger.http(`Requesting ${link}`);
76
- await page.goto(link, {
77
- waitUntil: 'domcontentloaded',
87
+ const response = await ofetch(link, {
88
+ headers,
78
89
  });
79
- await page.waitForSelector('a.enter-btn', { visible: true });
80
-
81
- await Promise.all([page.click('a.enter-btn'), page.waitForNavigation({ waitUntil: 'domcontentloaded' })]);
82
- const response = await page.content();
83
- await page.close();
84
-
85
90
  const $ = load(response);
86
91
 
87
92
  const list = $('#threadlisttableid tbody[id^=normalthread]')
@@ -101,20 +106,12 @@ async function handler(ctx) {
101
106
  const out = await Promise.all(
102
107
  list.map((info) =>
103
108
  cache.tryGet(info.link, async () => {
104
- const page = await browser.newPage();
105
- await page.setRequestInterception(true);
106
- page.on('request', (request) => {
107
- request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
109
+ const response = await ofetch(info.link, {
110
+ headers,
108
111
  });
109
112
 
110
- await page.goto(info.link, {
111
- // 指定页面等待载入的时间
112
- waitUntil: 'domcontentloaded',
113
- });
114
- const response = await page.content();
115
- await page.close();
116
113
  const $ = load(response);
117
- const postMessage = $("td[id^='postmessage']").slice(0, 1);
114
+ const postMessage = $('div[id^="postmessage"], td[id^="postmessage"]').slice(0, 1);
118
115
  const images = $(postMessage).find('img');
119
116
  for (const image of images) {
120
117
  const file = $(image).attr('file');
@@ -151,11 +148,12 @@ async function handler(ctx) {
151
148
  info.enclosure_url = enclosureUrl;
152
149
  info.enclosure_type = isMag ? 'application/x-bittorrent' : 'application/octet-stream';
153
150
  }
151
+
154
152
  return info;
155
153
  })
156
154
  )
157
155
  );
158
- await browser.close();
156
+
159
157
  return {
160
158
  title: `色花堂 - ${$('#pt > div:nth-child(1) > a:last-child').text()}`,
161
159
  link,
@@ -2,6 +2,7 @@ import { Route } from '@/types';
2
2
  import cache from '@/utils/cache';
3
3
  import got from '@/utils/got';
4
4
  import { load } from 'cheerio';
5
+ import timezone from '@/utils/timezone';
5
6
  import { parseDate } from '@/utils/parse-date';
6
7
 
7
8
  const defaultRootUrl = 'https://www.setn.com';
@@ -118,11 +119,19 @@ async function handler(ctx) {
118
119
 
119
120
  const content = load(detailResponse.data);
120
121
 
122
+ let head = {};
123
+ try {
124
+ head = JSON.parse(content('script[type="application/ld+json"]').first().text());
125
+ } catch {
126
+ head = {};
127
+ }
128
+
121
129
  content('#gad_setn_innity_oop_1x1').remove();
122
130
 
123
- item.author = content('meta[property="author"]').attr('content');
131
+ item.title = content('h1').text();
132
+ item.author = head?.author?.name || content('meta[name="author"]').attr('content');
124
133
  item.category = [content('meta[property="article:section"]').attr('content'), ...content('meta[name="news_keywords"]').attr('content').split(',')];
125
- item.pubDate = parseDate(content('meta[property="article:published_time"]').attr('content'));
134
+ item.pubDate = timezone(parseDate(content('meta[property="article:published_time"]').attr('content')), +8);
126
135
  item.description = content('article, .content-p').html();
127
136
 
128
137
  return item;