Metrics Extractor for Xiaohongshu Note Manager

展示指标数据并统计数据(浏览量、评论数、点赞数、收藏数、转发数)(聪明豆专属)。

目前为 2024-12-13 提交的版本。查看 最新版本

// ==UserScript==
// @name         Metrics Extractor for Xiaohongshu Note Manager
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  展示指标数据并统计数据(浏览量、评论数、点赞数、收藏数、转发数)(聪明豆专属)。
// @author       duz
// @match        https://creator.xiaohongshu.com/new/note-manager*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 防止脚本多次运行
    if (document.getElementById('metrics-extractor-container')) {
        return;
    }

    const metrics = ['浏览量', '评论数', '点赞数', '收藏数', '转发数'];
    const iconDivs = document.querySelectorAll('div.icon');
    const numbers = [];

    iconDivs.forEach(div => {
        const span = div.querySelector('span');
        if (span) {
            const number = span.textContent.trim();
            numbers.push(number);
        }
    });

    if (numbers.length % 5 !== 0) {
        console.warn('提取的数字数量不是5的倍数,可能存在数据缺失或多余。');
    }

    const categorizedData = [];
    for (let i = 0; i < numbers.length; i += 5) {
        const item = {};
        metrics.forEach((metric, index) => {
            if (i + index < numbers.length) {
                const num = parseInt(numbers[i + index], 10);
                item[metric] = isNaN(num) ? null : num;
            } else {
                item[metric] = null;
            }
        });
        categorizedData.push(item);
    }

    const totals = {
        '浏览量': 0,
        '评论数': 0,
        '点赞数': 0,
        '收藏数': 0,
        '转发数': 0
    };

    categorizedData.forEach(item => {
        metrics.forEach(metric => {
            const value = item[metric];
            if (typeof value === 'number') {
                totals[metric] += value;
            }
        });
    });

    // 创建样式
    const style = document.createElement('style');
    style.innerHTML = `
    #metrics-extractor-container {
        position: fixed;
        top: 20px;
        right: 20px;
        width: 320px;
        background: rgba(255, 255, 255, 0.95);
        border: 1px solid #ccc;
        border-radius: 8px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.2);
        padding: 15px;
        z-index: 10000;
        font-family: Arial, sans-serif;
        max-height: 90vh;
        overflow-y: auto;
    }
    #metrics-extractor-container h2 {
        text-align: center;
        margin-top: 0;
        font-size: 18px;
    }
    #metrics-extractor-container table {
        width: 100%;
        border-collapse: collapse;
        margin-bottom: 15px;
    }
    #metrics-extractor-container th, #metrics-extractor-container td {
        border: 1px solid #ddd;
        padding: 8px;
        text-align: center;
        font-size: 14px;
    }
    #metrics-extractor-container th {
        background-color: #f2f2f2;
    }
    #metrics-extractor-container button {
        width: 100%;
        padding: 10px;
        background-color: #4CAF50;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 14px;
        margin-bottom: 10px;
    }
    #metrics-extractor-container button:hover {
        background-color: #45a049;
    }
    #metrics-extractor-details {
        display: none;
        max-height: 300px;
        overflow-y: auto;
    }
    `;
    document.head.appendChild(style);

    // 创建容器
    const container = document.createElement('div');
    container.id = 'metrics-extractor-container';

    // 创建标题
    const title = document.createElement('h2');
    title.textContent = '指标总数';
    container.appendChild(title);

    // 创建总数表格
    const totalsTable = document.createElement('table');
    const totalsThead = document.createElement('thead');
    const totalsHeaderRow = document.createElement('tr');
    const metricHeader = document.createElement('th');
    metricHeader.textContent = '指标';
    const totalHeader = document.createElement('th');
    totalHeader.textContent = '总数';
    totalsHeaderRow.appendChild(metricHeader);
    totalsHeaderRow.appendChild(totalHeader);
    totalsThead.appendChild(totalsHeaderRow);
    totalsTable.appendChild(totalsThead);

    const totalsTbody = document.createElement('tbody');
    for (const [metric, total] of Object.entries(totals)) {
        const row = document.createElement('tr');
        const metricCell = document.createElement('td');
        metricCell.textContent = metric;
        const totalCell = document.createElement('td');
        totalCell.textContent = total;
        row.appendChild(metricCell);
        row.appendChild(totalCell);
        totalsTbody.appendChild(row);
    }
    totalsTable.appendChild(totalsTbody);
    container.appendChild(totalsTable);

    // 创建按钮
    const toggleButton = document.createElement('button');
    toggleButton.id = 'metrics-extractor-toggle';
    toggleButton.textContent = '显示详细数据';
    container.appendChild(toggleButton);

    // 创建详细数据部分
    const detailsSection = document.createElement('div');
    detailsSection.id = 'metrics-extractor-details';

    const detailsTitle = document.createElement('h2');
    detailsTitle.textContent = '详细数据';
    detailsSection.appendChild(detailsTitle);

    const detailsTable = document.createElement('table');
    const detailsThead = document.createElement('thead');
    const detailsHeaderRow = document.createElement('tr');
    const projectHeader = document.createElement('th');
    projectHeader.textContent = '项目';
    detailsHeaderRow.appendChild(projectHeader);
    metrics.forEach(metric => {
        const th = document.createElement('th');
        th.textContent = metric;
        detailsHeaderRow.appendChild(th);
    });
    detailsThead.appendChild(detailsHeaderRow);
    detailsTable.appendChild(detailsThead);

    const detailsTbody = document.createElement('tbody');
    categorizedData.forEach((item, index) => {
        const row = document.createElement('tr');
        const projectCell = document.createElement('td');
        projectCell.textContent = index + 1;
        row.appendChild(projectCell);
        metrics.forEach(metric => {
            const cell = document.createElement('td');
            cell.textContent = item[metric] !== null ? item[metric] : '-';
            row.appendChild(cell);
        });
        detailsTbody.appendChild(row);
    });
    detailsTable.appendChild(detailsTbody);
    detailsSection.appendChild(detailsTable);

    container.appendChild(detailsSection);
    document.body.appendChild(container);

    // 添加按钮点击事件
    toggleButton.addEventListener('click', () => {
        if (detailsSection.style.display === 'none' || detailsSection.style.display === '') {
            detailsSection.style.display = 'block';
            toggleButton.textContent = '隐藏详细数据';
        } else {
            detailsSection.style.display = 'none';
            toggleButton.textContent = '显示详细数据';
        }
    });
})();