屏蔽p站不感兴趣的标签和广告教程
作者:天溟启
先使用pixiv官方的正文筛选第一遍结果,
会出现很多雷区标签的作品
使用油猴脚本的程序的二次筛选功能,进行雷区标签和标题的屏蔽
屏蔽后效果
脚本源码,搜集端via浏览器可使用
// ==UserScript==
// @name Pixiv 小说二次筛选器 v2
// @namespace
// @version 2.0.0
// @description 对 Pixiv 官方小说搜索结果按标题和完整可见标签进行包含、排除筛选。
// @author ChatGPT
// @license MIT
// @match
// @run-at document-end
// @grant none
// ==/UserScript==
(function () {
'use strict';
const STORAGE_KEY = 'pixivNovelFilterV2.rules';
const HOST_ID = 'pixiv-novel-filter-v2-host';
const STYLE_ID = 'pixiv-novel-filter-v2-page-style';
const HIDDEN_CLASS = 'pixiv-novel-filter-v2-hidden';
const DASHES = '-‐‑‒–—―−﹘﹣-';
const norm = (value) => String(value ?? '').normalize('NFKC').trim().toLocaleLowerCase();
function parseRules(raw) {
const positive = [];
const negative = [];
const splitPrefix = new RegExp(`\\s+(?=[${DASHES}!!])`, 'u');
const negativePrefix = new RegExp(`^[${DASHES}!!]+`, 'u');
const entries = String(raw ?? '')
.split(/[\n,,;;]+/)
.flatMap((line) => line.trim().split(splitPrefix));
for (let entry of entries) {
entry = entry.trim();
if (!entry) continue;
const match = entry.match(negativePrefix);
const target = match ? negative : positive;
if (match) entry = entry.slic
e(match[0].length).trim();
entry = entry.replace(/^#/, '').trim();
const value = norm(entry);
if (value && !target.includes(value)) target.push(value);
}
return { positive, negative };
}
function matchesWork(work, titleRules, tagRules) {
const title = norm(work.title);
const tags = (work.tags || []).map(norm);
const hasTag = (rule) => tags.some((tag) => tag.includes(rule));
if (!titleRules.positive.every((rule) => title.includes(rule))) return false;
if (titleRules.negative.some((rule) => title.includes(rule))) return false;
if (!tagRules.positive.every(hasTag)) return false;
if (tagRules.negative.some(hasTag)) return false;
return true;
}
if (typeof document === 'undefined') {
globalThis.__PIXIV_FILTER_V2_TEST__ = { norm, parseRules, matchesWork };
return;
}
// 彻底移除 v1.x 的界面和隐藏样式。即使旧脚本仍在运行,也无法覆盖 v2 的筛选结果。
document.querySelectorAll('#pixiv-novel-second-filter-host').forEach((node) => node.remove());
document.getElementById('pixiv-novel-second-filter-page-style')?.remove();
document.querySelectorAll('.pxsf-hidden-by-second-filter, .pxsf-v13-hidden-by-second-filter')
.forEach((node) => node.classList.remove('pxsf-hidden-by-second-filter', 'pxsf-v13-hidden-by-second-filter'));
documen
t.getElementById(HOST_ID)?.remove();
document.getElementById(STYLE_ID)?.remove();
const pageStyle = document.createElement('style');
pageStyle.id = STYLE_ID;
pageStyle.textContent = `.${HIDDEN_CLASS} { display: none !important; }`;
document.head.appendChild(pageStyle);
const host = document.createElement('div');
host.id = HOST_ID;
const root = host.attachShadow({ mode: 'open' });
root.innerHTML = `
<style>
:host { all: initial; }
*, *::before, *::after { box-sizing: border-box; }
button, textarea { font: inherit; }
#open {
position: fixed; right: 16px; bottom: 145px; z-index: 2147483646;
border: 0; border-radius: 999px; padding: 11px 17px; cursor: pointer;
background: #f97316; color: white; font: 700 14px/1.2 system-ui, sans-serif;
box-shadow: 0 6px 20px rgb(0 0 0 / 28%);
}
#overlay {
display: none; position: fixed; inset: 0; z-index: 2147483647;
padding: 5vh 16px; background: rgb(0 0 0 / 54%);
font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}
#overlay.show { display: flex; justify-content: center; align-items: flex-start; }
#panel {
width: min(760px, 100%); max-height: 90vh; overflow: auto; padding: 18px;
border-radius: 14px; background: #fff; color: #1f2937;
box-
shadow: 0 20px 60px rgb(0 0 0 / 38%);
}
header { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
h2 { flex: 1; margin: 0; font-size: 19px; }
#close { border: 0; background: transparent; font-size: 25px; cursor: pointer; color: #64748b; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
label { font-weight: 700; }
textarea {
display: block; width: 100%; min-height: 120px; margin-top: 6px; padding: 10px;
resize: vertical; border: 1px solid #cbd5e1; border-radius: 8px; color: inherit; background: #fff;
}
.hint { margin-top: 5px; color: #64748b; font-size: 12px; font-weight: 400; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin-top: 16px; }
.primary, .secondary { border-radius: 8px; padding: 9px 14px; cursor: pointer; font-weight: 700; }
.primary { border: 1px solid #f97316; background: #f97316; color: white; }
.secondary { border: 1px solid #cbd5e1; background: #fff; color: #334155; }
#st