哔哩哔哩推荐-

哔哩哔哩推荐模块

  1. // ==UserScript==
  2. // @name 哔哩哔哩推荐-
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3.1
  5. // @description 哔哩哔哩推荐模块
  6. // @author You
  7. // @match https://*.bilibili.com/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14. /**
  15. * 秒 转 可阅读的时长
  16. * @param secondDuration
  17. */
  18. function utilSecond2StrChinese(secondDuration = 0) {
  19. let day = Math.floor(secondDuration / (60 * 60 * 24));
  20. secondDuration -= day * (60 * 60 * 24);
  21. let hour = Math.floor(secondDuration / (60 * 60));
  22. secondDuration -= hour * (60 * 60);
  23. let minute = Math.floor(secondDuration / (60));
  24. secondDuration -= minute * (60);
  25. return (day ? day + '天' : '')
  26. + (hour ? hour + '时' : '')
  27. + (minute ? minute + '分' : '')
  28. + (secondDuration ? secondDuration + '秒' : '');
  29. }
  30. /**
  31. * 播放量 转 几万播放量
  32. * @param secondDuration
  33. */
  34. function utilPlayTimes2TenThousands(playTimes = 0) {
  35. if (playTimes < 10000) {
  36. return playTimes;
  37. }
  38. return (playTimes / 10000).toFixed(1) + '万';
  39. }
  40. /*时间(今年的没年份)*/
  41. function utilDate2Str(date) {
  42. let curDate = new Date();
  43. return !date ? ''
  44. : (date.getFullYear() === curDate.getFullYear() ? '' : date.getFullYear() + '年')
  45. + (date.getMonth() + 1) + '月'
  46. + date.getDate() + '日';
  47. }
  48.  
  49. let html = `
  50. <a class="btn contact-help" id="open-my-recommend" onclick="document.getElementById('my-bilibili-recommend').style.display='block'">推荐页</a>
  51. <div id="my-bilibili-recommend" style="display:none;">
  52. <a class="btn out-btn-my-recommend" id="close-my-recommend">返回</a>
  53. <a class="btn out-btn-my-recommend" id="refresh-my-recommend" style="top:40px">刷新</a>
  54. <a class="btn out-btn-my-recommend" id="top-my-recommend" style="top:80px">顶部</a>
  55. <div class="recommend-content" style="text-align: center;">
  56. </div>
  57. </div>
  58. `;
  59. let style = `
  60. <style>
  61. .out-btn-my-recommend {
  62. position: fixed;
  63. left: 0;
  64. width: 20px;
  65. padding: 3px;
  66. background: #fff;
  67. line-height: 17px;
  68. cursor: pointer;
  69. }
  70.  
  71. #open-my-recommend {
  72. height: 60px;
  73. top: calc(50% - 100px);
  74.  
  75. -webkit-text-size-adjust: 100%;
  76. -webkit-tap-highlight-color: rgba(0,0,0,0);
  77. font: 12px -apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,sans-serif;
  78. -webkit-font-smoothing: antialiased;
  79. box-sizing: border-box;
  80. margin: 0;
  81. outline: none;
  82. cursor: pointer;
  83. touch-action: manipulation;
  84. text-decoration: none;
  85. position: fixed;
  86. z-index: 101;
  87. left: 0;
  88. margin-top: -36px;
  89. width: 28px;
  90. transition: all .3s;
  91. font-size: 12px;
  92. color: #505050;
  93. background: #fff;
  94. border: 1px solid #e7e7e7;
  95. box-shadow: 0 6px 10px 0 #e7e7e7;
  96. border-radius: 0 2px 2px 0;
  97. padding: 8px 7px;
  98. line-height: 14px;
  99. height: 60px;
  100. top: calc(50% - 100px);
  101. }
  102.  
  103. div#my-bilibili-recommend {
  104. position: fixed;
  105. width: 100%;
  106. height: 100%;
  107. top: 0;
  108. background: #FFF;
  109. z-index: 10000;
  110. overflow: auto;
  111. }
  112.  
  113. #my-bilibili-recommend .recommend-content {
  114. width: calc(100% - 20px);
  115. float: right;
  116. }
  117.  
  118. #my-bilibili-recommend .recommend-video {
  119. width: 450px;
  120. height: 170px;
  121. overflow: hidden;
  122. position: relative;
  123. padding: 5px 5px 5px 0;
  124. /*display: inline-block;*/
  125. float:left;
  126. text-align: left;
  127. }
  128.  
  129. #my-bilibili-recommend .recommend-video .recommend-video-img {
  130. width: calc(100% - 150px);
  131. overflow: hidden;
  132. height: 100%;
  133. float: left;
  134. }
  135.  
  136. #my-bilibili-recommend .recommend-video img {
  137. width: 100%;
  138. height: 100%;
  139. object-fit: cover;
  140. }
  141.  
  142. #my-bilibili-recommend a.recommend-video-info {
  143. display: block;
  144. float: left;
  145. width: 150px;
  146. height: 100%;
  147. position: relative;
  148. font-size: 14px;
  149. }
  150.  
  151. #my-bilibili-recommend a.recommend-video-info > div {
  152. padding: 0 5px;
  153. }
  154.  
  155. #my-bilibili-recommend .recommend-video-user {
  156. position: absolute;
  157. bottom: 0;
  158. left: 0;
  159. }
  160.  
  161. #my-bilibili-recommend .recommend-video-time {
  162. position: absolute;
  163. bottom: 0;
  164. right: 0;
  165. }
  166.  
  167. #my-bilibili-recommend .recommend-video-play-times {
  168. position: absolute;
  169. bottom: 17px;
  170. }
  171.  
  172. #my-bilibili-recommend .recommend-video-duration {
  173. position: absolute;
  174. bottom: 34px;
  175. }
  176.  
  177. #my-bilibili-recommend .recommend-video-play-tags {
  178. position: absolute;
  179. bottom: 17px;
  180. right: 0;
  181. }
  182.  
  183.  
  184. #page-follows > div > div.follow-sidenav > div.nav-container.follow-container > div.be-scrollbar.follow-list-container.ps {
  185. max-height: unset !important;
  186. }
  187. #page-fav > div.col-full.clearfix.master > div.fav-sidenav > div:nth-child(1) > div:nth-child(2) #fav-createdList-container {
  188. max-height: unset !important;
  189. }
  190. </style>
  191. `
  192. let div = document.createElement('div');
  193. document.body.append(div);
  194. div.innerHTML += html + style;
  195. function getVideoHtml(video) {
  196. if (document.querySelector('.recommend-video[videoId="'+video.id+'"]') != null) {
  197. return ``;
  198. }
  199. return `
  200. <div class="recommend-video" title="${video.title}" videoId="${video.id}">
  201. <div class="recommend-video-img"><a href="${video.uri}" target="_blank"><img src="${video.pic}"></a></div>
  202. <a class="recommend-video-info" href="${video.uri}" target="_blank">
  203. <div class="recommend-video-title">${video.title.substring(0, 40)}</div>
  204. <div class="recommend-video-play-times">${utilPlayTimes2TenThousands(video.stat.view)}</div>
  205. <div class="recommend-video-user">${video.owner.name}</div>
  206. <div class="recommend-video-duration">${utilSecond2StrChinese(video.duration)}</div>
  207. </a>
  208. </div>
  209. `
  210. }
  211. function eleCommendContent() {
  212. return document.querySelector('#my-bilibili-recommend .recommend-content');
  213. }
  214.  
  215. document.getElementById('open-my-recommend').onclick = document.getElementById('close-my-recommend').onclick = function () {
  216. let recommend = document.getElementById('my-bilibili-recommend');
  217. if (recommend.style.display === 'none') {
  218. recommend.style.display = 'block';
  219. document.documentElement.style.overflow = 'hidden';
  220. if (containerTooLess()) {
  221. RestGetVideoList();
  222. }
  223. } else {
  224. recommend.style.display = 'none';
  225. document.documentElement.style.overflow = 'auto';
  226. }
  227. };
  228. document.getElementById('refresh-my-recommend').onclick = function () {
  229. eleCommendContent().innerHTML = '';
  230. RestGetVideoList();
  231. };
  232. document.getElementById('top-my-recommend').onclick = function () {
  233. document.querySelector("#my-bilibili-recommend").scrollTop = 0;
  234. };
  235.  
  236. // RestGetVideoList();
  237. function RestGetVideoList() {
  238. // let request = new XMLHttpRequest();
  239. // request.open('GET', 'https://api.bilibili.com/x/web-interface/index/top/rcmd?fresh_type=3&fresh=' + Math.random());
  240. // request.setRequestHeader("If-Modified-Since","0"); // 清除缓存
  241. // request.setRequestHeader('Content-Type', 'application/json');
  242. // request.withCredentials = true;
  243. // // request.setRequestHeader('cookie', document.cookie);
  244. // request.addEventListener('load', function () {
  245. // let newHtml = '';
  246. // if (JSON.parse(this.responseText).code != 0) {
  247. // alert(JSON.parse(this.responseText).message);
  248. // return;
  249. // }
  250. // for (let video of JSON.parse(this.responseText).data.item) {
  251. // newHtml += getVideoHtml(video);
  252. // }
  253. // eleCommendContent().innerHTML += newHtml;
  254. // if (containerTooLess()) {
  255. // RestGetVideoList()
  256. // }
  257. // })
  258. // request.send();
  259.  
  260. fetch("https://api.bilibili.com/x/web-interface/index/top/rcmd?fresh_type=3&version=1&ps=10&fresh_idx=5&fresh_idx_1h=5&homepage_ver=1", {
  261. "headers": {
  262. "accept": "application/json, text/plain, */*",
  263. "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
  264. "sec-ch-ua": "\"Google Chrome\";v=\"105\", \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"105\"",
  265. "sec-ch-ua-mobile": "?0",
  266. "sec-ch-ua-platform": "\"Windows\"",
  267. "sec-fetch-dest": "empty",
  268. "sec-fetch-mode": "cors",
  269. "sec-fetch-site": "same-site"
  270. },
  271. "referrer": "https://www.bilibili.com/?spm_id_from=333.155.b_696e7465726e6174696f6e616c486561646572.1",
  272. "referrerPolicy": "no-referrer-when-downgrade",
  273. "body": null,
  274. "method": "GET",
  275. "mode": "cors",
  276. "credentials": "include"
  277. }).then(response => {
  278. response.json().then(res => {
  279. let newHtml = '';
  280. for (let video of res.data.item) {
  281. newHtml += getVideoHtml(video);
  282. }
  283. eleCommendContent().innerHTML += newHtml;
  284. if (containerTooLess()) {
  285. RestGetVideoList()
  286. }
  287. })
  288. });
  289. }
  290.  
  291. document.getElementById('my-bilibili-recommend').onscroll = function (event) {
  292. if (containerTooLess()) {
  293. RestGetVideoList();
  294. }
  295. };
  296.  
  297. function containerTooLess() {
  298. let scrollTop = document.getElementById('my-bilibili-recommend').scrollTop;
  299. let height = document.getElementById('my-bilibili-recommend').clientHeight;
  300. let contentHeight = eleCommendContent().clientHeight;
  301. if (scrollTop + height + 50 >= contentHeight) {
  302. return true;
  303. }
  304. return false;
  305. }
  306.  
  307. let scrollbarWidth = (function getScrollbarWidth() {
  308. var scrollDiv = document.createElement("div");
  309. scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
  310. document.body.appendChild(scrollDiv);
  311. var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  312. document.body.removeChild(scrollDiv);
  313. return scrollbarWidth;
  314. })();
  315.  
  316. // 适应宽度
  317. function myResize() {
  318. //let contentWidth = document.querySelector("#my-bilibili-recommend .recommend-content").offsetWidth - scrollbarWidth;
  319. let maxWidth = 600;
  320. let contentWidth = window.innerWidth - 20 - scrollbarWidth;
  321. let width = contentWidth <= maxWidth ? maxWidth : contentWidth / Math.ceil(contentWidth / maxWidth) - 5;
  322. let height = width * 0.4;
  323.  
  324. let newStyle = `
  325. <style>
  326. #my-bilibili-recommend .recommend-video {
  327. width: ${width}px;
  328. height: ${height}px;
  329. }
  330. </style>
  331. `
  332. let div = document.createElement('div');
  333. div.innerHTML += newStyle;
  334. document.body.append(div);
  335. }
  336. myResize();
  337. window.onresize = myResize;
  338.  
  339. // Your code here...
  340. })();