bai

百家号主页UID提取,隐藏图片,作品首次发布时间由相对时间改为绝对时间,解除复制限制(支持PC和移动端)

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         bai
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  百家号主页UID提取,隐藏图片,作品首次发布时间由相对时间改为绝对时间,解除复制限制(支持PC和移动端)
// @author       祝大家天天爆文! [email protected]
// @match        https://author.baidu.com/home/*
// @icon         https://www.baidu.com/favicon.ico
// @license      AGPL-3.0-only
// @grant        unsafeWindow
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // 检测是否为移动端
    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) 
                     || window.innerWidth < 768;

    // PC端样式
    const pcStyles = `
        .pc-topbar{display:none !important}
        .s-col.s-col-4.sfi-article-cover{display:none !important}
        .s-col.s-col-4.s-right-img-texts-cover{display:none !important}
        .s-col.s-col-4.s-image-set-cover{display:none !important}
        .s-col.s-col-8.s-image-set-cover{display:none !important}
        .sfi-video-image{display:none !important}
        .s-row.s-row-flex.s-row-wrap.sfi-n-smallVideo.imgsize-1{display:none !important}
        .avatar{display:none !important}
        .operate-btn.chat{display:none !important}
        .s-subscribes.head.pc-user-uhFollow.operate-btn{display:none !important}
    `;

    // 移动端样式
    const mobileStyles = `
        /* 隐藏移动端顶部导航 */
        .wap-topbar, .m-topbar, header{display:none !important}
        
        /* 隐藏移动端所有图片封面 */
        .article-cover, .video-cover, .dynamic-cover{display:none !important}
        img[class*="cover"], img[class*="thumb"]{display:none !important}
        
        /* 隐藏移动端视频封面 */
        .video-img, .video-image, .m-video-cover{display:none !important}
        
        /* 隐藏移动端头像 */
        .avatar, .user-avatar, img[class*="avatar"]{display:none !important}
        
        /* 隐藏移动端按钮 */
        .follow-btn, .chat-btn, .subscribe-btn{display:none !important}
        
        /* 隐藏所有可能的图片容器 */
        [class*="image-wrapper"], [class*="img-container"]{display:none !important}
    `;

    // 应用对应平台的样式
    GM_addStyle(isMobile ? mobileStyles : pcStyles);

    // 时间格式化
    const formatTimestamp = (timestamp) => {
        const date = new Date(timestamp * 1000);
        const now = new Date();
        const pad = n => n.toString().padStart(2, '0');
        const year = date.getFullYear();
        const month = pad(date.getMonth() + 1);
        const day = pad(date.getDate());
        const hours = pad(date.getHours());
        const minutes = pad(date.getMinutes());

        return (year === now.getFullYear())
            ? `${month}-${day} ${hours}:${minutes}`
            : `${year}-${month}-${day} ${hours}:${minutes}`;
    };

    // PC端处理配置
    const pcTypeConfig = {
        article: {
            selector: '.sfi-article-subscript',
            timeIndex: 2,
            insertPosition: 'beforeend'
        },
        dynamic: {
            selector: '.sfi-dynamic-subscript',
            timeIndex: null,
            insertPosition: 'beforeend'
        },
        mainSmallVideo: {
            selector: '.sfi-n-smallVideo-subscript',
            timeIndex: null,
            insertPosition: 'beforeend'
        },
        video: {
            selector: '.sfi-video-subscript',
            timeIndex: 1,
            insertPosition: 'beforeend'
        },
        zhibo: {
            selector: '.sfi-live-subscript',
            timeIndex: 1,
            insertPosition: 'beforeend',
            extraProcess: (container) => {
                const liveTag = document.querySelector('.sfi-live-status-tag');
                if (liveTag) {
                    const viewers = liveTag.parentNode.textContent.match(/\d+/)?.[0] || '未知';
                    container.insertAdjacentHTML('afterbegin',
                        `<span>${liveTag.textContent}: ${viewers}人观看</span>`);
                    liveTag.parentNode.remove();
                }
            }
        }
    };

    // PC端处理器
    const processItemPC = (item) => {
        const itemType = item.getAttribute('itemtype')?.split('/').pop();
        const config = pcTypeConfig[itemType];
        if (!config) return;

        const container = item.querySelector(config.selector);
        if (!container) return;

        if (config.timeIndex !== null) {
            const timeSpan = container.children[config.timeIndex];
            const timestamp = item.children[0]?.getAttribute('publish_at');
            if (timeSpan && timestamp) {
                timeSpan.textContent = formatTimestamp(timestamp);
            }
        }

        const feedId = item.getAttribute('feed_id');
        if (feedId && !container.querySelector('[data-nid-added]')) {
            const nidSpan = document.createElement('span');
            nidSpan.textContent = `nid: ${feedId}`;
            nidSpan.dataset.nidAdded = true;
            nidSpan.style.cssText = 'color: #ff6b6b; font-weight: bold; margin-left: 10px;';
            container.insertAdjacentElement(config.insertPosition, nidSpan);
        }

        config.extraProcess?.(container);
    };

    // 移动端处理器
    const processItemMobile = (item) => {
        // 查找所有可能包含时间和信息的元素
        const timeSelectors = [
            '.time', '.publish-time', '.date',
            '[class*="time"]', '[class*="date"]',
            'time', 'span[class*="meta"]'
        ];

        let timeElement = null;
        for (const selector of timeSelectors) {
            timeElement = item.querySelector(selector);
            if (timeElement) break;
        }

        // 尝试提取feed_id或其他ID
        const feedId = item.getAttribute('data-feed-id') 
                    || item.getAttribute('feed_id')
                    || item.getAttribute('data-id')
                    || item.id;

        if (feedId && !item.querySelector('[data-nid-added]')) {
            const nidSpan = document.createElement('div');
            nidSpan.textContent = `nid: ${feedId}`;
            nidSpan.dataset.nidAdded = true;
            nidSpan.style.cssText = `
                color: #ff6b6b;
                font-weight: bold;
                font-size: 12px;
                margin-top: 5px;
                padding: 3px 8px;
                background: #fff3f3;
                border-radius: 4px;
                display: inline-block;
            `;

            // 尝试插入到合适的位置
            if (timeElement && timeElement.parentNode) {
                timeElement.parentNode.appendChild(nidSpan);
            } else {
                const contentArea = item.querySelector('.content, .article-content, [class*="content"]');
                if (contentArea) {
                    contentArea.appendChild(nidSpan);
                } else {
                    item.appendChild(nidSpan);
                }
            }
        }

        // 处理时间格式
        if (timeElement) {
            const timestamp = item.getAttribute('data-publish-time') 
                           || item.getAttribute('publish_at')
                           || item.getAttribute('data-time');
            
            if (timestamp) {
                timeElement.textContent = formatTimestamp(timestamp);
            }
        }
    };

    // 主处理函数
    const processItem = (item) => {
        if (isMobile) {
            processItemMobile(item);
        } else {
            processItemPC(item);
        }
    };

    // 通用选择器(适配PC和移动端)
    const itemSelectors = [
        '[itemtype]',              // PC端
        '[data-feed-id]',          // 移动端可能的选择器
        '.article-item',           // 通用文章项
        '.video-item',             // 通用视频项
        '[class*="feed-item"]',    // 包含feed-item的类
        '[class*="content-item"]'  // 包含content-item的类
    ];

    // DOM监听器
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === 1) {
                    // 检查是否匹配任何一个选择器
                    for (const selector of itemSelectors) {
                        if (node.matches && node.matches(selector)) {
                            processItem(node);
                            break;
                        }
                    }
                    
                    // 也检查子元素
                    itemSelectors.forEach(selector => {
                        node.querySelectorAll?.(selector).forEach(processItem);
                    });
                }
            });
        });
    });

    // 初始化
    const init = () => {
        console.log(`[百家号助手] 运行模式: ${isMobile ? '移动端' : 'PC端'}`);
        
        // 处理已存在的元素
        itemSelectors.forEach(selector => {
            document.querySelectorAll(selector).forEach(processItem);
        });

        // 开始监听
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

        // 额外隐藏所有图片(兜底方案)
        setTimeout(() => {
            document.querySelectorAll('img').forEach(img => {
                if (!img.alt?.includes('icon') && !img.src?.includes('icon')) {
                    img.style.display = 'none';
                }
            });
        }, 1000);
    };

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

})();