Greasy Fork

Greasy Fork is available in English.

V2EX 成分分析器

自动提取V2EX用户的所有回复,支持导出CSV和Markdown格式,10维度量化评分+AI分析用户画像

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         V2EX 成分分析器
// @namespace    http://tampermonkey.net/
// @version      1.3.1
// @description  自动提取V2EX用户的所有回复,支持导出CSV和Markdown格式,10维度量化评分+AI分析用户画像
// @author       su3sl3h06
// @license      MIT
// @match        https://www.v2ex.com/member/*
// @match        https://v2ex.com/member/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // 存储提取的数据
    let allReplies = [];
    let allTopics = [];
    let isRunning = false;
    let shouldStop = false;

    // 创建控制面板
    function createControlPanel() {
        const panel = document.createElement('div');
        panel.id = 'reply-extractor-panel';
        panel.innerHTML = `
            <div style="
                position: fixed;
                top: 100px;
                right: 20px;
                width: 320px;
                background: white;
                border: 2px solid #ccc;
                border-radius: 8px;
                padding: 20px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.15);
                z-index: 10000;
                font-family: Arial, sans-serif;
            ">
                <h3 style="margin: 0 0 15px 0; font-size: 16px; color: #333;">
                    V2EX 回复提取器
                </h3>
                
                <div style="margin-bottom: 15px;">
                    <label style="display: block; margin-bottom: 5px; font-size: 14px; color: #666;">
                        提取模式:
                    </label>
                    <select id="extract-mode" style="
                        width: 100%;
                        padding: 8px;
                        border: 1px solid #ddd;
                        border-radius: 4px;
                        font-size: 14px;
                    ">
                        <option value="all">提取所有页面(上限500条)</option>
                        <option value="custom">自定义页数</option>
                    </select>
                </div>

                <div id="custom-pages-container" style="margin-bottom: 15px; display: none;">
                    <label style="display: block; margin-bottom: 5px; font-size: 14px; color: #666;">
                        提取页数:
                    </label>
                    <input 
                        type="number" 
                        id="pages-to-extract" 
                        min="1" 
                        value="5"
                        style="
                            width: 100%;
                            padding: 8px;
                            border: 1px solid #ddd;
                            border-radius: 4px;
                            font-size: 14px;
                        "
                    />
                </div>

                <div style="margin-bottom: 15px;">
                    <label style="display: block; margin-bottom: 5px; font-size: 14px; color: #666;">
                        延迟时间(毫秒):
                    </label>
                    <input 
                        type="number" 
                        id="delay-time" 
                        min="500" 
                        value="1500"
                        style="
                            width: 100%;
                            padding: 8px;
                            border: 1px solid #ddd;
                            border-radius: 4px;
                            font-size: 14px;
                        "
                    />
                </div>

                <div style="margin-bottom: 15px;">
                    <div style="
                        background: #f5f5f5;
                        padding: 10px;
                        border-radius: 4px;
                        font-size: 13px;
                    ">
                        <div>当前页: <span id="current-page">-</span></div>
                        <div>总页数: <span id="total-pages">-</span></div>
                        <div>已提取: <span id="extracted-count">0</span> 条</div>
                        <div>状态: <span id="status">等待中</span></div>
                    </div>
                </div>

                <div style="margin-bottom: 15px;">
                    <div style="
                        width: 100%;
                        height: 20px;
                        background: #f0f0f0;
                        border-radius: 10px;
                        overflow: hidden;
                    ">
                        <div id="progress-bar" style="
                            width: 0%;
                            height: 100%;
                            background: linear-gradient(90deg, #4CAF50, #8BC34A);
                            transition: width 0.3s ease;
                        "></div>
                    </div>
                    <div style="text-align: center; font-size: 12px; color: #666; margin-top: 5px;">
                        <span id="progress-text">0%</span>
                    </div>
                </div>

                <button id="start-extract-btn" style="
                    width: 100%;
                    padding: 10px;
                    background: #4CAF50;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-size: 14px;
                    cursor: pointer;
                    margin-bottom: 10px;
                ">
                    开始提取
                </button>

                <button id="stop-extract-btn" style="
                    width: 100%;
                    padding: 10px;
                    background: #f44336;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-size: 14px;
                    cursor: pointer;
                    margin-bottom: 10px;
                    display: none;
                ">
                    停止提取
                </button>

                <button id="export-csv-btn" style="
                    width: 100%;
                    padding: 10px;
                    background: #2196F3;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-size: 14px;
                    cursor: pointer;
                    margin-bottom: 10px;
                " disabled>
                    导出 CSV
                </button>

                <button id="export-md-btn" style="
                    width: 100%;
                    padding: 10px;
                    background: #FF9800;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-size: 14px;
                    cursor: pointer;
                    margin-bottom: 10px;
                " disabled>
                    📥 导出 MD 文件
                </button>

                <button id="copy-md-btn" style="
                    width: 100%;
                    padding: 10px;
                    background: #9C27B0;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-size: 14px;
                    cursor: pointer;
                    margin-bottom: 10px;
                " disabled>
                    📋 复制 MD 内容
                </button>

                <button id="close-panel-btn" style="
                    width: 100%;
                    padding: 8px;
                    background: #fff;
                    color: #666;
                    border: 1px solid #ddd;
                    border-radius: 4px;
                    font-size: 13px;
                    cursor: pointer;
                ">
                    关闭面板
                </button>
            </div>
        `;
        document.body.appendChild(panel);
        bindEvents();
    }

    // 收集该用户自己创建的主题URL(从已提取回复中筛选)
    function collectUserAuthoredTopicUrls(username) {
        const set = new Set();
        if (!username) return set;
        allReplies.forEach(r => {
            if ((r.主题作者 || '').trim() === username && r.主题链接) {
                set.add(r.主题链接.split('#')[0]);
            }
        });
        return set;
    }

    // 抓取主题正文(标题/节点/正文),limit用于限制最多抓取数量
    async function fetchTopicsContent(urls, delayMs = 1200, limit = 30, onProgress) {
        const topics = [];
        const slice = urls.slice(0, Math.max(0, limit));
        for (let i = 0; i < slice.length; i++) {
            const url = slice[i];
            try {
                // 节流
                if (i > 0) {
                    await new Promise(r => setTimeout(r, delayMs));
                }
                const html = await fetch(url, { credentials: 'include' }).then(res => res.text());
                const parser = new DOMParser();
                const doc = parser.parseFromString(html, 'text/html');

                const title = doc.querySelector('.post-wrapper .header h1')?.textContent?.trim() ||
                               doc.querySelector('h1')?.textContent?.trim() || '';
                const node = doc.querySelector('.post-wrapper .header a[href^="/go/"]')?.textContent?.trim() || '';
                const bodyEl = doc.querySelector('.topic_content .markdown_body') || doc.querySelector('.topic_content');
                let body = bodyEl ? bodyEl.textContent.trim() : '';
                // 压缩多余空白
                body = body.replace(/\u00a0/g, ' ').replace(/\s{3,}/g, ' ').replace(/[\r\t]+/g, '').trim();

                topics.push({ 标题: title, 节点: node, 正文: body });
                if (typeof onProgress === 'function') {
                    onProgress(i + 1, slice.length);
                }
            } catch (e) {
                console.error('抓取主题失败:', url, e);
                if (typeof onProgress === 'function') {
                    onProgress(i + 1, slice.length);
                }
            }
        }
        return topics;
    }

    // 统一Toast
    function showToast(message, durationMs = 10000) {
        try {
            const toast = document.createElement('div');
            toast.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                padding: 20px 28px;
                border-radius: 12px;
                box-shadow: 0 8px 32px rgba(102, 126, 234, 0.4);
                z-index: 10001;
                font-size: 15px;
                font-weight: bold;
                text-align: center;
                line-height: 1.6;
                animation: fadeInOut ${Math.max(200, durationMs)}ms ease-in-out;
                white-space: pre-line;
            `;
            toast.innerHTML = `✅\n${message}`;

            if (!document.getElementById('toast-animation-style')) {
                const style = document.createElement('style');
                style.id = 'toast-animation-style';
                style.textContent = `
                    @keyframes fadeInOut {
                        0% { opacity: 0; transform: translate(-50%, -50%) scale(0.92); }
                        10% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
                        90% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
                        100% { opacity: 0; transform: translate(-50%, -50%) scale(0.96); }
                    }
                `;
                document.head.appendChild(style);
            }

            document.body.appendChild(toast);
            setTimeout(() => { toast.remove(); }, durationMs);
        } catch (e) {
            // 兜底
            console.log('Toast:', message);
        }
    }

    // 绑定事件
    function bindEvents() {
        // 模式切换
        document.getElementById('extract-mode').addEventListener('change', function(e) {
            const customContainer = document.getElementById('custom-pages-container');
            customContainer.style.display = e.target.value === 'custom' ? 'block' : 'none';
        });

        // 开始提取
        document.getElementById('start-extract-btn').addEventListener('click', startExtraction);

        // 停止提取
        document.getElementById('stop-extract-btn').addEventListener('click', stopExtraction);

        // 导出CSV
        document.getElementById('export-csv-btn').addEventListener('click', exportToCSV);

        // 导出MD
        document.getElementById('export-md-btn').addEventListener('click', exportToMarkdown);

        // 复制MD到剪贴板
        document.getElementById('copy-md-btn').addEventListener('click', copyMarkdownToClipboard);

        // 关闭面板
        document.getElementById('close-panel-btn').addEventListener('click', function() {
            document.getElementById('reply-extractor-panel').style.display = 'none';
        });
    }

    // 获取当前页面信息
    function getPageInfo() {
        const headerText = document.querySelector('.box .header')?.textContent || '';
        const match = headerText.match(/第\s*(\d+)\s*页\s*\/\s*共\s*(\d+)\s*页/);
        
        if (match) {
            return {
                currentPage: parseInt(match[1]),
                totalPages: parseInt(match[2])
            };
        }
        
        // 如果没有分页信息,说明只有一页
        return {
            currentPage: 1,
            totalPages: 1
        };
    }

    // 提取当前页面的回复
    function extractCurrentPage() {
        const replies = [];
        const dockAreas = document.querySelectorAll('.dock_area');
        
        dockAreas.forEach((dockArea, index) => {
            try {
                // 获取时间
                const timeElement = dockArea.querySelector('.fr .fade');
                const time = timeElement ? timeElement.textContent.trim() : '';

                // 获取回复信息
                const graySpan = dockArea.querySelector('.gray');
                if (!graySpan) return;

                // 获取主题作者
                const authorLink = graySpan.querySelector('a[href^="/member/"]');
                const author = authorLink ? authorLink.textContent.trim() : '';

                // 获取板块
                const boardLink = graySpan.querySelector('a[href^="/go/"]');
                const board = boardLink ? boardLink.textContent.trim() : '';

                // 获取主题标题和链接
                const topicLink = graySpan.querySelector('a[href^="/t/"]');
                const topicTitle = topicLink ? topicLink.textContent.trim() : '';
                const topicUrl = topicLink ? 'https://www.v2ex.com' + topicLink.getAttribute('href') : '';

                // 获取回复内容
                let replyContent = '';
                const nextInner = dockArea.nextElementSibling;
                if (nextInner && (nextInner.classList.contains('inner') || nextInner.classList.contains('cell'))) {
                    const contentDiv = nextInner.querySelector('.reply_content');
                    if (contentDiv) {
                        replyContent = contentDiv.textContent.trim();
                    }
                }

                if (replyContent) {
                    replies.push({
                        时间: time,
                        主题作者: author,
                        板块: board,
                        主题标题: topicTitle,
                        主题链接: topicUrl,
                        回复内容: replyContent
                    });
                }
            } catch (error) {
                console.error('提取回复时出错:', error);
            }
        });

        return replies;
    }

    // 更新UI
    function updateUI(currentPage, totalPages, extractedCount, status, progress) {
        document.getElementById('current-page').textContent = currentPage;
        document.getElementById('total-pages').textContent = totalPages;
        document.getElementById('extracted-count').textContent = extractedCount;
        document.getElementById('status').textContent = status;
        document.getElementById('progress-bar').style.width = progress + '%';
        document.getElementById('progress-text').textContent = Math.round(progress) + '%';
    }

    // 开始提取
    async function startExtraction() {
        if (isRunning) return;

        isRunning = true;
        shouldStop = false;
        allReplies = [];
        allTopics = [];

        // 更新按钮状态
        document.getElementById('start-extract-btn').style.display = 'none';
        document.getElementById('stop-extract-btn').style.display = 'block';
        document.getElementById('export-csv-btn').disabled = true;
        document.getElementById('export-md-btn').disabled = true;
        document.getElementById('copy-md-btn').disabled = true;

        // 获取配置
        const mode = document.getElementById('extract-mode').value;
        const customPages = parseInt(document.getElementById('pages-to-extract').value) || 5;
        const delay = parseInt(document.getElementById('delay-time').value) || 1500;

        // 获取页面信息
        const pageInfo = getPageInfo();
        const totalPages = mode === 'all' ? pageInfo.totalPages : Math.min(customPages, pageInfo.totalPages);
        
        updateUI(pageInfo.currentPage, totalPages, 0, '正在提取...', 0);

        try {
            // 提取当前页
            const currentReplies = extractCurrentPage();
            allReplies.push(...currentReplies);
            if (allReplies.length >= 500) {
                allReplies = allReplies.slice(0, 500);
                updateUI(pageInfo.currentPage, totalPages, allReplies.length, '已达到500条上限,停止提取', (pageInfo.currentPage / totalPages) * 100);
                shouldStop = true;
            }
            updateUI(pageInfo.currentPage, totalPages, allReplies.length, '正在提取...', 
                    (pageInfo.currentPage / totalPages) * 100);

            // 如果需要提取更多页
            if (totalPages > pageInfo.currentPage && !shouldStop) {
                for (let page = pageInfo.currentPage + 1; page <= totalPages; page++) {
                    if (allReplies.length >= 500) break;
                    if (shouldStop) break;

                    updateUI(page, totalPages, allReplies.length, `正在加载第 ${page} 页...`, 
                            ((page - 1) / totalPages) * 100);

                    // 等待延迟
                    await new Promise(resolve => setTimeout(resolve, delay));

                    // 跳转到下一页
                    const nextPageUrl = window.location.pathname + '?p=' + page;
                    await loadPage(nextPageUrl);

                    // 提取新页面的回复
                    const newReplies = extractCurrentPage();
                    allReplies.push(...newReplies);
                    if (allReplies.length >= 500) {
                        allReplies = allReplies.slice(0, 500);
                        shouldStop = true;
                    }
                    
                    updateUI(page, totalPages, allReplies.length, '正在提取...', 
                            (page / totalPages) * 100);
                }
            }

            // 无论是否达到上限/主动停止,均尝试抓取该用户创建的主题内容
            const username = window.location.pathname.match(/\/member\/([^\/]+)/)?.[1] || '';
            try {
                const topicUrls = collectUserAuthoredTopicUrls(username);
                if (topicUrls.size > 0) {
                    updateUI(totalPages, totalPages, allReplies.length, `提取完成,正在抓取主题正文(${topicUrls.size})...`, 95);
                    const delayMs = parseInt(document.getElementById('delay-time').value) || 1500;
                    allTopics = await fetchTopicsContent(
                        Array.from(topicUrls),
                        delayMs,
                        30,
                        (done, total) => {
                            const pct = 95 + Math.min(5, (done / Math.max(1, total)) * 5);
                            updateUI(totalPages, totalPages, allReplies.length, `抓取主题正文 ${done}/${total} ...`, pct);
                        }
                    );
                    showToast(`提取完成\n抓取到用户创建的主题:${allTopics.length} 篇`);
                }
            } catch (e) {
                console.error('抓取主题正文失败:', e);
            }
            updateUI(totalPages, totalPages, allReplies.length, '提取完成!', 100);

        } catch (error) {
            console.error('提取过程出错:', error);
            updateUI('-', '-', allReplies.length, '提取出错', 0);
        }

        // 恢复按钮状态
        document.getElementById('start-extract-btn').style.display = 'block';
        document.getElementById('stop-extract-btn').style.display = 'none';
        document.getElementById('export-csv-btn').disabled = false;
        document.getElementById('export-md-btn').disabled = false;
        document.getElementById('copy-md-btn').disabled = false;
        isRunning = false;
    }

    // 停止提取
    function stopExtraction() {
        shouldStop = true;
        updateUI('-', '-', allReplies.length, '正在停止...', 0);
    }

    // 加载页面
    function loadPage(url) {
        return new Promise((resolve, reject) => {
            fetch(url)
                .then(response => response.text())
                .then(html => {
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(html, 'text/html');
                    
                    // 替换主内容区域
                    const newMain = doc.querySelector('#Main');
                    const oldMain = document.querySelector('#Main');
                    if (newMain && oldMain) {
                        oldMain.innerHTML = newMain.innerHTML;
                    }
                    
                    // 更新URL
                    window.history.pushState({}, '', url);
                    
                    resolve();
                })
                .catch(error => {
                    console.error('加载页面失败:', error);
                    reject(error);
                });
        });
    }

    // 导出为CSV
    function exportToCSV() {
        if (allReplies.length === 0) {
            showToast('没有数据可以导出!');
            return;
        }

        // CSV头部
        const headers = ['时间', '主题作者', '板块', '主题标题', '主题链接', '回复内容'];
        
        // 转换为CSV格式
        let csv = '\uFEFF'; // 添加BOM以支持中文
        csv += headers.join(',') + '\n';

        allReplies.forEach(reply => {
            const row = headers.map(header => {
                let value = reply[header] || '';
                // 转义双引号并用双引号包裹包含逗号、换行或双引号的字段
                value = value.replace(/"/g, '""');
                if (value.includes(',') || value.includes('\n') || value.includes('"')) {
                    value = '"' + value + '"';
                }
                return value;
            });
            csv += row.join(',') + '\n';
        });

        // 创建下载
        const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);
        
        // 获取用户名
        const username = window.location.pathname.match(/\/member\/([^\/]+)/)?.[1] || 'user';
        const filename = `v2ex_${username}_replies_${new Date().getTime()}.csv`;
        
        link.setAttribute('href', url);
        link.setAttribute('download', filename);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        showToast(`成功导出 ${allReplies.length} 条回复!`);
    }

    // 导出为Markdown格式(用于AI分析)
    function exportToMarkdown() {
        if (allReplies.length === 0) {
            showToast('没有数据可以导出!');
            return;
        }

        // 文本清洗,节约token
        const sanitizeForLLM = (text) => {
            let t = (text || '').toString();
            // 移除URL
            t = t.replace(/https?:\/\/[^\s)]+/g, '');
            // 去掉强调/代码等常见Markdown符号
            t = t.replace(/\*\*|__|`/g, '');
            // 折叠多空格
            t = t.replace(/\s{2,}/g, ' ');
            // 规范换行
            t = t.replace(/\n{3,}/g, '\n\n');
            return t.trim();
        };

        // 获取用户名
        const username = window.location.pathname.match(/\/member\/([^\/]+)/)?.[1] || 'unknown_user';
        
        // 统计信息
        const totalReplies = allReplies.length;
        const boards = [...new Set(allReplies.map(r => r.板块))];
        const boardStats = {};
        allReplies.forEach(reply => {
            const board = reply.板块 || '未知';
            boardStats[board] = (boardStats[board] || 0) + 1;
        });
        const sortedBoards = Object.entries(boardStats).sort((a, b) => b[1] - a[1]);

        // 构建Markdown内容
        let markdown = `# V2EX 用户画像分析任务

## 📋 任务说明

你是一位专业的用户行为分析师。现在需要你根据下方提供的V2EX用户回复数据,深入分析该用户的完整人物画像。

---

## 👤 分析对象

- **用户名**: ${username}
- **数据来源**: V2EX (一个面向创意工作者的中文社区)
- **回复总数**: ${totalReplies} 条
- **活跃板块数**: ${boards.length} 个
- **数据提取时间**: ${new Date().toLocaleString('zh-CN')}

---

## 📊 基础数据概览

### 板块活跃度统计(Top 10)

| 排名 | 板块名称 | 回复次数 | 占比 |
|------|---------|---------|------|
`;

        // 添加板块统计
        sortedBoards.slice(0, 10).forEach((item, index) => {
            const [board, count] = item;
            const percentage = ((count / totalReplies) * 100).toFixed(1);
            markdown += `| ${index + 1} | ${board} | ${count} | ${percentage}% |\n`;
        });

        markdown += `\n---

## 🧵 用户创建的主题(采样)

从用户创建的主题中抽取正文内容(最多展示30篇,用于辅助AI判断立场与真实度):

${(allTopics && allTopics.length ? allTopics : []).map((t, idx) => `### 主题 #${idx + 1}\n\n节点: ${t.节点 || '-'}\n标题: ${t.标题 || '-'}\n\n正文:\n> ${(t.正文 || '').split('\\n').join('\\n> ')}\n\n---\n`).join('')}

