您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一键获取并显示答主MCN数据,可同步数据库更新信息。一次收集,长效显示。
// ==UserScript== // @name Zhihu MCN | 知乎答主MCN信息显示 // @namespace https://github.com/ByronLeeeee/zhihu-mcn-data/ // @version 1.3 // @description 一键获取并显示答主MCN数据,可同步数据库更新信息。一次收集,长效显示。 // @author ByronLeeeee // @match *://www.zhihu.com/question/* // @match *://www.zhihu.com/people/* // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_openInTab // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @grant GM_addStyle // ==/UserScript== (function () { "use strict"; // GitHub配置 const GITHUB_CONFIG = { owner: "ByronLeeeee", repo: "zhihu-mcn-data", branch: "main", path: "mcn-data.json", }; // 添加样式 GM_addStyle(` .mcn-button { margin-left: 8px; padding: 2px 8px; font-size: 12px; color: #8590a6; background: none; border: 1px solid #8590a6; border-radius: 3px; cursor: pointer; } .mcn-button:hover { color: #76839b; border-color: #76839b; } .mcn-info { color: #999; font-size: 14px; margin-left: 5px; } .mcn-main-button { position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; background: #1772f6; color: white; border: none; border-radius: 50%; cursor: pointer; z-index: 1000; display: flex; align-items: center; justify-content: center; font-size: 18px; } .mcn-main-button:hover { background: #0077e6; } .mcn-sub-buttons { position: fixed; bottom: 80px; right: 20px; display: flex; flex-direction: column; align-items: flex-end; z-index: 999; } .mcn-sub-button { margin-bottom: 10px; padding: 8px 16px; background: #1772f6; color: white; border: none; border-radius: 4px; cursor: pointer; display: none; } .mcn-sub-button:hover { background: #389e0d; } .status-message { position: fixed; bottom: 70px; right: 20px; padding: 8px; background: rgba(0, 0, 0, 0.7); color: white; border-radius: 4px; font-size: 12px; z-index: 1000; display: none; } `); // 存储正在处理的用户ID,防止重复获取 const processingUsers = new Set(); // 数据管理器 const DataManager = { statusElement: null, mcnData: null, createStatusElement() { if (!this.statusElement) { this.statusElement = document.createElement("div"); this.statusElement.className = "status-message"; document.body.appendChild(this.statusElement); } }, showStatus(message, duration = 3000) { this.statusElement.textContent = message; this.statusElement.style.display = "block"; setTimeout(() => { this.statusElement.style.display = "none"; }, duration); }, // 添加主按钮 addMainButton() { const mainButton = document.createElement("button"); mainButton.className = "mcn-main-button"; mainButton.textContent = "MCN"; const subButtonsContainer = document.createElement("div"); subButtonsContainer.className = "mcn-sub-buttons"; const downloadButton = document.createElement("button"); downloadButton.className = "mcn-sub-button"; downloadButton.textContent = "更新MCN数据库"; downloadButton.onclick = async () => { downloadButton.disabled = true; downloadButton.textContent = "更新中..."; await this.updateMCNData(); downloadButton.disabled = false; downloadButton.textContent = "更新MCN数据库"; updateAllMCNDisplays(); }; const exportButton = document.createElement("button"); exportButton.className = "mcn-sub-button"; exportButton.textContent = "导出MCN数据"; exportButton.onclick = () => { try { this.exportData(); } catch (error) { console.error("导出按钮点击处理失败:", error); this.showStatus("导出操作失败"); } }; subButtonsContainer.appendChild(downloadButton); subButtonsContainer.appendChild(exportButton); mainButton.onclick = () => { if ( subButtonsContainer.style.display === "none" || subButtonsContainer.style.display === "" ) { subButtonsContainer.style.display = "flex"; downloadButton.style.display = "block"; exportButton.style.display = "block"; } else { subButtonsContainer.style.display = "none"; downloadButton.style.display = "none"; exportButton.style.display = "none"; } }; document.body.appendChild(mainButton); document.body.appendChild(subButtonsContainer); }, // 获取所有本地存储的MCN数据 getAllLocalData() { const localData = {}; // 从本地存储获取手动记录的数据 if (typeof GM_listValues === "function") { const keys = GM_listValues(); keys.forEach((key) => { const value = GM_getValue(key); if (value) { localData[key] = value; } }); } console.log("导出数据统计:", { 本地数据条数: Object.keys(localData).length, }); return localData; }, // 导出数据为JSON文件 exportData() { const data = this.getAllLocalData(); const dataCount = Object.keys(data).length; if (dataCount === 0) { this.showStatus("没有找到可导出的数据"); return; } const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json", }); const url = URL.createObjectURL(blob); const timestamp = new Date() .toISOString() .slice(0, 19) .replace(/[T:]/g, "-"); const a = document.createElement("a"); a.href = url; a.download = `zhihu-mcn-data-${timestamp}.json`; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 100); this.showStatus(`已导出 ${dataCount} 条MCN数据`); }, // 更新MCN数据 async updateMCNData() { try { // 从GitHub获取新数据 const data = await this.fetchFromGitHub(); // 获取本地存储的键 const keys = GM_listValues ? GM_listValues() : []; // 优先使用本地数据并保存 for (const key of Object.keys(data)) { const localValue = keys.includes(key) ? GM_getValue(key) : undefined; const valueToSave = localValue !== undefined ? localValue : data[key]; GM_setValue(key, valueToSave); } // 处理本地数据中未在data中出现的键 for (const key of keys) { if (!data.hasOwnProperty(key)) { GM_setValue(key, GM_getValue(key)); // 重新保存本地值 } } this.showStatus("已更新MCN数据"); return true; } catch (error) { console.error("更新MCN数据失败:", error); this.showStatus("更新MCN数据失败"); return false; } }, // 从GitHub获取数据 async fetchFromGitHub() { const rawUrl = `https://raw.githubusercontent.com/${GITHUB_CONFIG.owner}/${GITHUB_CONFIG.repo}/${GITHUB_CONFIG.branch}/${GITHUB_CONFIG.path}`; try { console.log("Fetching from URL:", rawUrl); // 调试信息 const response = await fetch(rawUrl); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const data = await response.json(); console.log("Fetched data:", data); // 调试信息 return data; } catch (error) { console.error("Fetch failed:", error); // 调试信息 throw error; } }, // 获取MCN信息 getMCNInfo(userId) { // 优先从本地存储获取 const localInfo = GM_getValue(userId); if (localInfo) return localInfo; }, }; // 获取MCN信息的函数(手动模式) async function fetchMCNInfo(userId, mcnButton) { if (processingUsers.has(userId)) { return; } processingUsers.add(userId); mcnButton.textContent = "获取中..."; mcnButton.disabled = true; const tab = GM_openInTab( `https://www.zhihu.com/people/${userId}?autoOpened=true`, { active: false, insert: true, } ); const checkInterval = setInterval(() => { const mcnInfo = GM_getValue(userId); if (mcnInfo !== undefined) { clearInterval(checkInterval); processingUsers.delete(userId); mcnButton.textContent = "记录MCN"; mcnButton.disabled = false; updateAllMCNDisplays(); } }, 500); setTimeout(() => { clearInterval(checkInterval); processingUsers.delete(userId); mcnButton.textContent = "记录MCN"; mcnButton.disabled = false; }, 10000); } // 更新所有MCN显示 function updateAllMCNDisplays() { const answers = document.querySelectorAll(".List-item"); answers.forEach((answer) => { const urlMeta = answer.querySelector('meta[itemprop="url"]'); if (!urlMeta) return; const userId = urlMeta.content.split("/").pop(); const nameElement = answer.querySelector(".AuthorInfo-name"); if (!nameElement) return; // 移除旧的MCN信息 const oldMcnInfo = nameElement.querySelector(".mcn-info"); if (oldMcnInfo) { oldMcnInfo.remove(); } // 添加新的MCN信息 const mcnInfo = DataManager.getMCNInfo(userId); if (mcnInfo) { const mcnElement = document.createElement("span"); mcnElement.className = "mcn-info"; mcnElement.textContent = `(MCN: ${mcnInfo})`; nameElement.appendChild(mcnElement); } }); } // 处理用户页面(用于手动获取MCN信息) function handlePeoplePage() { if (!window.location.pathname.startsWith("/people/")) { return; } const userId = window.location.pathname.split("/").pop(); const urlParams = new URLSearchParams(window.location.search); const isAutoOpened = urlParams.get("autoOpened") === "true"; setTimeout(async () => { const expandButton = document.querySelector( ".ProfileHeader-expandButton" ); if (expandButton) { expandButton.click(); } setTimeout(() => { const mcnElements = document.querySelectorAll( ".ProfileHeader-detailItem" ); let mcnInfo = ""; for (const element of mcnElements) { if (element.textContent.includes("MCN 机构")) { const mcnValue = element.querySelector( ".ProfileHeader-detailValue" ); if (mcnValue) { mcnInfo = mcnValue.textContent.trim(); // 存储到本地 GM_setValue(userId, mcnInfo); console.log("已保存MCN信息:", userId, mcnInfo); break; } } } if (isAutoOpened) { window.close(); } }, 1000); }, 1000); } // 处理问题页面 function handleQuestionPage() { if (!window.location.pathname.startsWith("/question/")) { return; } function processAnswer(answer) { if (answer.classList.contains("processed-mcn")) { return; } const authorInfo = answer.querySelector(".AuthorInfo"); if (!authorInfo) return; const urlMeta = authorInfo.querySelector('meta[itemprop="url"]'); if (!urlMeta) return; const userId = urlMeta.content.split("/").pop(); answer.classList.add("processed-mcn"); const nameElement = authorInfo.querySelector(".AuthorInfo-name"); if (nameElement && !nameElement.querySelector(".mcn-button")) { // 创建MCN按钮 const mcnButton = document.createElement("button"); mcnButton.className = "mcn-button"; mcnButton.textContent = "记录MCN"; mcnButton.onclick = () => fetchMCNInfo(userId, mcnButton); nameElement.appendChild(mcnButton); // 显示MCN信息 const mcnInfo = DataManager.getMCNInfo(userId); if (mcnInfo) { const mcnElement = document.createElement("span"); mcnElement.className = "mcn-info"; mcnElement.textContent = `(MCN: ${mcnInfo})`; nameElement.appendChild(mcnElement); } } } // 处理已有的回答 const initialAnswers = document.querySelectorAll(".List-item"); initialAnswers.forEach(processAnswer); // 监听新加载的回答 const observer = new MutationObserver((mutations) => { const answers = document.querySelectorAll( ".List-item:not(.processed-mcn)" ); answers.forEach(processAnswer); }); observer.observe(document.querySelector(".List") || document.body, { childList: true, subtree: true, }); } // 初始化 async function initialize() { DataManager.createStatusElement(); DataManager.addMainButton(); if (window.location.pathname.startsWith("/people/")) { handlePeoplePage(); } else if (window.location.pathname.startsWith("/question/")) { handleQuestionPage(); } } // 页面加载完成后初始化 window.addEventListener("load", initialize); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址