// ==UserScript== // @name b站统计真实评分 // @namespace http://tampermonkey.net/ // @version 0.1 // @description b站统计真实评分,使用后在番剧介绍页会多一个“计算真实评分”的按钮,点击将会收集所有能进行访问(重点)的评论进行统计,得出真实评分。 // @author thunder-sword-b站up主月雨洛然(主体代码来自Meow) // @match https://www.bilibili.com/bangumi/media/md* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @license MIT // @grant none // @downloadURL none // ==/UserScript== /* 声明:计算主体代码修改于b站大佬的代码,视频地址忘了,博客地址倒是有…… /* 来源:https://wdhhh.cn/home?article=627 /* 注意:需要进入介绍页运行 https://www.bilibili.com/bangumi/media/md4315402/ */ const allScore = []; const shortScore = []; const longScore = []; let totalCount = { short: 0, long: 0, }; let trueScore = 0;//真实评分 let render = null; let rmDialog = null; let mid; try { mid = location.href.match(/media\/md(\d+)/)[1]; } catch (_) { alert("获取mid失败"); _; } if (!mid) { throw new Error("未进入介绍详情页面"); } async function getScore(next, type) { let url = `https://api.bilibili.com/pgc/review/${type}/list?media_id=${mid}&ps=12575&sort=0`; if (next) { url += `&cursor=${next}`; } const res = await fetch(url, { "method": "GET" }); const { data } = await res.json(); if (totalCount[type] == 0) { totalCount[type] = data.total; } return data; } async function scoreMain(type) { let { list, next } = await getScore(undefined, type); handlerList(list, type); while (true) { const data = await getScore(next, type); handlerList(data.list, type); render(type); next = data.next; if (next == 0) { return; } } } function average() { const total = allScore.reduce((p, v) => { return p + v; }, 0) const tmp = total / allScore.length; trueScore = tmp.toFixed(1); document.getElementsByClassName("media-info-score-content")[0].innerText = trueScore; const starLc = parseInt(Math.round(trueScore / 2)); const starHc = 5 - starLc; const starsDom = document.getElementsByClassName("review-stars")[0]; starsDom.innerHTML = ''; for (let i = 0; i < starLc; i++) { const star = document.createElement('i'); star.className = "icon-star icon-star-light"; starsDom.appendChild(star); } for (let i = 0; i < starHc; i++) { const star = document.createElement('i'); star.className = "icon-star icon-star-half"; starsDom.appendChild(star); } console.log("总评价人数:",allScore.length); console.log('总平均分:', tmp); } function handlerList(list, type) { allScore.push(...list.map(item => item.score)); if("short"===type){ shortScore.push(...list.map(item => item.score)); }else if("long"===type){ longScore.push(...list.map(item => item.score)); } } function beforeRender() { const dialog = document.createElement('div'); document.body.appendChild(dialog); dialog.style.position = 'fixed'; dialog.style.width = '100%'; dialog.style.height = '100%'; dialog.style.background = 'rgba(0,0,0,.8)'; dialog.style.top = '0'; dialog.style.left = '0'; dialog.style.zIndex = '999'; dialog.style.display = 'flex'; dialog.style.alignItems = 'center'; dialog.style.justifyContent = 'center'; const dialogContent = document.createElement('div'); dialog.appendChild(dialogContent); dialogContent.style.width = '455px'; dialogContent.style.height = '200px'; dialogContent.style.background = '#fff'; dialogContent.style.borderRadius = '6px'; dialogContent.style.padding = '51px 0'; const shortWrap = document.createElement('div'); dialogContent.appendChild(shortWrap); const longWrap = document.createElement('div'); dialogContent.appendChild(longWrap); shortWrap.style.width = longWrap.style.width = '455px'; shortWrap.style.height = longWrap.style.height = '100px'; shortWrap.style.display = longWrap.style.display = 'flex'; shortWrap.style.alignItems = longWrap.style.alignItems = 'center'; shortWrap.style.justifyContent = longWrap.style.justifyContent = 'center'; // -------------- const shortw1 = document.createElement('div'); const longw1 = document.createElement('div'); shortWrap.appendChild(shortw1); longWrap.appendChild(longw1); shortw1.innerText = '短评:'; longw1.innerText = '长评:'; longw1.style.fontSize = shortw1.style.fontSize = '14px'; longw1.style.color = shortw1.style.color = '#333'; longw1.style.marginRight = shortw1.style.marginRight = '16px'; const shortw2 = document.createElement('div'); const longw2 = document.createElement('div'); shortWrap.appendChild(shortw2); longWrap.appendChild(longw2); longw2.style.width = shortw2.style.width = '300px'; longw2.style.height = shortw2.style.height = '32px'; longw2.style.background = shortw2.style.background = '#eee'; longw2.style.position = shortw2.style.position = 'relative'; const shortPrg = document.createElement('div'); const longPrg = document.createElement('div'); shortw2.appendChild(shortPrg); longw2.appendChild(longPrg); longPrg.style.position = shortPrg.style.position = 'absolute'; longPrg.style.left = shortPrg.style.left = '0'; longPrg.style.top = shortPrg.style.top = '0'; longPrg.style.width = shortPrg.style.width = '0%'; longPrg.style.height = shortPrg.style.height = '100%'; longPrg.style.background = shortPrg.style.background = '#ff85ad'; render = function (type) { const dom = type == 'long' ? longPrg : shortPrg; let width; if (type == 'long') { width = ((allScore.length - totalCount.short) * 100 / totalCount.long) + '%'; } else { width = (allScore.length * 100 / totalCount.short) + '%'; } dom.style.width = width; } rmDialog = function () { document.body.removeChild(dialog); } } //统计短评和长评评分 function partAverage() { //短评统计 const shortTotal = shortScore.reduce((p, v) => { return p + v; }, 0) const shortAverage = shortTotal / shortScore.length; //const shortAverage = tmp1.toFixed(1); console.log(`短评评分人数:${shortScore.length}`); console.log(`短评平均分数:${shortAverage}`); //长评统计 const longTotal = longScore.reduce((p, v) => { return p + v; }, 0) const longAverage = longTotal / longScore.length; //const longAverage = tmp2.toFixed(1); console.log(`长评评分人数:${longScore.length}`); console.log(`长评平均分数:${longAverage}`); } async function main() { beforeRender(); console.log("--统计短评"); await scoreMain('short'); console.log("--统计长评"); await scoreMain('long'); average(); rmDialog(); } //main(); //作用:生成toast,让其在toast_container中,显示在页面中上部,会永久性向页面添加一个id为ths_toast_container的div标签 function showStackToast(message, timeout=3000){ //没有容器则生成容器 let box=document.querySelector("body > div#ths_toast_container"); if(!box){ box=document.createElement('div'); box.id="ths_toast_container"; box.style.cssText = ` position: fixed; top: 10px; left: 50%; transform: translateX(-50%); right: 10px; width: 300px; height: auto; display: flex; z-index: 9999; flex-direction: column-reverse;`; document.body.appendChild(box); } //创建toast const toast = document.createElement('div'); toast.innerText = message; toast.style.cssText = ` padding: 10px; background-color: rgb(76, 175, 80); color: rgb(255, 255, 255); border-radius: 10px; font-size: 24px; font-weight: bold; text-align: center; box-shadow: rgb(0 0 0 / 30%) 0px 5px 10px; opacity: 1; transition: opacity 0.3s ease-in-out 0s; z-index: 9999; margin: 5px; `; box.appendChild(toast); toast.style.opacity = 1; if(timeout > 0){ setTimeout(() => { toast.style.opacity = 0; setTimeout(() => { box.removeChild(toast); }, 300); }, timeout); } return toast; } /* 添加按钮 */ function addButton() { var container=document.querySelector("#app > div.media-info-wrp > div.media-info-content > div > div.media-info-r > div.media-info-btns"); if(!container){ alert("获取按钮容器失败,请刷新重试!"); throw new Error("获取按钮容器失败,请刷新重试!"); } var button=document.createElement("div"); button.setAttribute("class", "btn-pay-wrapper"); button.setAttribute("style", "margin-left: 20px"); button.innerHTML=`计算真实评分
`; button.addEventListener("click", async () => { await main(); partAverage(); showStackToast("统计结束"); showStackToast(`共统计${allScore.length}条评价`); showStackToast(`真实评分为:${trueScore}`); }); container.appendChild(button); } (function() { 'use strict'; setTimeout(addButton, 500); })();