网页文本词频分析 (使用 innerText)

使用 innerText 分析网页文本词频,显示在可拖拽悬浮窗口

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         网页文本词频分析 (使用 innerText)
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  使用 innerText 分析网页文本词频,显示在可拖拽悬浮窗口
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';
    function countMostFrequentTwoWords(text) {
        if (typeof text !== 'string' || text.length < 2) {
            return "输入文本不合法或长度不足"; // 处理无效输入
        }

        // 1. 清理文本:移除标点符号和多余空格
        text = text.replace(/[,、;:。?!“”‘’《》【】{}()…—·!¥…&……%@*]/g, ''); // 移除中文标点
        text = text.replace(/\s+/g, ' '); // 将多个空格替换为一个空格
        text = text.trim(); // 去除首尾空格

        // 2. 分割成单字数组
        let characters = text.split('');

        // 3. 创建双字词并计数
        let twoWordCounts = {};
        for (let i = 0; i < characters.length - 1; i++) {
            let twoWord = characters[i] + characters[i + 1];
            twoWordCounts[twoWord] = (twoWordCounts[twoWord] || 0) + 1;
        }

        // 4. 找到出现次数最多的两个双字词
        let sortedTwoWords = Object.entries(twoWordCounts).sort(([, countA], [, countB]) => countB - countA);

        //处理没有双字词的情况
        if (sortedTwoWords.length === 0) {
            return "文本中没有双字词";
        }

        // 返回出现次数最多的两个双字词
        let topTwo = sortedTwoWords.slice(0, 2);
        let result = "";
        for(let i = 0; i < topTwo.length; i++){
            result += `第${i+1}名: "${topTwo[i][0]}" 出现了 ${topTwo[i][1]} 次\n`;
        }
        return result;
    }



    function wordFrequency(text) {
        if (typeof text !== 'string' || text.length === 0) {
            return {};
        }

        // 预处理:去除标点符号和空格,转换为小写
        text = text.replace(/[\p{P}\s]+/gu, '').toLowerCase();

        const frequency = {};
        const n = text.length;

        for (let i = 0; i < n; i++) {
            for (let j = 1; j <= 4 && i + j <= n; j++) { // 限制词组最多四个字
            const word = text.substring(i, i + j);
            frequency[word] = (frequency[word] || 0) + 1;
            }
        }

        // 将词频对象转换为数组并按词频降序排序 (可选)
        const sortedFrequency = Object.entries(frequency).sort(([, a], [, b]) => b - a);

            // 如果需要返回对象而不是数组,可以省略上面的排序代码,直接返回 frequency 对象

        return sortedFrequency; // 或者 return frequency;
    }

    function topWordFrequency(text, topN = 20) {
        if (typeof text !== 'string' || text.length === 0) {
            return []; // 或者返回空对象 {},取决于你的需求
        }

        // 预处理:去除标点符号和空格,转换为小写
        text = text.replace(/[\p{P}\s]+/gu, '').toLowerCase();

        const frequency = {};
        const n = text.length;

        for (let i = 0; i < n; i++) {
            for (let j = 1; j <= 4 && i + j <= n; j++) {
                const word = text.substring(i, i + j);
                frequency[word] = (frequency[word] || 0) + 1;
            }
        }

        // 将词频对象转换为数组并按词频降序排序
        const sortedFrequency = Object.entries(frequency).sort(([, a], [, b]) => b - a);

        // 返回前 topN 个词组
        return sortedFrequency.slice(0, topN);
    }

    function analyzeText() {
        // 使用 innerText 获取所有文本
        let allText = document.body.innerText;
        let output=topWordFrequency(allText)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 清理文本
        //allText = allText.replace(/[,。??.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").replace(/\s{2,}/g," ").toLowerCase();
        // 定义需要切割的标点符号,注意转义特殊字符
        //let punctuation = /[,、;:。?!“”‘’《》【】{}()]/g;

        //let words = allText.split(punctuation);

        // 过滤掉空字符串
        //words = words.filter(word => word.trim() !== "");

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//         let words= countMostFrequentTwoWords(allText)
//         // 统计词频
//         let wordFrequency = {};
//         for (let word of words) {
//             if (word !== "") {
//                 wordFrequency[word] = (wordFrequency[word] || 0) + 1;
//             }
//         }

//         // 排序词频
//         let sortedWords = Object.entries(wordFrequency).sort(([, a], [, b]) => b - a);

        // 创建显示结果的 div
        let resultDiv = document.createElement("div");
        resultDiv.id = "wordFrequencyResult"; // 添加 id 方便后续操作
        resultDiv.style.position = "fixed";
        resultDiv.style.top = "10px";
        resultDiv.style.left = "10px";
        resultDiv.style.backgroundColor = "white";
        resultDiv.style.border = "1px solid black";
        resultDiv.style.padding = "10px";
        resultDiv.style.zIndex = "9999";
        resultDiv.style.maxHeight = "500px";
        resultDiv.style.overflowY = "scroll";
        resultDiv.style.resize = "both"; // 允许调整大小
        resultDiv.style.overflow = "auto";
        resultDiv.style.minWidth = "200px"; // 设置最小宽度,防止拖拽成一条线

        // let output = "词频分析结果:\n";
        // for (let [word, frequency] of sortedWords) {
        //     output += word + ": " + frequency + "\n";
        // }
        resultDiv.textContent = output;

        document.body.appendChild(resultDiv);

        // 使 div 可拖拽
        dragElement(resultDiv);
    }

    //拖拽功能
    function dragElement(elmnt) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        if (elmnt.querySelector(".drag-header")) {
            /* 如果存在 header,则 header 是拖拽的“手柄” */
            elmnt.querySelector(".drag-header").onmousedown = dragMouseDown;
        } else {
            /* 否则,整个元素都是拖拽的“手柄” */
            elmnt.onmousedown = dragMouseDown;
        }

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            // 获取鼠标在光标位置的初始位置
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            // 计算新的光标位置
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            // 设置元素的新位置
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            /* 停止移动 */
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }


    // 创建分析按钮
    let analyzeButton = document.createElement("button");
    analyzeButton.textContent = "分析词频";
    analyzeButton.style.position = "fixed";
    analyzeButton.style.top = "10px";
    analyzeButton.style.right = "10px";
    analyzeButton.style.zIndex = "9999";
    analyzeButton.onclick = analyzeText;
    document.body.appendChild(analyzeButton);
})();