您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动化实现,效率低但是绝对安全,放心使用
// ==UserScript== // @name b站评论自动点赞 // @namespace http://tampermonkey.net/ // @version 1.0.1 // @description 自动化实现,效率低但是绝对安全,放心使用 // @author 口吃者 // @match https://www.bilibili.com/video/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @require https://update.greasyfork.org/scripts/498507/1398070/sweetalert2.js // @license MIT // @grant none // ==/UserScript== var targetAmountGlobal = 100; var lastArrayLen; (function () { 'use strict'; window.addEventListener('load', addPanel); })(); /* 父级评论点赞,点赞时移动到评论元素中心点 */ async function clickCommentsAuto(targetAmount) { /* 获取所有父级评论元素数组 全部执行完时再次获取,以此往复 */ var alreadyClicked = 0; while (alreadyClicked < targetAmount) { alreadyClicked = await clickComments(alreadyClicked); if (alreadyClicked < targetAmount) { await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒后再尝试 } } } async function clickComments(alreadyClicked) { // 使用链式调用和可选链操作符来简化元素查找过程 const feedElement = document.querySelector('#commentapp > bili-comments')?.shadowRoot?.querySelector('#feed'); if (!feedElement) return alreadyClicked; // 直接遍历所有需要的元素,同时尽量减少对shadowRoot的访问次数 var commentThreads = [...feedElement.querySelectorAll('bili-comment-thread-renderer')]; if(lastArrayLen){ const lengthNew = Math.max(0, commentThreads.length - lastArrayLen); commentThreads = [...commentThreads.slice(lengthNew)] } for (const shadowRootEle of commentThreads) { const likeButtonContainer = shadowRootEle.shadowRoot?.querySelector('bili-comment-renderer')?.shadowRoot?.querySelector('#footer > bili-comment-action-buttons-renderer'); if (!likeButtonContainer) continue; const likeButton = likeButtonContainer.shadowRoot?.querySelector('#like button'); if (!likeButton) continue; // 平滑滚动到点赞按钮位置 await scrollToElement(likeButton); // 只有当点赞图标为未点赞状态时才进行操作 if (likeButton.querySelector('bili-icon')?.getAttribute('icon') === 'BDC/hand_thumbsup_line/1') { // 模拟点击点赞按钮 likeButton.click(); alreadyClicked += 1; } } lastArrayLen = commentThreads.length; return alreadyClicked; } // 辅助函数:平滑滚动到元素中心点 function scrollToElement(element) { return new Promise((resolve) => { element.scrollIntoView({ behavior: 'smooth', block: 'center' }); // 等待滚动动画完成 setTimeout(resolve, 500); // 假设滚动动画持续时间不超过500ms }); } function addPanel() { function genButton(text, foo, id, fooParams = {}) { let b = document.createElement('button'); b.textContent = text; b.style.verticalAlign = 'inherit'; // 使用箭头函数创建闭包来保存 fooParams 并传递给 foo b.addEventListener('click', () => { foo.call(b, ...Object.values(fooParams)); // 使用 call 方法确保 this 指向按钮对象 }); if (id) { b.id = id }; return b; } function changeRangeDynamics() { const value = parseInt(this.value, 10); const roundedValue = Math.ceil(value / 10) * 10; targetAmountGlobal = roundedValue; // 只能通过 DOM 方法改变 document.querySelector('#swal-range > output').textContent = roundedValue; } async function openPanelFunc() { let isLoadEnd = false; targetAmountGlobal = 100; var swalRangeValue = 100; setTimeout(() => { isLoadEnd = true; }, 13000); const { value: formValues } = await Swal.fire({ title: "最大点赞数", showCancelButton: true, cancelButtonText: '取消', confirmButtonText: '确定', //class="swal2-range" swalalert框架可能会对其有特殊处理,导致其内标签的id声明失效 html: ` <div class="swal2-range" id="swal-range" style="display: flex;"> <input type="range" min="0" max="500" step="10" value="100"> <output>${swalRangeValue}</output> </div> `, focusConfirm: false, didOpen: () => { const swalRange = document.querySelector('#swal-range input'); swalRange.addEventListener('input', changeRangeDynamics); }, willClose: () => { // 在关闭前清除事件监听器以防止内存泄漏 const swalRange = document.querySelector('#swal-range input'); swalRange.removeEventListener('input', changeRangeDynamics); }, preConfirm: () => { return [ targetAmountGlobal ]; } }); if (formValues) { targetAmountGlobal = formValues[0]; clickCommentsAuto(targetAmountGlobal); } } let myButton = genButton('CMlike', openPanelFunc, 'CMlike'); document.body.appendChild(myButton); var css_text = ` #CMlike { position: fixed; top: 70%; left: -20px;/* 初始状态下左半部分隐藏 */ transform: translateY(-50%); z-index: 1000; /* 确保按钮在最前面 */ padding: 10px 24px; border-radius: 5px; cursor: pointer; border: 0; background-color: white; box-shadow: rgb(0 0 0 / 5%) 0 0 8px; letter-spacing: 1.5px; text-transform: uppercase; font-size: 9px; transition: all 0.5s ease; } #CMlike:hover { left: 0%; /* 鼠标悬停时完整显示 */ letter-spacing: 3px; background-image: linear-gradient(to top, #fad0c4 0%, #fad0c4 1%, #ffd1ff 100%); box-shadow: rgba(211, 67, 235, 0.7) 0px 7px 29px 0px; /* 更柔和的紫色阴影,带透明度 */ } #CMlike:active { letter-spacing: 3px; background-image: linear-gradient(to top, #fad0c4 0%, #fad0c4 1%, #ffd1ff 100%); box-shadow: rgba(211, 67, 235, 0.5) 0px 0px 0px 0px; /* 活动状态下的阴影,保持一致性 */ transition: 100ms; } ` GMaddStyle(css_text); } function GMaddStyle(css) { var myStyle = document.createElement('style'); myStyle.textContent = css; var doc = document.head || document.documentElement; doc.appendChild(myStyle); }