运用以下工具,针对网页的喜欢列表展开监听。

【25/6/4】抖音/快手下载工具v3.1 支持点赞下载 - 吾爱破解 - 52pojie.cn

该工具仅能监听网页加载呈现出的喜欢列表。倘若点赞列表数量庞大,手动通过滚轮操作将会极为繁琐。

最初,我考虑运用鼠标模拟软件来实现自动滚动。然而,存在两个问题:其一,当拉取过多喜欢列表时,通过F12查看网页会发现,<li>标签数量过多,浏览器难以承受,极有可能导致崩溃;其二,鼠标必须置于抖音网页喜欢列表区域,鼠标模拟软件方可进行下拉操作。



因此,我编写了此油猴脚本,其功能在于限制 <li> 元素的数量,并实现自动滚动。通过这种方式,能够有效降低网页内存占用,同时用户可将鼠标移至其他区域,而不会对脚本功能及其他操作造成影响。

// ==UserScript==
// @name         抖音列表调试脚本
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  带详细调试日志的列表优化脚本
// @author       doubao
// @match        https://www.douyin.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 配置项(需根据实际情况修改)
    const LIST_CONTAINER = 'ul[data-e2e="scroll-list"]'; // 目标容器选择器
    const LIST_ITEM = 'li[class*="niBfRBgX"]';          // li元素选择器
    const KEEP_LAST = 20;                                // 保留数量

    // 主函数
    function init() {
        console.log('【脚本启动】开始监控列表容器:', LIST_CONTAINER);

        // 首次检查
        checkAndClean();

        // 监听滚动(带防抖)
        const scrollHandler = debounce(() => {
            console.log('【触发滚动】检查列表更新...');
            checkAndClean();
        }, 500);
        window.addEventListener('scroll', scrollHandler);

        // 监听容器DOM变化
        observeContainer();

        // 监听文档(容器未加载时)
        observeDocument();
    }

    // 检查并清理旧元素
    function checkAndClean() {
        const container = document.querySelector(LIST_CONTAINER);
        if (!container) {
            console.log('【警告】未找到容器:', LIST_CONTAINER);
            return;
        }

        const allItems = container.querySelectorAll(LIST_ITEM);
        console.log(`【当前列表】容器存在,检测到${allItems.length}条li`);

        if (allItems.length <= KEEP_LAST) {
            console.log(`【无需清理】数量(${allItems.length})≤保留数(${KEEP_LAST})`);
            return;
        }

        // 执行清理
        const toKeep = allItems.length - KEEP_LAST;
        const itemsToRemove = Array.from(allItems).slice(0, toKeep);
        itemsToRemove.forEach(item => {
            console.log(`【删除元素】移除旧li: ${item.textContent.substr(0, 30)}...`);
        });

        // 批量删除
        const fragment = document.createDocumentFragment();
        itemsToRemove.forEach(item => fragment.appendChild(item));
        container.removeChild(fragment);

        console.log(`【清理完成】已删除${itemsToRemove.length}条,剩余${KEEP_LAST}条`);
    }

    // 监听容器变化
    function observeContainer() {
        const container = document.querySelector(LIST_CONTAINER);
        if (container) {
            const observer = new MutationObserver(mutations => {
                mutations.forEach(mut => {
                    if (mut.type === 'childList') {
                        console.log('【触发Mutation】容器子节点变化,检查列表...');
                        checkAndClean();
                    }
                });
            });
            observer.observe(container, { childList: true, subtree: true });
            console.log('【监听成功】已绑定容器MutationObserver');
        }
    }

    // 监听文档(容器未加载时)
    function observeDocument() {
        const docObserver = new MutationObserver(mutations => {
            mutations.forEach(mut => {
                if (mut.type === 'childList') {
                    const container = document.querySelector(LIST_CONTAINER);
                    if (container) {
                        console.log('【文档监听】发现容器加载,切换至容器监听模式');
                        docObserver.disconnect();
                        observeContainer();
                        checkAndClean();
                    }
                }
            });
        });
        docObserver.observe(document.body, { childList: true, subtree: true });
        console.log('【监听成功】已绑定文档MutationObserver(等待容器加载)');
    }

    // 防抖函数
    function debounce(func, wait) {
        let timeout;
        return function() {
            const context = this;
            const args = arguments;
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(context, args), wait);
        };
    }

    // 立即执行初始化
    init();
})();