您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在用户资料页添加“下载10条回答”,自己主页/他人主页都适用。
// ==UserScript== // @name Zhihu Answer Downloader // @namespace https://tampermonkey.net/ // @version 0.2 // @description 在用户资料页添加“下载10条回答”,自己主页/他人主页都适用。 // @match https://www.zhihu.com/people/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; /* ========== 通用工具 ========== */ const sleep = ms => new Promise(r => setTimeout(r, ms)); const downloadTxt = (name, content) => { const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = name; document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); }; /* ========== 抓取回答并下载 ========== */ async function grabFirst10Answers() { const btn = document.getElementById('zhihu-dl-btn'); btn.disabled = true; btn.innerText = '准备中…'; /* 1. 向下滚动直到 ≥10 条回答或最多滚 20 次 */ let tries = 0; while (document.querySelectorAll('div.List-item').length < 10 && tries < 20) { window.scrollBy(0, window.innerHeight); await sleep(800); tries++; } /* 2. 展开「阅读全文」 */ const readMore = Array.from(document.querySelectorAll('button.Button--plain')) .filter(b => /阅读全文/.test(b.innerText)) .slice(0, 10); for (const b of readMore) { b.click(); await sleep(400); } /* 3. 组装 TXT */ const items = Array.from(document.querySelectorAll('div.List-item')).slice(0, 10); const txt = items.map((it, i) => { const q = it.querySelector('a.QuestionItem-title, a[data-za-detail-view-element_name="Title"]')?.innerText.trim() || `Question ${i + 1}`; const a = it.querySelector('span.RichText')?.innerText.trim().replace(/\s+\n/g, '\n') || ''; return `Q${i + 1}: ${q}\nA${i + 1}: ${a}\n\n`; }).join(''); /* 4. 下载 */ downloadTxt('zhihu_answers.txt', txt); btn.innerText = '已下载'; } /* ========== 插入按钮 ========== */ function insertButton() { if (document.getElementById('zhihu-dl-btn')) return; // 已插入 // ① 先找「关注」按钮 let anchor = Array.from(document.querySelectorAll('button')) .find(b => /关注(他|她)?$/.test(b.textContent.trim())); // ② 若无,再找「编辑个人资料」/「编辑资料」 if (!anchor) { anchor = Array.from(document.querySelectorAll('button')) .find(b => /编辑.*资料/.test(b.textContent.trim())); } // ③ 再不行,就放到 .ProfileHeader-operation 容器里 if (!anchor) { anchor = document.querySelector('.ProfileHeader-operation'); if (!anchor) return; // 还没渲染出来,先退出 } // 构造下载按钮 const dlBtn = document.createElement('button'); dlBtn.id = 'zhihu-dl-btn'; dlBtn.className = 'Button Button--primary Button--blue'; // 跟知乎原生按钮保持一致 dlBtn.style.marginLeft = '8px'; dlBtn.textContent = '下载10条回答'; dlBtn.onclick = grabFirst10Answers; // 插入 if (anchor.parentNode.classList.contains('ProfileHeader-operation')) { // anchor 是容器 anchor.appendChild(dlBtn); } else { anchor.parentNode.insertBefore(dlBtn, anchor.nextSibling); } } /* ========== 监听页面变化,路由切换也能保持 ========== */ const obs = new MutationObserver(insertButton); obs.observe(document.body, { childList: true, subtree: true }); insertButton(); // 首次执行 })();