2.0版 用篡改猴脚本给个人中心的收藏和发帖加上搜索功能!
评论
收藏

2.0版 用篡改猴脚本给个人中心的收藏和发帖加上搜索功能!

经验分享
狼辛
2025-11-14 08:59·浏览量:576
狼辛
影刀中级开发者
发布于 2025-11-14 08:59576浏览

原贴: https://www.yingdao.com/community/detaildiscuss?id=873547200801124352&tag=&from=userCenter&sort=createTime&page=1

日常够用,但是 过客  https://www.yingdao.com/community/userCenter?userUuid=687223449269694466 用户有1600条回答,恐怖如斯ᔪ꒰꒪ω꒪|||꒱,原有的就不够用了,10条10条得加载到什么时候.

于是通过修改请求,每次请求返回最大500条文章,来解决.应该有办法更快,不过懒得弄了,正常来讲不至于超过500条回答

吧.....................................

篡改猴脚本:

// ==UserScript==
// @name         影刀社区文章自动加载与搜索器
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  优化影刀社区页面,支持大量文章自动加载(每次500条)和搜索功能,修复回答栏目搜索显示问题和收藏栏目搜索功能
// @author       You
// @match        *://www.yingdao.com/community/userCenter?userUuid*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 全局变量
    let currentSection = 'PUBLISH'; // 默认栏目:发布
    let currentSubSection = '提问'; // 默认子栏目:提问
    let loadedCount = 0; // 已加载的内容数量
    let totalCount = 0; // 当前栏目总内容数量
    let isLoading = false; // 加载状态标志
    let loadInterval = null; // 自动加载的定时器
    let retryCount = 0; // 重试次数计数
    let maxRetries = 10; // 最大重试次数
    
    // XPath常量定义
    const XPATHS = {
        // 发布栏目子栏目按钮
        publishQuestion: "//div[@id=\"rc-tabs-0-panel-PUBLISH\"]//div[contains(@class, \"btn___N0geJ\")]//div//button[contains(text(),\"提问\")]",
        publishAnswer: "//div[@id=\"rc-tabs-0-panel-PUBLISH\"]//div[contains(@class, \"btn___N0geJ\")]//div//button[contains(text(),\"回答\")]",
        publishArticle: "//div[@id=\"rc-tabs-0-panel-PUBLISH\"]//div[contains(@class, \"btn___N0geJ\")]//div//button[contains(text(),\"文章\")]",
        // 收藏栏目子栏目按钮
        collectQa: "//div[@id=\"rc-tabs-0-panel-COLLECT\"]//div[contains(@class, \"btn___N0geJ\")]//div//button[contains(text(),\"问答\")]",
        collectArticle: "//div[@id=\"rc-tabs-0-panel-COLLECT\"]//div[contains(@class, \"btn___N0geJ\")]//div//button[contains(text(),\"文章\")]",
        // 查看更多按钮
        viewMore: "//span[normalize-space(text())=\"查看更多\"]"
    };

    // 配置常量
    const 配置 = {
        每页加载数量: 500,
        初始延时: 2000, // 栏目切换后初始等待时间
        回答栏目初始延时: 4000, // 回答栏目特殊处理,给予更长时间加载
        重试间隔: 2000, // 按钮检测失败后的重试间隔
        检查间隔: 3000 // 常规检查间隔
    };
    
    // API请求监控对象
    const API请求监控 = {
        最后请求时间: 0,
        请求计数: 0,
        最后响应数据: null
    };

    // 初始化函数
    function 初始化() {
        console.log('影刀社区文章自动加载与搜索器v1.3初始化');
        
        // 添加搜索框
        添加搜索框();
        
        // 设置栏目监听
        设置栏目监听();
        
        // 初始化当前栏目信息
        更新栏目信息();
        
        // 设置MutationObserver监听页面变化
        设置页面变化监听();
        
        // 注入API拦截器
        注入API拦截器();
        
        // 开始自动加载
        开始自动加载();
        
        // 添加全局错误处理
        添加全局错误处理();
    }

    // 获取当前栏目信息函数
    function 获取当前栏目信息() {
        let 栏目标识 = '';
        let 大栏目 = currentSection;
        let 子栏目 = currentSubSection;
        
        if (currentSection === 'PUBLISH') {
            if (currentSubSection.includes('提问')) {
                栏目标识 = '发布提问';
            } else if (currentSubSection.includes('回答')) {
                栏目标识 = '发布回答';
            } else if (currentSubSection.includes('文章')) {
                栏目标识 = '发布文章';
            }
        } else if (currentSection === 'COLLECT') {
            if (currentSubSection.includes('问答')) {
                栏目标识 = '收藏问答';
            } else if (currentSubSection.includes('文章')) {
                栏目标识 = '收藏文章';
            }
        }
        
        return {
            栏目标识: 栏目标识,
            大栏目: 大栏目,
            子栏目: 子栏目
        };
    }

    // 优化版API拦截器 - 借鉴废弃版实现
    function 注入API拦截器() {
        try {
            console.log('开始注入API拦截器...');
            
            const 原始Fetch = window.fetch;
            
            // 重写fetch函数
            window.fetch = function(url, options) {
                // 检查是否是目标API请求 - 使用废弃版的精确匹配模式
                if (typeof url === 'string' && 
                    (url.includes('queryUserPublishList') || 
                     url.includes('queryUserAnswerList') || 
                     url.includes('queryUserQuestionList') || 
                     url.includes('queryUserFavoriteList'))) {
                    
                    console.log(`拦截到用户内容加载请求: ${url}`);
                    
                    // 更新API请求监控
                    API请求监控.最后请求时间 = Date.now();
                    API请求监控.请求计数++;
                    
                    try {
                        // 解析请求选项
                        const 修改选项 = options || {};
                        
                        // 如果有请求体,尝试解析并修改
                        if (修改选项.body) {
                            const 请求体 = JSON.parse(修改选项.body);
                            
                            // 智能判断:只有当当前栏目是目标栏目时才修改数量
                            const 栏目信息 = 获取当前栏目信息();
                            if ((栏目信息.栏目标识 === '发布文章' && url.includes('queryUserPublishList')) ||
                                (栏目信息.栏目标识 === '发布回答' && (url.includes('queryUserPublishList') || url.includes('queryUserAnswerList'))) ||
                                (栏目信息.栏目标识 === '发布提问' && url.includes('queryUserQuestionList')) ||
                                (栏目信息.栏目标识 === '收藏问答' || 栏目信息.栏目标识 === '收藏文章') && url.includes('queryUserFavoriteList')) {
                                
                                // 修改size或pageSize参数为500
                                if (请求体.size !== undefined) {
                                    const 原始数量 = 请求体.size;
                                    请求体.size = 配置.每页加载数量;
                                    修改选项.body = JSON.stringify(请求体);
                                    console.log(`修改size参数: ${原始数量} -> ${配置.每页加载数量}`);
                                } else if (请求体.pageSize !== undefined) {
                                    const 原始数量 = 请求体.pageSize;
                                    请求体.pageSize = 配置.每页加载数量;
                                    修改选项.body = JSON.stringify(请求体);
                                    console.log(`修改pageSize参数: ${原始数量} -> ${配置.每页加载数量}`);
                                }
                            }
                            
                            // 确保请求包含正确的用户ID
                            const 用户ID = 获取URL参数('userUuid');
                            if (用户ID) {
                                if (请求体.userUuid) {
                                    请求体.userUuid = 用户ID;
                                }
                            }
                        }
                        
                        // 处理URL参数
                        if (url.includes('?')) {
                            const urlParts = url.split('?');
                            const queryParams = new URLSearchParams(urlParts[1]);
                            
                            // 更新size或pageSize参数为500
                            if (queryParams.has('size')) {
                                queryParams.set('size', 配置.每页加载数量.toString());
                                url = `${urlParts[0]}?${queryParams.toString()}`;
                                console.log(`修改URL size参数为: ${配置.每页加载数量}`);
                            } else if (queryParams.has('pageSize')) {
                                queryParams.set('pageSize', 配置.每页加载数量.toString());
                                url = `${urlParts[0]}?${queryParams.toString()}`;
                                console.log(`修改URL pageSize参数为: ${配置.每页加载数量}`);
                            }
                        }
                        
                        console.log(`API请求已修改: ${url}`);
                    } catch (e) {
                        console.error('修改请求参数失败:', e);
                    }
                }
                
                // 执行原始fetch并返回Promise
                return 原始Fetch(url, options).then(response => {
                    // 克隆响应以解析其内容
                    const 克隆的响应 = response.clone();
                    
                    // 尝试解析JSON响应
                    克隆的响应.json().then(data => {
                        API请求监控.最后响应数据 = data;
                        // 验证是否成功加载了500条数据
                        if (data.data && data.data.records) {
                            console.log(`成功加载 ${data.data.records.length} 条记录`);
                        }
                    }).catch(e => {
                        // 非JSON响应,忽略错误
                    });
                    
                    return response;
                }).catch(error => {
                    console.error('API请求错误:', error);
                    throw error;
                });
            };
            
            console.log('API拦截器注入成功,已配置为每次加载500条数据');
        } catch (error) {
            console.error('注入API拦截器失败:', error);
        }
    }
    
    // 获取URL参数函数
    function 获取URL参数(参数名) {
        const URL参数 = new URLSearchParams(window.location.search);
        return URL参数.get(参数名);
    }

    // 添加全局错误处理
    function 添加全局错误处理() {
        // 全局错误处理
        window.addEventListener('error', function(event) {
            console.error('全局错误:', event.message, event.error);
            // 不阻止默认行为,让错误继续传播
        });
        
        // Promise拒绝处理
        window.addEventListener('unhandledrejection', function(event) {
            console.error('Promise拒绝:', event.reason);
            // 不阻止默认行为,让错误继续传播
        });
    }

    // 添加搜索框
    function 添加搜索框() {
        // 创建搜索容器
        const searchContainer = document.createElement('div');
        searchContainer.style.cssText = `
            position: fixed;
            top: 10px;
            right: 20px;
            z-index: 9999;
            background: white;
            padding: 10px;
            border-radius: 6px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            display: flex;
            align-items: center;
        `;
        
        // 创建搜索输入框
        const searchInput = document.createElement('input');
        searchInput.type = 'text';
        searchInput.placeholder = '搜索内容...';
        searchInput.style.cssText = `
            padding: 8px 32px 8px 12px;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            width: 250px;
            margin-right: 8px;
            font-size: 14px;
            box-sizing: border-box;
        `;
        
        // 创建搜索按钮
        const searchButton = document.createElement('button');
        searchButton.textContent = '搜索';
        searchButton.style.cssText = `
            padding: 8px 16px;
            background: #1890ff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            margin-right: 8px;
        `;
        
        // 创建清除按钮
        const clearButton = document.createElement('button');
        clearButton.textContent = '清除';
        clearButton.style.cssText = `
            padding: 8px 16px;
            background: #f0f0f0;
            color: #333;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        `;
        
        // 添加搜索事件
        searchButton.addEventListener('click', () => 执行搜索(searchInput.value));
        clearButton.addEventListener('click', () => {
            searchInput.value = '';
            执行搜索('');
        });
        
        // 回车键搜索
        searchInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') 执行搜索(searchInput.value);
        });
        
        // 监听输入变化,添加防抖
        let searchTimeout;
        searchInput.addEventListener('input', () => {
            clearTimeout(searchTimeout);
            // 搜索框为空时立即恢复所有内容显示
            if (searchInput.value.trim() === '') {
                执行搜索('');
            }
        });
        
        // 组装搜索框
        searchContainer.appendChild(searchInput);
        searchContainer.appendChild(searchButton);
        searchContainer.appendChild(clearButton);
        document.body.appendChild(searchContainer);
        
        // 定位搜索框到页面顶部右侧
        searchContainer.style.position = 'fixed';
        searchContainer.style.top = '10px';
        searchContainer.style.right = '10px';
        searchContainer.style.zIndex = '9999';
        searchContainer.style.background = 'white';
        searchContainer.style.padding = '10px';
        searchContainer.style.borderRadius = '6px';
        searchContainer.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.15)';
        searchContainer.style.display = 'flex';
        searchContainer.style.alignItems = 'center';
    }

    // UI提示函数 - 替代浏览器弹窗
    function 显示搜索结果提示(message, isSuccess = true) {
        try {
            // 创建或获取提示容器
            let 提示容器 = document.getElementById('搜索提示容器');
            if (!提示容器) {
                提示容器 = document.createElement('div');
                提示容器.id = '搜索提示容器';
                提示容器.style.cssText = `
                    position: fixed;
                    top: 20px;
                    left: 50%;
                    transform: translateX(-50%);
                    z-index: 99999;
                    background: ${isSuccess ? '#52c41a' : '#ff7875'};
                    color: white;
                    padding: 12px 24px;
                    border-radius: 6px;
                    font-size: 14px;
                    font-weight: 500;
                    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                    max-width: 400px;
                    text-align: center;
                    line-height: 1.4;
                    transition: all 0.3s ease;
                `;
                document.body.appendChild(提示容器);
            }
            
            // 更新提示内容和样式
            提示容器.textContent = message;
            提示容器.style.background = isSuccess ? '#52c41a' : '#ff7875';
            提示容器.style.display = 'block';
            
            // 3秒后自动隐藏
            setTimeout(() => {
                提示容器.style.opacity = '0';
                setTimeout(() => {
                    提示容器.style.display = 'none';
                }, 300);
            }, 3000);
            
            console.log(`搜索提示: ${message}`);
        } catch (e) {
            console.error('显示搜索提示失败:', e);
            // 如果UI提示失败,回退到控制台输出
            console.log(`搜索结果: ${message}`);
        }
    }

    // 执行搜索 - 优化版,参考废弃版方法修复搜索问题,保留1.5版本API和栏目检测功能
    function 执行搜索(keyword) {
        const 搜索关键词 = keyword.trim().toLowerCase();
        let 匹配数量 = 0;
        
        console.log(`开始搜索关键词: ${搜索关键词}`);
        console.log(`当前栏目: ${currentSection}-${currentSubSection}(${totalCount})`);
        
        // 首先清除所有高亮
        清除所有高亮();
        
        // 获取当前激活的标签面板 - 参考废弃版的直接DOM查找方式
        let 活动面板 = null;
        
        // 使用更直接的方式查找活动面板,参考废弃版代码
        const 标签页区域 = document.querySelector('.ant-tabs-nav, .tabs-nav, [role="tablist"]');
        if (标签页区域) {
            // 找到活动标签
            const 活动标签 = 标签页区域.querySelector('.ant-tabs-tab-active, [aria-selected="true"]');
            if (活动标签) {
                const 标签文本 = 活动标签.textContent.trim();
                console.log(`当前活动标签: ${标签文本}`);
                
                // 根据标签文本查找对应的面板
                if (标签文本.includes('发布') || 标签文本.includes('文章')) {
                    活动面板 = document.querySelector('#rc-tabs-0-panel-PUBLISH, [data-tab="PUBLISH"]');
                } else if (标签文本.includes('回答')) {
                    活动面板 = document.querySelector('#rc-tabs-0-panel-ANSWER, [data-tab="ANSWER"]');
                } else if (标签文本.includes('提问') || 标签文本.includes('问题')) {
                    活动面板 = document.querySelector('#rc-tabs-0-panel-QUESTION, [data-tab="QUESTION"]');
                } else if (标签文本.includes('收藏')) {
                    活动面板 = document.querySelector('#rc-tabs-0-panel-COLLECT, [data-tab="COLLECT"]');
                }
            }
        }
        
        // 如果通过标签找不到面板,尝试直接查找可见的面板
        if (!活动面板) {
            const 所有面板 = document.querySelectorAll('[role="tabpanel"], .ant-tabs-panel, [id*="panel"]');
            for (const 面板 of 所有面板) {
                const 样式 = window.getComputedStyle(面板);
                if (样式.display !== 'none' && 面板.offsetParent !== null) {
                    活动面板 = 面板;
                    break;
                }
            }
        }
        
        // 如果还是找不到面板,使用fallback方法
        if (!活动面板) {
            活动面板 = document.querySelector('[role="main"], .user-center-content, .content-area') || document.body;
        }
        
        // 获取所有文章项 - 参考废弃版的有效选择器策略
        let 所有文章项 = [];
        
        // 如果搜索关键词为空,恢复显示所有内容
        if (搜索关键词 === '') {
            // 尝试多种选择器找到所有项目并显示
            const 候选选择器 = [
                '.list___18bDQ > div',
                '.list_item___nmNeS',
                'a[href*="/community/"]',
                'div[role="tabpanel"] a',
                '.qa-item, .article-item, .answer-item',
                '[class*="item"]',
                '[class*="list"] > div'
            ];
            
            for (const 选择器 of 候选选择器) {
                const 找到的项目 = 活动面板.querySelectorAll(选择器);
                if (找到的项目.length > 0) {
                    找到的项目.forEach(item => {
                        item.style.display = '';
                    });
                    console.log(`使用选择器 ${选择器} 恢复了 ${找到的项目.length} 个项目`);
                }
            }
            
            console.log('已显示所有内容');
            显示搜索结果提示('已显示所有内容', true);
            return;
        }
        
        // 使用废弃版的策略:优先使用高效的选择器
        const 有效选择器 = [
            '.list___18bDQ > div',
            '.list_item___nmNeS'
        ];
        
        for (const 选择器 of 有效选择器) {
            所有文章项 = [...活动面板.querySelectorAll(选择器)];
            if (所有文章项.length > 0) {
                console.log(`使用选择器 ${选择器} 找到 ${所有文章项.length} 个项目`);
                break;
            }
        }
        
        // 如果主要选择器找不到,使用备用选择器
        if (所有文章项.length === 0) {
            const 备用选择器 = [
                'a[href*="/community/"]',
                'div[role="tabpanel"] a',
                '.qa-item, .article-item, .answer-item',
                '[class*="item"]',
                '[class*="list"] > div'
            ];
            
            for (const 选择器 of 备用选择器) {
                所有文章项 = [...活动面板.querySelectorAll(选择器)];
                if (所有文章项.length > 0) {
                    console.log(`备用选择器 ${选择器} 找到 ${所有文章项.length} 个项目`);
                    break;
                }
            }
        }
        
        console.log(`总共找到 ${所有文章项.length} 个内容项,开始搜索...`);
        
        // 遍历所有内容项 - 参考废弃版的直接处理方式
        所有文章项.forEach((item) => {
            try {
                // 先隐藏所有项,稍后显示匹配项
                item.style.display = 'none';
                
                // 获取内容项中的文本内容 - 使用更直接的方式
                const 项内容 = item.textContent.toLowerCase();
                
                // 搜索匹配项
                if (项内容.includes(搜索关键词)) {
                    // 显示匹配项
                    item.style.display = '';
                    
                    // 高亮匹配的关键词
                    高亮关键词(item, 搜索关键词);
                    匹配数量++;
                } else {
                    // 清除高亮
                    清除高亮(item);
                }
            } catch (e) {
                console.error('搜索处理单个项目失败:', e);
            }
        });
        
        // 更新搜索结果计数和提示
        console.log(`搜索完成,找到 ${匹配数量} 个匹配项`);
        
        if (匹配数量 > 0) {
            // 滚动到第一个结果
            const 第一个可见结果 = 所有文章项.find(item => item.style.display !== 'none');
            if (第一个可见结果) {
                第一个可见结果.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
            显示搜索结果提示(`找到 ${匹配数量} 条包含关键词 "${keyword}" 的内容`, true);
        } else {
            // 提供更详细的调试信息
            const 调试信息 = {
                活动面板: 活动面板 ? 活动面板.tagName + (活动面板.className ? '.' + 活动面板.className.split(' ').join('.') : '') : '未找到',
                选择器尝试: 'list___18bDQ > div, list_item___nmNeS',
                找到项目数: 所有文章项.length,
                搜索关键词: 搜索关键词,
                当前URL: window.location.href
            };
            
            console.log('搜索失败调试信息:', 调试信息);
            显示搜索结果提示(`未找到包含关键词 "${keyword}" 的内容。\n\n调试信息:\n- 活动面板: ${调试信息.活动面板}\n- 找到项目数: ${调试信息.找到项目数}\n- 当前URL: ${调试信息.当前URL}`, false);
        }
    }

    // 清除单个元素的高亮函数
    function 清除高亮(element) {
        try {
            // 查找该元素内所有高亮span并清除
            const highlightSpans = element.querySelectorAll('span[style*="background-color: rgb(255, 235, 59)"]');
            highlightSpans.forEach(span => {
                const parent = span.parentNode;
                if (parent) {
                    // 将span的文本内容替换为文本节点
                    const textNode = document.createTextNode(span.textContent);
                    parent.replaceChild(textNode, span);
                    // 合并相邻的文本节点
                    parent.normalize();
                }
            });
        } catch (e) {
            console.error('清除单个元素高亮失败:', e);
        }
    }

    // 高亮关键词函数 - 优化版,确保保留原有DOM结构和链接
    function 高亮关键词(element, keyword) {
        try {
            // 先清除之前的高亮
            清除高亮(element);
            
            const 关键词转义 = 转义正则字符(keyword);
            const 正则表达式 = new RegExp(`(${关键词转义})`, 'gi');
            
            // 递归处理节点,只处理文本节点,保留原有DOM结构
            function processNode(node) {
                if (node.nodeType === 3) { // 文本节点
                    const text = node.textContent;
                    if (正则表达式.test(text)) {
                        const parent = node.parentNode;
                        const parts = text.split(正则表达式);
                        
                        // 移除原文本节点
                        parent.removeChild(node);
                        
                        // 重新构建节点内容
                        parts.forEach((part, index) => {
                            if (index % 2 === 1) { // 匹配的关键词部分
                                const highlightSpan = document.createElement('span');
                                highlightSpan.style.backgroundColor = 'rgb(255, 235, 59)';
                                highlightSpan.textContent = part;
                                parent.appendChild(highlightSpan);
                            } else if (part) { // 非关键词部分
                                parent.appendChild(document.createTextNode(part));
                            }
                        });
                    }
                } else if (node.nodeType === 1 && node.tagName !== 'SPAN') { // 元素节点且不是高亮span
                    // 处理子节点
                    const children = Array.from(node.childNodes);
                    for (let i = 0; i < children.length; i++) {
                        processNode(children[i]);
                    }
                }
            }
            
            // 开始处理
            processNode(element);
        } catch (e) {
            console.error('高亮关键词失败:', e);
        }
    }

    // 清除所有高亮函数 - 全局清除页面上所有的高亮元素
    function 清除所有高亮() {
        try {
            // 获取页面上所有的高亮元素并清除
            document.querySelectorAll('span[style*="background-color: rgb(255, 235, 59)"]').forEach(el => {
                const 父节点 = el.parentNode;
                if (父节点) {
                    父节点.replaceChild(document.createTextNode(el.textContent), el);
                    父节点.normalize();
                }
            });
            console.log('已清除所有搜索高亮');
        } catch (e) {
            console.error('清除所有高亮失败:', e);
        }
    }

    // 转义正则字符函数
    function 转义正则字符(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    // 设置栏目监听
    function 设置栏目监听() {
        // 监听大栏目切换(发布/收藏)
        const tabElements = document.querySelectorAll('.rc-tabs-tab');
        tabElements.forEach(tab => {
            tab.addEventListener('click', function() {
                // 延迟执行,等待DOM更新
                setTimeout(() => {
                    const tabKey = this.getAttribute('data-tab-key');
                    if (tabKey === 'PUBLISH' || tabKey === 'COLLECT') {
                        currentSection = tabKey;
                        
                        // 立即更新控制台显示,提示用户已切换到哪个大栏目
                        console.log(`切换到大栏目: ${currentSection}`);
                        
                        // 获取当前激活的子栏目
                        setTimeout(() => {
                            获取当前激活的子栏目();
                            更新栏目信息();
                            重置加载状态();
                            开始自动加载();
                        }, 500); // 额外延迟,确保子栏目已经渲染
                    }
                }, 300);
            });
        });
        
        // 添加MutationObserver监听大栏目切换,作为点击事件的补充
        const tabsContent = document.querySelector('.rc-tabs-content');
        if (tabsContent) {
            const observer = new MutationObserver(mutations => {
                for (const mutation of mutations) {
                    if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                        // 检查当前激活的面板
                        const activePanel = document.querySelector('.rc-tabs-tabpane-active');
                        if (activePanel) {
                            const panelId = activePanel.id;
                            if (panelId.includes('PUBLISH')) {
                                if (currentSection !== 'PUBLISH') {
                                    currentSection = 'PUBLISH';
                                    console.log(`检测到大栏目切换: ${currentSection}`);
                                    获取当前激活的子栏目();
                                    更新栏目信息();
                                }
                            } else if (panelId.includes('COLLECT')) {
                                if (currentSection !== 'COLLECT') {
                                    currentSection = 'COLLECT';
                                    console.log(`检测到大栏目切换: ${currentSection}`);
                                    获取当前激活的子栏目();
                                    更新栏目信息();
                                }
                            }
                        }
                    }
                }
            });
            
            // 监听所有选项卡内容面板的class变化
            const tabPanes = document.querySelectorAll('.rc-tabs-tabpane');
            tabPanes.forEach(pane => {
                observer.observe(pane, { attributes: true });
            });
        }
        
        // 获取当前激活的子栏目
    function 获取当前激活的子栏目() {
        try {
            // 查找所有可能的子栏目按钮
            const allButtons = [];
            
            // 发布栏目按钮
            const publishButtons = document.evaluate(XPATHS.publishQuestion + ' | ' + 
                                                  XPATHS.publishAnswer + ' | ' + 
                                                  XPATHS.publishArticle, 
                                                  document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
            
            // 收藏栏目按钮
            const collectButtons = document.evaluate(XPATHS.collectQa + ' | ' + 
                                                  XPATHS.collectArticle, 
                                                  document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
            
            // 收集发布栏目按钮
            for (let i = 0; i < publishButtons.snapshotLength; i++) {
                allButtons.push(publishButtons.snapshotItem(i));
            }
            
            // 收集收藏栏目按钮
            for (let i = 0; i < collectButtons.snapshotLength; i++) {
                allButtons.push(collectButtons.snapshotItem(i));
            }
            
            // 查找激活状态的按钮
            for (const button of allButtons) {
                // 检查按钮是否有激活状态的样式或类
                const classList = button.classList;
                const parentClassList = button.parentNode ? button.parentNode.classList : [];
                
                // 通常激活的按钮会有特定的样式或类名标记
                if (classList.contains('active') || 
                    parentClassList.contains('active') ||
                    classList.contains('selected') ||
                    parentClassList.contains('selected') ||
                    button.style.color === 'rgb(59, 130, 246)' || // 假设激活状态是蓝色
                    button.style.fontWeight === 'bold') {
                    
                    currentSubSection = button.textContent.trim();
                    console.log(`检测到当前激活子栏目: ${currentSubSection}`);
                    return;
                }
            }
            
            // 如果没有找到激活的按钮,尝试根据当前显示的内容推断
            if (document.querySelector('.answer-item')) {
                currentSubSection = '回答';
            } else if (document.querySelector('.qa-item')) {
                currentSubSection = currentSection === 'PUBLISH' ? '提问' : '问答';
            } else if (document.querySelector('.article-item')) {
                currentSubSection = '文章';
            }
            
            console.log(`推断当前子栏目: ${currentSubSection}`);
        } catch (e) {
            console.error('获取当前激活子栏目失败:', e);
        }
    }
    
    // 监听子栏目切换 - 优化版,确保覆盖所有栏目并正确显示当前状态
    function 监听子栏目按钮() {
        const buttons = [];
        
        // 尝试获取所有可能的子栏目按钮
        try {
            // 发布栏目按钮
            if (currentSection === 'PUBLISH') {
                const questionBtn = document.evaluate(XPATHS.publishQuestion, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                const answerBtn = document.evaluate(XPATHS.publishAnswer, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                const articleBtn = document.evaluate(XPATHS.publishArticle, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                
                if (questionBtn) buttons.push(questionBtn);
                if (answerBtn) buttons.push(answerBtn);
                if (articleBtn) buttons.push(articleBtn);
            } 
            // 收藏栏目按钮
            else if (currentSection === 'COLLECT') {
                const qaBtn = document.evaluate(XPATHS.collectQa, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                const articleBtn = document.evaluate(XPATHS.collectArticle, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                
                if (qaBtn) buttons.push(qaBtn);
                if (articleBtn) buttons.push(articleBtn);
            }
            
            // 添加全局查找,确保不会遗漏任何子栏目按钮
            const allSubSectionButtons = document.querySelectorAll('.menu-item___397g0');
            allSubSectionButtons.forEach(btn => {
                if (!buttons.includes(btn)) {
                    buttons.push(btn);
                }
            });
            
            // 再次添加全局兜底方案,查找所有可能的按钮
            const sectionButtons = document.querySelectorAll('.btn___N0geJ button, .btn-group button, .submenu button');
            sectionButtons.forEach(btn => {
                if (btn.textContent && 
                    (btn.textContent.includes('提问') || 
                     btn.textContent.includes('回答') || 
                     btn.textContent.includes('文章') || 
                     btn.textContent.includes('问答')) && 
                    !buttons.includes(btn)) {
                    buttons.push(btn);
                }
            });
        } catch (e) {
            console.error('获取子栏目按钮失败:', e);
        }
        
        // 为按钮添加点击事件
        buttons.forEach(button => {
            // 避免重复添加事件
            if (!button.hasAttribute('data-listener-added')) {
                button.setAttribute('data-listener-added', 'true');
                
                button.addEventListener('click', function() {
                    const buttonText = this.textContent.trim();
                    currentSubSection = buttonText;
                    
                    // 立即在控制台显示切换到的子栏目,使用明确的格式
                    console.log(`当前栏目: ${currentSection}-${currentSubSection}`);
                    
                    // 根据不同栏目设置不同的初始延时
                    const 延时时间 = currentSubSection.includes('回答') ? 配置.回答栏目初始延时 : 配置.初始延时;
                    console.log(`栏目切换后等待 ${延时时间}ms 再开始加载`);
                    
                    // 延迟执行,等待DOM更新
                    setTimeout(() => {
                        // 再次确认当前栏目信息
                        获取当前激活的子栏目();
                        // 确保在控制台显示最新的完整栏目信息,包括总数
                        更新栏目信息();
                        // 重置搜索状态,清除之前的搜索高亮
                        清除所有高亮();
                        // 重置加载状态
                        重置加载状态();
                        // 开始自动加载
                        开始自动加载();
                    }, 延时时间);
                });
            }
        });
    }
        
        // 定期检查子栏目按钮
        setInterval(监听子栏目按钮, 1000);
        监听子栏目按钮(); // 立即执行一次
    }

    // 更新栏目信息
    function 更新栏目信息() {
        try {
            let targetButton;
            let sectionText = '';
            
            // 根据当前栏目获取对应的按钮
            if (currentSection === 'PUBLISH') {
                sectionText = '发布';
                if (currentSubSection.includes('提问')) {
                    targetButton = document.evaluate(XPATHS.publishQuestion, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                } else if (currentSubSection.includes('回答')) {
                    targetButton = document.evaluate(XPATHS.publishAnswer, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                } else if (currentSubSection.includes('文章')) {
                    targetButton = document.evaluate(XPATHS.publishArticle, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                }
            } else if (currentSection === 'COLLECT') {
                sectionText = '收藏';
                if (currentSubSection.includes('问答')) {
                    targetButton = document.evaluate(XPATHS.collectQa, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                } else if (currentSubSection.includes('文章')) {
                    targetButton = document.evaluate(XPATHS.collectArticle, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                }
            }
            
            // 提取数量
            if (targetButton) {
                const text = targetButton.textContent;
                const match = text.match(/\((\d+)\)/);
                if (match && match[1]) {
                    totalCount = parseInt(match[1], 10);
                    // 确保控制台显示完整的栏目信息,使用统一格式
                    console.log(`当前栏目: ${currentSection}-${currentSubSection}(${totalCount})`);
                    return;
                }
            }
            
            // 备用方案:尝试从其他位置获取总数
            if (currentSection === 'COLLECT') {
                // 对于收藏栏目,尝试查找其他可能包含总数的元素
                const collectCountElements = document.querySelectorAll('.rc-tabs-tab[data-tab-key="COLLECT"]');
                if (collectCountElements.length > 0) {
                    const text = collectCountElements[0].textContent;
                    const match = text.match(/\((\d+)\)/);
                    if (match && match[1]) {
                        totalCount = parseInt(match[1], 10);
                        // 确保控制台显示完整的栏目信息,使用统一格式
                        console.log(`当前栏目: ${currentSection}-${currentSubSection}(${totalCount})`);
                        return;
                    }
                }
                
                // 收藏栏目特定处理:尝试从当前活动的子栏目按钮获取数量
                const activeSubSectionButtons = document.querySelectorAll(`#rc-tabs-0-panel-COLLECT .btn___N0geJ button`);
                for (const button of activeSubSectionButtons) {
                    const text = button.textContent;
                    const match = text.match(/\((\d+)\)/);
                    if (match && match[1]) {
                        // 检查这个按钮是否是激活状态
                        if (button.classList.contains('active') || 
                            button.parentNode.classList.contains('active') ||
                            button.style.color === 'rgb(59, 130, 246)' || 
                            button.style.fontWeight === 'bold') {
                            totalCount = parseInt(match[1], 10);
                            console.log(`当前栏目: ${currentSection}-${currentSubSection}(${totalCount})`);
                            return;
                        }
                    }
                }
            }
            
            // 如果无法获取数量,设置默认值
            totalCount = 100; // 默认值
            console.log(`无法获取栏目数量,使用默认值: ${totalCount}`);
            // 仍然显示当前栏目信息,即使无法获取精确数量
            console.log(`当前栏目: ${currentSection}-${currentSubSection}(~${totalCount})`);
        } catch (e) {
            console.error('更新栏目信息失败:', e);
            totalCount = 100;
            // 即使出错,也要确保控制台显示当前栏目信息
            console.log(`当前栏目: ${currentSection}-${currentSubSection}(~${totalCount})`);
        }
    }

    // 设置页面变化监听
    function 设置页面变化监听() {
        const observer = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
                // 检查是否有新内容加载
                if (mutation.addedNodes.length > 0) {
                    // 更新已加载数量
                    更新已加载数量();
                    
                    // 检查是否需要继续加载
                    if (!isLoading && loadedCount < totalCount) {
                        检查并点击查看更多();
                    }
                }
            });
        });
        
        // 监听页面主体内容变化
        const contentArea = document.querySelector('.rc-tabs-content');
        if (contentArea) {
            observer.observe(contentArea, {
                childList: true,
                subtree: true
            });
        }
    }

    // 更新已加载数量 - 优化版,确保与当前栏目正确绑定
    function 更新已加载数量() {
        try {
            // 构建选择器,确保只统计当前活动面板中的内容
            let selector = '';
            
            if (currentSection === 'PUBLISH') {
                // 只统计发布面板中的内容
                selector = '#rc-tabs-0-panel-PUBLISH .article-item, ' +
                           '#rc-tabs-0-panel-PUBLISH .qa-item, ' +
                           '#rc-tabs-0-panel-PUBLISH .answer-item, ' +
                           '#rc-tabs-0-panel-PUBLISH .list_item___nmNeS, ' +
                           '#rc-tabs-0-panel-PUBLISH .list___18bDQ > div';
                
                // 特别为回答栏目添加更精确的选择器
                if (currentSubSection.includes('回答')) {
                    selector += ', #rc-tabs-0-panel-PUBLISH .answer-item, ' +
                               '#rc-tabs-0-panel-PUBLISH [class*="answer"].item, ' +
                               '#rc-tabs-0-panel-PUBLISH [data-type="answer"]';
                }
            } else if (currentSection === 'COLLECT') {
                // 只统计收藏面板中的内容
                selector = '#rc-tabs-0-panel-COLLECT .article-item, ' +
                           '#rc-tabs-0-panel-COLLECT .qa-item, ' +
                           '#rc-tabs-0-panel-COLLECT .answer-item, ' +
                           '#rc-tabs-0-panel-COLLECT .list_item___nmNeS, ' +
                           '#rc-tabs-0-panel-COLLECT .fav-item, ' +
                           '#rc-tabs-0-panel-COLLECT .collect-item, ' +
                           '#rc-tabs-0-panel-COLLECT .list___18bDQ > div';
            }
            
            // 获取当前面板中所有匹配的项目
            const items = document.querySelectorAll(selector);
            
            // 更新已加载数量
            loadedCount = items.length;
            
            // 在控制台显示详细信息,包括当前栏目和已加载数量
            console.log(`当前栏目: ${currentSection}-${currentSubSection} | 已加载数量: ${loadedCount}/${totalCount}`);
        } catch (e) {
            console.error('更新已加载数量失败:', e);
        }
    }

    // 重置加载状态
    function 重置加载状态() {
        isLoading = false;
        loadedCount = 0;
        retryCount = 0; // 重置重试计数
        
        // 清除之前的定时器
        if (loadInterval) {
            clearInterval(loadInterval);
            loadInterval = null;
        }
    }

    // 开始自动加载
    function 开始自动加载() {
        // 重置重试计数
        retryCount = 0;
        
        // 先立即执行一次加载检查
        检查并点击查看更多();
        
        // 设置定时加载
        loadInterval = setInterval(() => {
            检查并点击查看更多();
        }, 配置.检查间隔); // 使用配置的检查间隔
        
        console.log(`开始自动加载,检查间隔:${配置.检查间隔}ms`);
    }

    // 检查并点击查看更多
    function 检查并点击查看更多() {
        // 如果已经在加载中,不重复触发
        if (isLoading) return;
        
        // 检查是否已达到总数量
        if (loadedCount >= totalCount) {
            console.log('已达到总数量,停止加载');
            if (loadInterval) {
                clearInterval(loadInterval);
                loadInterval = null;
            }
            return;
        }
        
        try {
            // 查找查看更多按钮 - 尝试多种选择器
            let viewMoreButton = null;
            
            // 1. 使用XPath选择器(原方案)
            try {
                viewMoreButton = document.evaluate(XPATHS.viewMore, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            } catch (xpathError) {
                console.warn('XPath查找失败:', xpathError);
            }
            
            // 2. 备选方案:使用CSS选择器
            if (!viewMoreButton) {
                viewMoreButton = document.querySelector(".rc-tabs-tabpane-active span:contains('查看更多')") || 
                               document.querySelector("span:contains('查看更多')");
            }
            
            // 3. 备选方案:查找所有文本包含'查看更多'的元素
            if (!viewMoreButton) {
                const allSpans = document.querySelectorAll('span');
                for (const span of allSpans) {
                    if (span.textContent && span.textContent.trim() === '查看更多') {
                        viewMoreButton = span;
                        break;
                    }
                }
            }
            
            if (viewMoreButton) {
                // 重置重试计数,因为找到了按钮
                retryCount = 0;
                
                isLoading = true;
                console.log('点击"查看更多"按钮,加载更多内容...');
                
                // 点击查看更多按钮
                viewMoreButton.click();
                
                // 设置智能延迟,避免服务器繁忙
                setTimeout(() => {
                    isLoading = false;
                    // 点击后强制更新已加载数量
                    更新已加载数量();
                }, 2000 + Math.random() * 1000); // 2-3秒随机延迟
            } else {
                // 增加重试计数
                retryCount++;
                
                // 根据当前栏目调整重试逻辑
                const isAnswerSection = currentSubSection.includes('回答');
                const maxRetriesForSection = isAnswerSection ? maxRetries * 2 : maxRetries;
                
                console.log(`未找到"查看更多"按钮 (重试 ${retryCount}/${maxRetriesForSection})`);
                
                // 对于回答栏目,增加更多的重试机会
                if (retryCount >= maxRetriesForSection) {
                    console.log('达到最大重试次数,停止自动重试');
                    // 注意:不清除定时器,让定期检查继续运行
                } else {
                    console.log(`将在 ${配置.重试间隔}ms 后再次尝试查找`);
                }
            }
        } catch (e) {
            console.error('点击查看更多失败:', e);
            isLoading = false;
        }
    }

    // 修改请求参数 - 保留此函数以确保兼容性
    function 修改请求参数() {
        try {
            console.log('修改请求参数被调用,但已通过API拦截器处理');
            
            // 获取当前栏目信息
            const 栏目信息 = 获取当前栏目信息();
            console.log('当前栏目信息:', 栏目信息);
            
            // 这里可以添加特定栏目的处理逻辑
        } catch (error) {
            console.error('修改请求参数失败:', error);
        }
    }

    // 启动脚本
    setTimeout(() => {
        初始化();
        // 初始加载时获取当前激活的子栏目
        setTimeout(() => {
            获取当前激活的子栏目();
            更新栏目信息();
        }, 500);
    }, 1000);
})();


收藏
全部评论1
最新
发布评论
评论