## 💬 完整回复记录(最多500条)

以下为该用户的回复内容(按时间从新到旧,最多500条):

`;

        // 添加所有回复(最多500条)
        (allReplies.slice(0, 500)).forEach((reply, index) => {
            markdown += `### 回复 #${index + 1}\n\n时间: ${reply.时间}  \n板块: ${reply.板块}  \n主题: ${reply.主题标题}  \n主题作者: ${reply.主题作者}  \n回复内容:\n> ${reply.回复内容.split('\\n').join('\\n> ')}\n\n---\n\n`;
        });

        // 添加分析要求
        markdown += `
---

## 🎯 分析任务要求

请基于以上所有回复数据,从以下维度深入分析该用户,并生成一份详细的**量化用户画像报告**。

**重要**: 每个维度必须按照给定的评分标准打分,不能凭主观感觉!

---

## 📊 评分标准与分析维度

### 1. 技术能力评估 💻 (1-10分)

**评分标准**:
- **1-3分**: 非技术用户,基本不涉及技术讨论
- **4-6分**: 技术爱好者,了解基础技术概念,偶尔讨论技术话题
- **7-8分**: 技术从业者,熟悉特定技术栈,经常分享技术见解
- **9-10分**: 技术专家,深入讨论底层原理,能解决复杂技术问题

**量化指标**:
- 技术相关回复占比: ____%
- 提及的技术关键词数量: ___个
- 技术深度(是否涉及原理/架构/底层): 是/否

**分析要点**:
- 主要技术栈(编程语言、框架、工具等)
- 技术广度与深度
- 是否有专业技术背景
- 对新技术的接受程度

**评分**: ___/10 分

---

### 2. 消费能力评估 💰 (1-10分)

**评分标准**:
- **1-3分**: 消费保守,注重性价比,多讨论如何省钱
- **4-6分**: 消费适中,偶尔购买中高端产品,理性消费
- **7-8分**: 消费能力较强,经常购买中高端产品,品质优先
- **9-10分**: 消费能力很强,购买高端/奢侈品,价格不敏感

**量化指标**:
- 提及的产品价格范围: ¥___ - ¥___
- 高价值物品(>5000元)提及次数: ___次
- 投资/理财相关讨论: ___次

**分析要点**:
- 提及的具体产品及价格(如手机、电脑、旅行等)
- 消费观念(性价比/品质/奢侈)
- 是否有投资理财意识
- 经济压力感知

**评分**: ___/10 分

---

### 3. 专业深度评估 🎓 (1-10分)

**评分标准**:
- **1-3分**: 泛泛而谈,缺乏专业见解
- **4-6分**: 在某些领域有一定见解,但不够深入
- **7-8分**: 在1-2个领域有专业见解,能给出专业建议
- **9-10分**: 多领域专家,回复经常被认可,有行业影响力

**量化指标**:
- 专业术语使用频率: 高/中/低
- 深度分析回复占比: ____%
- 被@请教的次数: ___次(从回复中推断)

**分析要点**:
- 专业领域识别(职业相关)
- 知识深度与广度
- 是否经常解答他人问题
- 专业表达能力

**评分**: ___/10 分

---

### 4. 社交活跃度 👥 (1-10分)

**评分标准**:
- **1-3分**: 很少互动,回复简短,不主动交流
- **4-6分**: 适度互动,偶尔参与讨论,回复中等长度
- **7-8分**: 活跃互动,经常@他人,回复详细,乐于助人
- **9-10分**: 高度活跃,社区KOL,有固定交流圈子

**量化指标**:
- 平均回复长度: ___字
- @他人次数: ___次
- 回复情感倾向: 友善/中性/冷淡
- 活跃板块数量: ___个

**分析要点**:
- 交流主动性
- 互动频率和质量
- 是否有固定交流对象
- 社交风格(热情/礼貌/高冷)

**评分**: ___/10 分

---

### 5. 兴趣广度评估 🎮 (1-10分)

**评分标准**:
- **1-3分**: 兴趣单一,只关注1-2个领域
- **4-6分**: 兴趣适中,关注3-5个不同领域
- **7-8分**: 兴趣广泛,跨多个领域(科技/生活/娱乐等)
- **9-10分**: 兴趣极其广泛,涉猎各个领域,博学多才

**量化指标**:
- 涉及的主题类别数: ___个
- 话题分散度: 高/中/低
- 跨领域讨论占比: ____%

**分析要点**:
- 主要兴趣点列表
- 兴趣深度(入门/进阶/专家)
- 是否有特别突出的兴趣
- 兴趣是否与职业相关

**评分**: ___/10 分

---

### 6. 情绪稳定性 🧩 (1-10分)

**评分标准**:
- **1-3分**: 情绪波动大,经常抱怨/焦虑/愤怒
- **4-6分**: 情绪一般,偶尔流露负面情绪
- **7-8分**: 情绪稳定,多数回复平和理性
- **9-10分**: 情绪非常稳定,始终保持积极乐观态度

**量化指标**:
- 负面情绪词汇出现次数: ___次(如:郁闷、烦、气、无语等)
- 正面情绪词汇出现次数: ___次(如:开心、爽、赞、喜欢等)
- 中性客观回复占比: ____%

**分析要点**:
- 主要情绪倾向
- 压力/焦虑表现
- 对挫折的态度
- 生活满意度

**评分**: ___/10 分

---

### 7. 生活品质指数 🌟 (1-10分)

**评分标准**:
- **1-3分**: 生活压力大,多讨论省钱、焦虑、工作压力
- **4-6分**: 生活一般,工作生活平衡,偶尔享受生活
- **7-8分**: 生活品质较高,经常旅行/美食/娱乐
- **9-10分**: 生活品质很高,追求精致生活,时间自由

**量化指标**:
- 休闲娱乐相关回复: ___次
- 旅行/美食/爱好讨论: ___次
- 加班/压力相关吐槽: ___次

**分析要点**:
- 工作生活平衡
- 休闲娱乐方式
- 生活态度(积极/佛系/焦虑)
- 是否有生活追求

**评分**: ___/10 分

---

### 8. 影响力指数 🏆 (1-10分)

**评分标准**:
- **1-3分**: 无影响力,回复少人关注
- **4-6分**: 影响力一般,偶尔有高质量回复
- **7-8分**: 有一定影响力,回复经常被认可
- **9-10分**: 社区意见领袖,高质量输出,被广泛认可

**量化指标**:
- 回复质量(是否有深度见解): 高/中/低
- 是否解答他人问题: ___次
- 是否引发讨论: 是/否
- 回复被感谢的可能性: 高/中/低(从上下文推断)

**分析要点**:
- 内容质量
- 专业权威性
- 对他人的帮助程度
- 在社区的认可度

**评分**: ___/10 分

---

### 9. 学习成长力 📈 (1-10分)

**评分标准**:
- **1-3分**: 学习意愿低,少讨论新知识/新技术
- **4-6分**: 学习意愿一般,偶尔接触新事物
- **7-8分**: 学习意愿强,经常研究新技术/新领域
- **9-10分**: 持续学习,快速接受新事物,有成长型思维

**量化指标**:
- 提问/求教次数: ___次
- 学习/研究相关讨论: ___次
- 对新技术/新产品的关注度: 高/中/低

**分析要点**:
- 学习态度
- 对新事物的接受度
- 是否主动求知
- 成长型/固定型思维

**评分**: ___/10 分

---

### 10. 真实度/可信度 🎭 (1-10分)

**评分标准**:
- **1-3分**: 疑似水军/发帖员,频繁引战,内容前后矛盾,编故事明显
- **4-6分**: 部分内容夸张或不实,偶尔引战,但大部分内容真实
- **7-8分**: 内容基本真实可信,偶有夸张但无恶意
- **9-10分**: 高度真实,言行一致,内容经得起推敲,真诚度高

**量化指标**:
- 内容前后一致性: 高/中/低
- 引战/攻击性言论次数: ___次
- 疑似营销/广告内容: ___次
- 逻辑矛盾或编故事迹象: ___处

**重点识别特征**:

**🚩 发帖员/水军特征**:
- 短期内大量发帖/回复(不正常的活跃度)
- 重复发布相似内容或套路化回复
- 频繁推荐特定产品/服务/链接
- 账号注册时间短但活跃度极高
- 回复内容空洞,缺乏个人观点

**🚩 故意引战特征**:
- 频繁使用攻击性、煽动性语言
- 刻意挑起争议话题
- 对不同观点采取极端对立态度
- 喜欢"抬杠",缺乏建设性讨论
- 制造焦虑或贩卖恐慌

**🚩 编故事/造假特征**:
- 前后描述自相矛盾(职业/收入/经历不一致)
- 过度夸张的个人经历
- 时间线混乱(如"去年"的事在不同回复中日期不符)
- 细节模糊或经不起推敲
- 频繁更换人设或立场

**✅ 真实可信特征**:
- 长期稳定的发言风格
- 内容具体详细,有个人特色
- 前后观点一致,言行相符
- 分享真实经验教训(包括失败)
- 对话真诚,愿意承认不足

**分析要点**:
- 内容真实性(是否有明显编造迹象)
- 动机纯粹性(是否有营销/引导目的)
- 立场一致性(观点是否前后矛盾)
- 言行一致性(说的和做的是否匹配)
- 互动真诚度(回复是否真心还是套路)

**评分**: ___/10 分

---

### 11. 生活地域判断 🏠

**不评分,仅推断**

**分析要点**:
- **居住城市**: _____(根据讨论的地域板块、提及的地点)
- **证据强度**: 强/中/弱
- **可能的活动范围**: _____
- **是否有地域相关特征**: _____

---

## 📋 综合评价

### 综合画像卡片

| 维度 | 评分 | 等级 | 关键特征 |
|------|------|------|---------|
| 技术能力 | __/10 | 专家/从业者/爱好者/无 | _____ |
| 消费能力 | __/10 | 高/中高/中/中低/低 | _____ |
| 专业深度 | __/10 | 专家/资深/中级/初级 | _____ |
| 社交活跃度 | __/10 | 非常活跃/活跃/一般/不活跃 | _____ |
| 兴趣广度 | __/10 | 非常广泛/广泛/适中/单一 | _____ |
| 情绪稳定性 | __/10 | 非常稳定/稳定/一般/不稳定 | _____ |
| 生活品质 | __/10 | 优质/良好/一般/较差 | _____ |
| 影响力 | __/10 | KOL/活跃/普通/潜水 | _____ |
| 学习成长力 | __/10 | 强/较强/一般/弱 | _____ |
| 真实度/可信度 | __/10 | 高度真实/基本可信/存疑/疑似造假 | _____ |

**综合评分**: ___/100 分

---

### 用户画像总结 (200-300字)

[用一段话描述该用户的整体特征,包括:
- 基本信息(年龄段、地域、职业推断)
- 核心特征(最突出的2-3个特点)
- 兴趣爱好概况
- 性格特征
- 生活状态
- 最具代表性的标签]

---

### 特殊标签 🏷️

请根据分析给出3-5个最具代表性的标签:

\`#标签1\` \`#标签2\` \`#标签3\` \`#标签4\` \`#标签5\`

---

### 核心洞察 💡

**优势特征**(最突出的3个方面):
1. _____
2. _____
3. _____

**潜在需求**(可能感兴趣的3个方向):
1. _____
2. _____
3. _____

**性格特质**(MBTI参考):
- 可能的性格类型: _____
- 主要性格特征: _____

---

## 📋 输出格式要求

1. **严格按照评分标准打分**,不得凭感觉评分
2. **必须列出量化指标的具体数值**
3. **每个评分必须有具体的证据支撑**(引用回复内容)
4. **填写综合评价表格**
5. **生成200-300字的用户画像总结**
6. **给出3-5个标签**
7. **不用重新输出评分标准,只给出要求的结果**

---

## ⚡ 开始分析

请开始你的专业量化分析,注意:

✅ **量化优先**: 先统计量化指标,再基于数据打分  
✅ **证据支撑**: 每个结论都要引用具体回复  
✅ **客观准确**: 基于实际数据,不要过度臆测  
✅ **标准一致**: 严格按照评分标准,不得凭主观感觉  

---

*本文档由 V2EX 用户回复提取器自动生成*  
*提取时间: ${new Date().toLocaleString('zh-CN')}*  
*数据量: ${totalReplies} 条回复*  
*评分体系: 10维度量化评估 (总分100分)*  
*版权: su3sl3h06*
`;

        // 创建下载
        const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8;' });
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);
        
        const filename = `v2ex_${username}_analysis_prompt_${new Date().getTime()}.md`;
        
        link.setAttribute('href', url);
        link.setAttribute('download', filename);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        showToast(`成功导出分析提示词!\n文件名: ${filename}\n回复数: ${totalReplies} 条`);
    }

    // 复制Markdown内容到剪贴板
    async function copyMarkdownToClipboard() {
        if (allReplies.length === 0) {
            showToast('没有数据可以复制!');
            return;
        }

        try {
            // 获取用户名
            const username = window.location.pathname.match(/\/member\/([^\/]+)/)?.[1] || 'unknown_user';
            
            // 统计信息
            const totalReplies = allReplies.length;
            const boards = [...new Set(allReplies.map(r => r.板块))];
            const boardStats = {};
            allReplies.forEach(reply => {
                const board = reply.板块 || '未知';
                boardStats[board] = (boardStats[board] || 0) + 1;
            });
            const sortedBoards = Object.entries(boardStats).sort((a, b) => b[1] - a[1]);

            // 构建Markdown内容(与exportToMarkdown相同)
            let markdown = `# V2EX 用户画像分析任务

## 📋 任务说明

你是一位专业的用户行为分析师。现在需要你根据下方提供的V2EX用户回复数据,深入分析该用户的完整人物画像。

---

## 👤 分析对象

- **用户名**: ${username}
- **数据来源**: V2EX (一个面向创意工作者的中文社区)
- **回复总数**: ${totalReplies} 条
- **活跃板块数**: ${boards.length} 个
- **数据提取时间**: ${new Date().toLocaleString('zh-CN')}

---

## 📊 基础数据概览

### 板块活跃度统计(Top 10)

| 排名 | 板块名称 | 回复次数 | 占比 |
|------|---------|---------|------|
`;

            // 添加板块统计
            sortedBoards.slice(0, 10).forEach((item, index) => {
                const [board, count] = item;
                const percentage = ((count / totalReplies) * 100).toFixed(1);
                markdown += `| ${index + 1} | ${board} | ${count} | ${percentage}% |\n`;
            });

            markdown += `\n---

## 🧵 用户创建的主题(采样)

从用户创建的主题中抽取正文内容(最多展示30篇,用于辅助AI判断立场与真实度):

${(allTopics && allTopics.length ? allTopics : []).map((t, idx) => `### 主题 #${idx + 1}\n\n**节点**: ${t.节点 || '-'}  \n**标题**: ${t.标题 || '-'}\n\n**正文节选**:\n> ${(t.正文 || '').split('\n').slice(0, 12).join('\n> ')}\n\n---\n`).join('')}

## 💬 完整回复记录(最多500条)

以下为该用户的所有回复内容,按时间顺序排列(从新到旧):

`;

            // 添加所有回复
            allReplies.forEach((reply, index) => {
                markdown += `### 回复 #${index + 1}

时间: ${reply.时间}  
板块: ${reply.板块}  
主题: ${reply.主题标题}  
主题作者: ${reply.主题作者}  
回复内容:
> ${reply.回复内容.split('\n').join('\n> ')}

---

`;
            });

            // 添加分析要求(与exportToMarkdown相同的完整内容)
            markdown += `
---

## 🎯 分析任务要求

请基于以上所有回复数据,从以下维度深入分析该用户,并生成一份详细的**量化用户画像报告**。

**重要**: 每个维度必须按照给定的评分标准打分,不能凭主观感觉!

---

## 📊 评分标准与分析维度

### 1. 技术能力评估 💻 (1-10分)

**评分标准**:
- **1-3分**: 非技术用户,基本不涉及技术讨论
- **4-6分**: 技术爱好者,了解基础技术概念,偶尔讨论技术话题
- **7-8分**: 技术从业者,熟悉特定技术栈,经常分享技术见解
- **9-10分**: 技术专家,深入讨论底层原理,能解决复杂技术问题

**量化指标**:
- 技术相关回复占比: ____%
- 提及的技术关键词数量: ___个
- 技术深度(是否涉及原理/架构/底层): 是/否

**分析要点**:
- 主要技术栈(编程语言、框架、工具等)
- 技术广度与深度
- 是否有专业技术背景
- 对新技术的接受程度

**评分**: ___/10 分

---

### 2. 消费能力评估 💰 (1-10分)

**评分标准**:
- **1-3分**: 消费保守,注重性价比,多讨论如何省钱
- **4-6分**: 消费适中,偶尔购买中高端产品,理性消费
- **7-8分**: 消费能力较强,经常购买中高端产品,品质优先
- **9-10分**: 消费能力很强,购买高端/奢侈品,价格不敏感

**量化指标**:
- 提及的产品价格范围: ¥___ - ¥___
- 高价值物品(>5000元)提及次数: ___次
- 投资/理财相关讨论: ___次

**分析要点**:
- 提及的具体产品及价格(如手机、电脑、旅行等)
- 消费观念(性价比/品质/奢侈)
- 是否有投资理财意识
- 经济压力感知

**评分**: ___/10 分

---

### 3. 专业深度评估 🎓 (1-10分)

**评分标准**:
- **1-3分**: 泛泛而谈,缺乏专业见解
- **4-6分**: 在某些领域有一定见解,但不够深入
- **7-8分**: 在1-2个领域有专业见解,能给出专业建议
- **9-10分**: 多领域专家,回复经常被认可,有行业影响力

**量化指标**:
- 专业术语使用频率: 高/中/低
- 深度分析回复占比: ____%
- 被@请教的次数: ___次(从回复中推断)

**分析要点**:
- 专业领域识别(职业相关)
- 知识深度与广度
- 是否经常解答他人问题
- 专业表达能力

**评分**: ___/10 分

---

### 4. 社交活跃度 👥 (1-10分)

**评分标准**:
- **1-3分**: 很少互动,回复简短,不主动交流
- **4-6分**: 适度互动,偶尔参与讨论,回复中等长度
- **7-8分**: 活跃互动,经常@他人,回复详细,乐于助人
- **9-10分**: 高度活跃,社区KOL,有固定交流圈子

**量化指标**:
- 平均回复长度: ___字
- @他人次数: ___次
- 回复情感倾向: 友善/中性/冷淡
- 活跃板块数量: ___个

**分析要点**:
- 交流主动性
- 互动频率和质量
- 是否有固定交流对象
- 社交风格(热情/礼貌/高冷)

**评分**: ___/10 分

---

### 5. 兴趣广度评估 🎮 (1-10分)

**评分标准**:
- **1-3分**: 兴趣单一,只关注1-2个领域
- **4-6分**: 兴趣适中,关注3-5个不同领域
- **7-8分**: 兴趣广泛,跨多个领域(科技/生活/娱乐等)
- **9-10分**: 兴趣极其广泛,涉猎各个领域,博学多才

**量化指标**:
- 涉及的主题类别数: ___个
- 话题分散度: 高/中/低
- 跨领域讨论占比: ____%

**分析要点**:
- 主要兴趣点列表
- 兴趣深度(入门/进阶/专家)
- 是否有特别突出的兴趣
- 兴趣是否与职业相关

**评分**: ___/10 分

---

### 6. 情绪稳定性 🧩 (1-10分)

**评分标准**:
- **1-3分**: 情绪波动大,经常抱怨/焦虑/愤怒
- **4-6分**: 情绪一般,偶尔流露负面情绪
- **7-8分**: 情绪稳定,多数回复平和理性
- **9-10分**: 情绪非常稳定,始终保持积极乐观态度

**量化指标**:
- 负面情绪词汇出现次数: ___次(如:郁闷、烦、气、无语等)
- 正面情绪词汇出现次数: ___次(如:开心、爽、赞、喜欢等)
- 中性客观回复占比: ____%

**分析要点**:
- 主要情绪倾向
- 压力/焦虑表现
- 对挫折的态度
- 生活满意度

**评分**: ___/10 分

---

### 7. 生活品质指数 🌟 (1-10分)

**评分标准**:
- **1-3分**: 生活压力大,多讨论省钱、焦虑、工作压力
- **4-6分**: 生活一般,工作生活平衡,偶尔享受生活
- **7-8分**: 生活品质较高,经常旅行/美食/娱乐
- **9-10分**: 生活品质很高,追求精致生活,时间自由

**量化指标**:
- 休闲娱乐相关回复: ___次
- 旅行/美食/爱好讨论: ___次
- 加班/压力相关吐槽: ___次

**分析要点**:
- 工作生活平衡
- 休闲娱乐方式
- 生活态度(积极/佛系/焦虑)
- 是否有生活追求

**评分**: ___/10 分

---

### 8. 影响力指数 🏆 (1-10分)

**评分标准**:
- **1-3分**: 无影响力,回复少人关注
- **4-6分**: 影响力一般,偶尔有高质量回复
- **7-8分**: 有一定影响力,回复经常被认可
- **9-10分**: 社区意见领袖,高质量输出,被广泛认可

**量化指标**:
- 回复质量(是否有深度见解): 高/中/低
- 是否解答他人问题: ___次
- 是否引发讨论: 是/否
- 回复被感谢的可能性: 高/中/低(从上下文推断)

**分析要点**:
- 内容质量
- 专业权威性
- 对他人的帮助程度
- 在社区的认可度

**评分**: ___/10 分

---

### 9. 学习成长力 📈 (1-10分)

**评分标准**:
- **1-3分**: 学习意愿低,少讨论新知识/新技术
- **4-6分**: 学习意愿一般,偶尔接触新事物
- **7-8分**: 学习意愿强,经常研究新技术/新领域
- **9-10分**: 持续学习,快速接受新事物,有成长型思维

**量化指标**:
- 提问/求教次数: ___次
- 学习/研究相关讨论: ___次
- 对新技术/新产品的关注度: 高/中/低

**分析要点**:
- 学习态度
- 对新事物的接受度
- 是否主动求知
- 成长型/固定型思维

**评分**: ___/10 分

---

### 10. 真实度/可信度 🎭 (1-10分)

**评分标准**:
- **1-3分**: 疑似水军/发帖员,频繁引战,内容前后矛盾,编故事明显
- **4-6分**: 部分内容夸张或不实,偶尔引战,但大部分内容真实
- **7-8分**: 内容基本真实可信,偶有夸张但无恶意
- **9-10分**: 高度真实,言行一致,内容经得起推敲,真诚度高

**量化指标**:
- 内容前后一致性: 高/中/低
- 引战/攻击性言论次数: ___次
- 疑似营销/广告内容: ___次
- 逻辑矛盾或编故事迹象: ___处

**重点识别特征**:

**🚩 发帖员/水军特征**:
- 短期内大量发帖/回复(不正常的活跃度)
- 重复发布相似内容或套路化回复
- 频繁推荐特定产品/服务/链接
- 账号注册时间短但活跃度极高
- 回复内容空洞,缺乏个人观点

**🚩 故意引战特征**:
- 频繁使用攻击性、煽动性语言
- 刻意挑起争议话题
- 对不同观点采取极端对立态度
- 喜欢"抬杠",缺乏建设性讨论
- 制造焦虑或贩卖恐慌

**🚩 编故事/造假特征**:
- 前后描述自相矛盾(职业/收入/经历不一致)
- 过度夸张的个人经历
- 时间线混乱(如"去年"的事在不同回复中日期不符)
- 细节模糊或经不起推敲
- 频繁更换人设或立场

**✅ 真实可信特征**:
- 长期稳定的发言风格
- 内容具体详细,有个人特色
- 前后观点一致,言行相符
- 分享真实经验教训(包括失败)
- 对话真诚,愿意承认不足

**分析要点**:
- 内容真实性(是否有明显编造迹象)
- 动机纯粹性(是否有营销/引导目的)
- 立场一致性(观点是否前后矛盾)
- 言行一致性(说的和做的是否匹配)
- 互动真诚度(回复是否真心还是套路)

**评分**: ___/10 分

---

### 11. 生活地域判断 🏠

**不评分,仅推断**

**分析要点**:
- **居住城市**: _____(根据讨论的地域板块、提及的地点)
- **证据强度**: 强/中/弱
- **可能的活动范围**: _____
- **是否有地域相关特征**: _____

---

## 📋 综合评价

### 综合画像卡片

| 维度 | 评分 | 等级 | 关键特征 |
|------|------|------|---------|
| 技术能力 | __/10 | 专家/从业者/爱好者/无 | _____ |
| 消费能力 | __/10 | 高/中高/中/中低/低 | _____ |
| 专业深度 | __/10 | 专家/资深/中级/初级 | _____ |
| 社交活跃度 | __/10 | 非常活跃/活跃/一般/不活跃 | _____ |
| 兴趣广度 | __/10 | 非常广泛/广泛/适中/单一 | _____ |
| 情绪稳定性 | __/10 | 非常稳定/稳定/一般/不稳定 | _____ |
| 生活品质 | __/10 | 优质/良好/一般/较差 | _____ |
| 影响力 | __/10 | KOL/活跃/普通/潜水 | _____ |
| 学习成长力 | __/10 | 强/较强/一般/弱 | _____ |
| 真实度/可信度 | __/10 | 高度真实/基本可信/存疑/疑似造假 | _____ |

**综合评分**: ___/100 分

---

### 用户画像总结 (200-300字)

[用一段话描述该用户的整体特征,包括:
- 基本信息(年龄段、地域、职业推断)
- 核心特征(最突出的2-3个特点)
- 兴趣爱好概况
- 性格特征
- 生活状态
- 最具代表性的标签]

---

### 特殊标签 🏷️

请根据分析给出3-5个最具代表性的标签:

\`#标签1\` \`#标签2\` \`#标签3\` \`#标签4\` \`#标签5\`

---

### 核心洞察 💡

**优势特征**(最突出的3个方面):
1. _____
2. _____
3. _____

**潜在需求**(可能感兴趣的3个方向):
1. _____
2. _____
3. _____

**性格特质**(MBTI参考):
- 可能的性格类型: _____
- 主要性格特征: _____

---

## 📋 输出格式要求

1. **严格按照评分标准打分**,不得凭感觉评分
2. **必须列出量化指标的具体数值**
3. **每个评分必须有具体的证据支撑**(引用回复内容)
4. **填写综合评价表格**
5. **生成200-300字的用户画像总结**
6. **给出3-5个标签**
7. **不用重新输出评分标准,只给出要求的结果**

---

## ⚡ 开始分析

请开始你的专业量化分析,注意:

✅ **量化优先**: 先统计量化指标,再基于数据打分  
✅ **证据支撑**: 每个结论都要引用具体回复  
✅ **客观准确**: 基于实际数据,不要过度臆测  
✅ **标准一致**: 严格按照评分标准,不得凭主观感觉  

---

*本文档由 V2EX 用户回复提取器自动生成*  
*提取时间: ${new Date().toLocaleString('zh-CN')}*  
*数据量: ${totalReplies} 条回复*  
*评分体系: 10维度量化评估 (总分100分)*  
*版权: su3sl3h06*
`;

            // 复制到剪贴板
            await navigator.clipboard.writeText(markdown);
            
            // 成功提示
            const toast = document.createElement('div');
            toast.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                padding: 20px 40px;
                border-radius: 12px;
                box-shadow: 0 8px 32px rgba(102, 126, 234, 0.4);
                z-index: 10001;
                font-size: 16px;
                font-weight: bold;
                text-align: center;
                animation: fadeInOut 2s ease-in-out;
            `;
            toast.innerHTML = `
                <div style="font-size: 48px; margin-bottom: 10px;">✅</div>
                <div>复制成功!</div>
                <div style="font-size: 14px; margin-top: 8px; opacity: 0.9;">
                    ${totalReplies} 条回复已复制到剪贴板
                </div>
                <div style="font-size: 13px; margin-top: 8px; opacity: 0.8;">
                    现在可以粘贴到 ChatGPT/Claude 等AI工具
                </div>
            `;
            
            // 添加动画样式
            if (!document.getElementById('toast-animation-style')) {
                const style = document.createElement('style');
                style.id = 'toast-animation-style';
                style.textContent = `
                    @keyframes fadeInOut {
                        0% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
                        15% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
                        85% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
                        100% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
                    }
                `;
                document.head.appendChild(style);
            }
            
            document.body.appendChild(toast);
            
            // 2秒后自动移除提示
            setTimeout(() => {
                toast.remove();
            }, 2000);

        } catch (error) {
            console.error('复制失败:', error);
            showToast('复制失败!\n可能原因:\n- 浏览器不支持剪贴板API\n- 没有权限访问剪贴板\n\n建议使用"导出 MD 文件"功能');
        }
    }

    // 创建主页快捷按钮
    function createHomepageButton() {
        const button = document.createElement('div');
        button.id = 'reply-extractor-homepage-btn';
        button.innerHTML = `
            <div style="
                position: fixed;
                bottom: 80px;
                right: 20px;
                width: 160px;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                padding: 15px 20px;
                border-radius: 12px;
                box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
                cursor: pointer;
                z-index: 10000;
                font-family: Arial, sans-serif;
                text-align: center;
                transition: all 0.3s ease;
            " onmouseover="this.style.transform='translateY(-3px)'; this.style.boxShadow='0 6px 20px rgba(102, 126, 234, 0.5)';" 
               onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 4px 15px rgba(102, 126, 234, 0.4)';">
                <div style="font-size: 24px; margin-bottom: 8px;">📊</div>
                <div style="font-size: 14px; font-weight: bold; margin-bottom: 4px;">提取用户回复</div>
                <div style="font-size: 11px; opacity: 0.9;">点击进入回复页</div>
            </div>
        `;
        
        button.addEventListener('click', function() {
            // 获取用户名
            const username = window.location.pathname.match(/\/member\/([^\/]+)/)?.[1];
            if (username) {
                // 跳转到回复页
                window.location.href = `/member/${username}/replies`;
            }
        });
        
        document.body.appendChild(button);
    }

    // 初始化
    function init() {
        // 检查是否在用户页面
        if (window.location.pathname.includes('/member/')) {
            const username = window.location.pathname.match(/\/member\/([^\/]+)/)?.[1];
            
            if (!username) return;
            
            // 判断是否在回复页
            if (window.location.pathname.includes('/replies')) {
                // 在回复页,显示完整控制面板
                createControlPanel();
                
                // 显示当前页面信息
                const pageInfo = getPageInfo();
                updateUI(pageInfo.currentPage, pageInfo.totalPages, 0, '等待中', 0);
            } else {
                // 在主页,显示快捷按钮
                createHomepageButton();
            }
        }
    }

    // 页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();