// ==UserScript==
// @name 新浪微博热搜屏蔽
// @namespace https://greasyfork.org/zh-CN/users/756550
// @version 0.13
// @description 在微博热搜右边栏屏蔽不想看的热搜,屏蔽娱乐圈,支持关键词和分类屏蔽
// @author festoney8
// @license MIT
// @match http*://weibo.com/*
// @match http*://www.weibo.com/*
// @match http*://s.weibo.com/*
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
(function () {
'use strict'
// 自定义设置
// 屏蔽指定的关键词,用竖线分割,如:"关键词A|关键词B"
let keywordBlacklist = "肖战|王一博"
// 是否保留爆字label的话题
let keepSuperHotLabel = true;
// 是否移除包含任何明星的话题
let removeStar = true;
// 屏蔽指定的分类,用竖线分割,默认屏蔽娱乐圈
let categoryBlacklist = "美妆|影视|艺人|综艺|作品衍生"
// —————————————————————————————————————————————————————————————————————————————————
// 全局css修改,固定热搜栏,热搜标题全长度
if (window.location.pathname === "/hot/search") {
log("热搜榜页面,不执行css更改")
} else if (window.location.hostname === "weibo.com" || window.location.hostname === "www.weibo.com") {
GM_addStyle(`
/* 热搜栏sticky */
[class^="Side_posSticky"] {
position: sticky;
top: 60px !important;
}
[class^="Side_sideBox"] {
top: 60px !important;
}
/* 移除热度icon */
.wbpro-side-card7 .icon,
.wbpro-icon-search- {
display: none !important;
}
/* 全长度热搜 */
.wbpro-side-card7 .con {
padding-right: 0 !important;
}
.wbpro-side-panel {
padding-left: 10px !important;
padding-right: 10px !important;
}
/* 高度微调 */
#app [class^="cardHotSearch_tit"] {
padding-bottom: unset !important;
}
.wbpro-side-bottom {
padding-top: 0 !important;
}
`)
log("css修改完成")
} else if (window.location.hostname === "s.weibo.com") {
GM_addStyle(`
/* 热度icon移除 */
.card-hotrank .card-content i.icon-txt {
display: none !important;
}
/* 全长度热搜 */
.card-hotrank .card-content ul>li {
padding-right: 0 !important;
}
.card-hotrank .card-content span.val {
padding-left: 15px !important;
}
/* 右栏移除其他板块 */
#pl_right_msg,
#pl_right_side .card-user {
display: none !important;
}
#pl_right_side {
z-index: unset !important;
top: 70px !important;
}
`)
log("css修改完成")
}
function containKeyword(obj) {
if (keywordBlacklist.length === 0) {
return false
}
let lst = keywordBlacklist.split('|')
let regex = new RegExp(`(${lst.join('|')})`, 'i')
return regex.test(obj.word)
}
function containCategory(obj) {
if (categoryBlacklist.length === 0) {
return false
}
let lst = categoryBlacklist.split('|')
let regex = new RegExp(`(${lst.join('|')})`, 'i')
return regex.test(obj.category)
}
function containStarName(obj) {
// 包含明星的话题
return JSON.stringify(obj.star_name) !== '{}'
}
function containAd(obj) {
// 屏蔽广告
return obj.is_ad === 1 || obj.ad_type === "商业投放" || obj.ad_type === "资源投放";
}
function containSuperHot(obj) {
// 爆 label的热搜
return obj.label_name === "爆";
}
function log(...args) {
const nowTime = new Date().toLocaleTimeString();
const newArgs = [`[WeiboGreasyfork] ${nowTime}:`, ...args];
console.log.apply(console, newArgs);
}
// 移除置顶热搜,添加热搜位,移除无排名热搜(dot)
function adjustHotSearchPlace(num, removeTop = true) {
if (window.location.pathname === "/hot/search") {
return
}
if (window.location.hostname === "weibo.com" || window.location.hostname === "www.weibo.com") {
// 移除置顶热搜,移除点开头的非排名热搜
let topicElems = document.querySelectorAll('.wbpro-side-card7 .wbpro-side-panel')
if (removeTop) {
topicElems[0].remove()
log(`移除了置顶热搜`)
}
for (let i = 0; i < topicElems.length; i++) {
let e = topicElems[i];
let span = e.querySelector(".wbpro-icon-doticon")
if (span) {
e.remove()
log(`移除了Dot热搜`)
}
}
// 添加热搜位
let topic = document.querySelector('.wbpro-side-card7')
let lastChild = topic.children[topic.children.length - 1]
for (let i = 0; i < num; i++) {
let newChild = lastChild.cloneNode(true)
topic.appendChild(newChild)
}
log(`添加了 ${num} 个热搜位`)
} else if (window.location.hostname === "s.weibo.com") {
let topicElems = document.querySelectorAll('.card-hotrank .card-content li')
if (topicElems.length > 0) {
topicElems[0].remove()
log(`移除了置顶热搜`)
}
}
}
// 覆盖热搜列表
function overwriteHotSearch(filteredData) {
function convertIntToStr(intNum) {
let strNum;
if (intNum >= 100000000) {
strNum = (intNum / 100000000).toFixed(1) + '亿';
} else if (intNum >= 10000) {
// strNum = (intNum / 10000).toFixed(1) + '万';
strNum = (intNum / 10000).toFixed(1);
} else {
strNum = intNum.toString();
}
return strNum;
}
if (window.location.pathname === "/hot/search") {
return
}
if (window.location.hostname === "weibo.com" || window.location.hostname === "www.weibo.com") {
let topicElems = document.querySelectorAll('.wbpro-side-card7 .wbpro-side-panel')
if (topicElems.length > 0) {
// 用筛选后热搜列表覆盖热搜内容
for (let i = 0; i < topicElems.length; i++) {
let oldTopic = topicElems[i]
let newData = filteredData[i]
try {
oldTopic.querySelector("a").href = "//s.weibo.com/weibo?q=" + encodeURIComponent(newData.word)
oldTopic.querySelector(".rank").textContent = " " + (i + 1) + " "
oldTopic.querySelector(".wbpro-textcut").textContent = newData.word
oldTopic.querySelector(".wbpro-textcut").title = newData.word
// 将icon颜色显示在热度上,热度加粗显示
let hotstatus = oldTopic.querySelector(".clb")
// 有时会出现无热度指数span的情况(原因未知),手动创建
if (!hotstatus) {
let hotStatusSpan = document.createElement("span")
hotStatusSpan.setAttribute("class", "f13 clb")
hotStatusSpan.textContent = "0"
let parentNode = oldTopic.querySelector(".woo-box-alignCenter")
let targetNode = oldTopic.querySelector(".wbpro-textcut")
parentNode.insertBefore(hotStatusSpan, targetNode.nextSibling)
}
hotstatus = oldTopic.querySelector(".clb")
hotstatus.textContent = convertIntToStr(newData.raw_hot)
let e = oldTopic.querySelector(".icon")
if (e) {
e.remove()
}
let dict = {
"": "font-weight: bold;",
"热": "font-weight: bold; color: #ff7100 !important",
"沸": "font-weight: bold; color: #f86400 !important",
"暖": "font-weight: bold; color: #FFAB5A !important",
"商": "font-weight: bold; color: #00b7ee !important",
"新": "font-weight: bold; color: #22dd9f !important",
"爆": "font-weight: bold; color: red !important; text-shadow: 0px 0px 10px yellow;",
}
hotstatus.style = dict[newData.label_name]
} catch (e) {
console.error("Error, 跳过本条热搜:", e);
log(oldTopic)
log(newData)
}
}
log("完成热搜覆盖")
}
}
if (window.location.hostname === "s.weibo.com") {
let topicElems = document.querySelectorAll('.card-hotrank .card-content li')
if (topicElems.length > 0) {
for (let i = 0; i < topicElems.length; i++) {
let oldTopic = topicElems[i]
let newData = filteredData[i]
try {
oldTopic.querySelector("a").href = "//s.weibo.com/weibo?q=" + encodeURIComponent(newData.word)
oldTopic.querySelector("a").textContent = newData.word
// 移除icon,将icon颜色显示在热度上,热度加粗显示
let hotstatus = oldTopic.querySelector("span.val")
hotstatus.textContent = convertIntToStr(newData.raw_hot)
let e = oldTopic.querySelector("i.icon-txt")
if (e) {
e.remove()
}
let dict = {
"": "font-weight: bold;",
"热": "font-weight: bold; color: #ff7100 !important",
"暖": "font-weight: bold; color: #FFAB5A !important",
"新": "font-weight: bold; color: #22dd9f !important",
"爆": "font-weight: bold; color: red !important; text-shadow: 0px 0px 10px yellow;",
}
hotstatus.style = dict[newData.label_name]
} catch (e) {
console.error("Error, 跳过本条热搜:", e);
log(oldTopic)
log(newData)
}
}
log("完成热搜覆盖")
}
}
}
// fetch新热搜, 筛选
function newHotSearch() {
// api获取top50个热搜并筛选
GM_xmlhttpRequest({
method: "GET", url: "https://weibo.com/ajax/side/hotSearch", onload: function (response) {
let jsonapi = JSON.parse(response.responseText)
let hotSearch = jsonapi.data.realtime
let filteredData = hotSearch.filter(function (obj) {
// 黑名单关键字最高优先级
if (containKeyword(obj)) {
return false
}
// 放过爆字label的话题
if (keepSuperHotLabel && containSuperHot(obj)) {
return true
}
// 是否屏蔽全部明星
if (containStarName(obj) && removeStar) {
return false
}
return !(containAd(obj) || containCategory(obj))
})
if (!filteredData) {
return
}
log("筛选后热搜数量:", filteredData.length)
overwriteHotSearch(filteredData)
}, onerror: function (response) {
console.error(response.responseText)
}
})
}
// 监听 URL 变化,并刷新热搜
var lastExecTime = null;
var lastURL = null;
window.addEventListener('load', function () {
lastURL = window.location.href;
setInterval(() => {
let newURL = window.location.href;
if (newURL !== lastURL) {
log("URL change detected")
log("current url", window.location.href)
checkUrlChange()
lastURL = newURL;
}
}, 100);
});
function checkUrlChange() {
if (window.location.pathname === "/hot/search") {
return
}
if (!lastExecTime || Date.now() - lastExecTime > 60 * 1000) {
log("检测到 URL 变化,刷新热搜");
adjustHotSearchPlace(0, false)
newHotSearch();
lastExecTime = Date.now();
} else {
log("1 分钟内已经刷新过,忽略");
}
}
function runAfterDOMContentLoaded(retries) {
function work() {
try {
if (window.location.pathname === "/hot/search") {
return
}
// 添加热搜位
adjustHotSearchPlace(2)
// 覆盖热搜
newHotSearch()
// 刷新热搜按钮 重新绑定事件
if (window.location.hostname === "weibo.com" || window.location.hostname === "www.weibo.com") {
let oldButton = document.querySelector(".wbpro-side-tit .woo-box-flex.woo-box-alignCenter")
if (!oldButton) {
throw Error("No button")
}
let newButton = oldButton.cloneNode(true)
newButton.addEventListener("click", newHotSearch)
oldButton.parentNode.replaceChild(newButton, oldButton)
}
} catch (error) {
if (retries > 0) {
retries--;
setTimeout(work, 500);
}
}
}
work();
}
runAfterDOMContentLoaded(3)
})()