吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 669|回复: 6
上一主题 下一主题
收起左侧

[其他转载] 微博网页版 搜索一键拉黑脚本,首页 一键拉黑。油猴脚本 ai写的

  [复制链接]
跳转到指定楼层
楼主
遇见你 发表于 2026-7-7 15:13 回帖奖励
搞这个玩意儿,初衷。网页版微博,哎,经常刷着刷着,中间插播一条什么谁 发的微博,根本就没有关注,真的跟个神经病一样,我没有关注你推,那不就是广告了?你投流了,我就要看啊。哎呀,没有解决办法,我先把这新浪开头的一批账号先拉黑了。

结果不是不知道,一说吓一跳,耶!进新浪单独运营账号这么多呀。应该不是一个人运营一个账号吧?那不知道要开多少工位。而且点进去,有些账号很久都没更新了,还有一些账号不是他的,嗯,专享他还在发。应该是矩阵多账号,批量那种的。

哎呀,搜索结果,然后点进账号,然后主页要点右边三个点,然后再点加入黑名单,再确认。哎,这步骤太麻烦了。

我就让AI写一个啊,让DeepSeek给我写一个。写了好几个版本,哎呀,问题太多了,非要获取什么令牌,麻烦麻烦的,搞了七八个版本不行,烦了,我去转头找隔壁 Kimi 了。

kimi慢是慢了点,哎呀,确实太慢了,要一两分钟才出结果。不过一次成功还好。

个人主页一键拉黑成功,好。然后转头找DeepSeek,把代码给他,让他学着在搜索页面来搞。结果这个笨蛋输出结果快是快,但是没用啊,输出三四个版本也不行。

啊,又转头找Kimi开新窗口。哎呀,那个窗口对话呃对话达到上限了。第一次失败,第二次成功了。



我用的是篡改猴。
最后就是代码都是Kimi搞出来的。
// ==UserScript==
// [url=home.php?mod=space&uid=170990]@name[/url]         微博一键拉黑
// [url=home.php?mod=space&uid=467642]@namespace[/url]    http://tampermonkey.net/
// [url=home.php?mod=space&uid=1248337]@version[/url]      1.0
// @description  在微博个人主页添加一键拉黑按钮,省去繁琐操作
// [url=home.php?mod=space&uid=686208]@AuThor[/url]       You
// [url=home.php?mod=space&uid=195849]@match[/url]        https://weibo.com/u/*
// @match        https://weibo.com/*
// [url=home.php?mod=space&uid=609072]@grant[/url]        GM_xmlhttpRequest
// @grant        GM_notification
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // 配置
    const CONFIG = {
        buttonText: '一键拉黑',
        buttonColor: '#ff4d4f',
        buttonHoverColor: '#ff7875',
        undoTimeout: 5000, // 撤销时间窗口(毫秒)
    };

    // 存储当前页面用户信息
    let currentUserInfo = {
        uid: null,
        nickname: '',
        blocked: false
    };

    let undoTimer = null;
    let toastElement = null;
    let undoBarElement = null;

    // ========== 工具函数 ==========

    // 获取当前页面用户UID
    function getCurrentUID() {
        // 方法1: 从URL提取
        const match = location.pathname.match(/\/u\/(\d+)/);
        if (match) return match[1];

        // 方法2: 从页面脚本变量提取
        if (window.$$CONFIG && window.$$CONFIG.uid) {
            return window.$$CONFIG.uid;
        }

        // 方法3: 从DOM提取
        const usercardLinks = document.querySelectorAll('a[usercard]');
        for (let link of usercardLinks) {
            const uid = link.getAttribute('usercard');
            if (uid && /^\d+$$/.test(uid)) return uid;
        }

        // 方法4: 从关注按钮提取
        const followBtn = document.querySelector('[user]');
        if (followBtn) {
            const userAttr = followBtn.getAttribute('user');
            try {
                const userObj = JSON.parse(userAttr);
                if (userObj.id) return userObj.id;
            } catch(e) {}
        }

        return null;
    }

    // 获取用户昵称
    function getNickname() {
        const nameEl = document.querySelector('._name_1yc79_291, .woo-box-flex ._nick_ygi5b_25 span[title], h1[class*="name"], [class*="nickname"]');
        if (nameEl) return nameEl.textContent.trim();

        const title = document.querySelector('title');
        if (title) {
            const match = title.textContent.match(/@(.+) 的个人主页/);
            if (match) return match[1];
        }

        return '该用户';
    }

    // 获取微博的cookie和token
    function getToken() {
        // 从cookie获取XSRF-TOKEN
        const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
        if (match) return decodeURIComponent(match[1]);
        return '';
    }

    // ========== UI组件 ==========

    // 创建Toast提示
    function createToast() {
        if (toastElement) return toastElement;

        const toast = document.createElement('div');
        toast.id = 'wblk-toast';
        toast.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) scale(0);
            background: rgba(0,0,0,0.85);
            color: white;
            padding: 16px 28px;
            border-radius: 12px;
            font-size: 16px;
            font-weight: 600;
            z-index: 999999;
            transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
            display: flex;
            align-items: center;
            gap: 10px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.3);
            pointer-events: none;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        `;
        document.body.appendChild(toast);
        toastElement = toast;
        return toast;
    }

    // 显示Toast
    function showToast(text, type = 'success') {
        const toast = createToast();
        const iconColor = type === 'success' ? '#52c41a' : type === 'error' ? '#ff4d4f' : '#faad14';
        const iconSvg = type === 'success'
            ? '<polyline points="20 6 9 17 4 12" style="fill:none;stroke:' + iconColor + ';stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"/>'
            : '<circle cx="12" cy="12" r="10" style="fill:none;stroke:' + iconColor + ';stroke-width:2.5"/><line x1="12" y1="8" x2="12" y2="12" style="stroke:' + iconColor + ';stroke-width:2.5;stroke-linecap:round"/><line x1="12" y1="16" x2="12.01" y2="16" style="stroke:' + iconColor + ';stroke-width:2.5;stroke-linecap:round"/>';

        toast.innerHTML = `
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none">$${iconSvg}</svg>
            <span>$${text}</span>
        `;
        toast.style.transform = 'translate(-50%, -50%) scale(1)';

        setTimeout(() => {
            toast.style.transform = 'translate(-50%, -50%) scale(0)';
        }, 2000);
    }

    // 创建撤销条
    function createUndoBar() {
        if (undoBarElement) return undoBarElement;

        const bar = document.createElement('div');
        bar.id = 'wblk-undo-bar';
        bar.style.cssText = `
            position: fixed;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%) translateY(100px);
            background: #1a1a1a;
            color: white;
            padding: 12px 20px;
            border-radius: 24px;
            font-size: 14px;
            z-index: 999999;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 16px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.3);
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        `;
        document.body.appendChild(bar);
        undoBarElement = bar;
        return bar;
    }

    // 显示撤销条
    function showUndoBar(uid, nickname) {
        const bar = createUndoBar();
        bar.innerHTML = `
            <span>已拉黑 <b style="color:#ff8200">$${nickname}</b></span>
            <button id="wblk-undo-btn" style="
                background: transparent;
                border: 1px solid rgba(255,255,255,0.3);
                color: #ff8200;
                padding: 4px 12px;
                border-radius: 12px;
                cursor: pointer;
                font-size: 13px;
                font-weight: 600;
                transition: all 0.2s;
            ">撤销</button>
        `;
        bar.style.transform = 'translateX(-50%) translateY(0)';

        // 绑定撤销事件
        const undoBtn = bar.querySelector('#wblk-undo-btn');
        undoBtn.addEventListener('click', () => {
            unblockUser(uid, nickname);
            bar.style.transform = 'translateX(-50%) translateY(100px)';
            clearTimeout(undoTimer);
        });

        // 自动隐藏
        clearTimeout(undoTimer);
        undoTimer = setTimeout(() => {
            bar.style.transform = 'translateX(-50%) translateY(100px)';
        }, CONFIG.undoTimeout);
    }

    // ========== 核心功能 ==========

    // 一键拉黑
    function blockUser(uid, nickname) {
        if (!uid) {
            showToast('未获取到用户ID,请刷新页面重试', 'error');
            return;
        }

        const token = getToken();
        if (!token) {
            showToast('未登录或登录已过期,请先登录', 'error');
            return;
        }

        // 显示加载状态
        const btn = document.getElementById('wblk-block-btn');
        if (btn) {
            btn.innerHTML = `
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" style="animation: wblk-spin 1s linear infinite">
                    <circle cx="12" cy="12" r="10" stroke-dasharray="60" stroke-dashoffset="20" stroke-linecap="round"/>
                </svg>
                处理中...
            `;
        }

        // 调用微博拉黑API
        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://weibo.com/aj/filter/block?ajwvr=6',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-Requested-With': 'XMLHttpRequest',
                'Referer': location.href
            },
            data: `uid=$${uid}&filter_type=1&status=1&interact=1&follow=1&__rnd=$${Date.now()}`,
            onload: function(response) {
                try {
                    const res = JSON.parse(response.responseText);
                    if (res.code === '100000' || res.code === 100000) {
                        currentUserInfo.blocked = true;
                        updateButtonState(true);
                        showToast(`已成功拉黑 @$${nickname}`);
                        showUndoBar(uid, nickname);

                        // 可选:发送桌面通知
                        GM_notification({
                            title: '微博一键拉黑',
                            text: `已拉黑用户:$${nickname}`,
                            timeout: 3000
                        });
                    } else {
                        throw new Error(res.msg || '操作失败');
                    }
                } catch(e) {
                    console.error('[微博一键拉黑] 响应解析失败:', e);
                    showToast('操作失败:' + e.message, 'error');
                    updateButtonState(false);
                }
            },
            onerror: function(err) {
                console.error('[微博一键拉黑] 请求失败:', err);
                showToast('网络请求失败,请检查网络连接', 'error');
                updateButtonState(false);
            }
        });
    }

    // 撤销拉黑
    function unblockUser(uid, nickname) {
        if (!uid) return;

        const token = getToken();

        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://weibo.com/aj/filter/block?ajwvr=6',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-Requested-With': 'XMLHttpRequest',
                'Referer': location.href
            },
            data: `uid=$${uid}&filter_type=1&status=0&interact=0&follow=0&__rnd=$${Date.now()}`,
            onload: function(response) {
                try {
                    const res = JSON.parse(response.responseText);
                    if (res.code === '100000' || res.code === 100000) {
                        currentUserInfo.blocked = false;
                        updateButtonState(false);
                        showToast(`已撤销对 @$${nickname} 的拉黑`);
                    } else {
                        throw new Error(res.msg || '撤销失败');
                    }
                } catch(e) {
                    showToast('撤销失败:' + e.message, 'error');
                }
            },
            onerror: function() {
                showToast('撤销请求失败,请手动操作', 'error');
            }
        });
    }

    // 更新按钮状态
    function updateButtonState(isBlocked) {
        const btn = document.getElementById('wblk-block-btn');
        if (!btn) return;

        if (isBlocked) {
            btn.innerHTML = `
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
                    <circle cx="12" cy="12" r="3"></circle>
                    <line x1="1" y1="1" x2="23" y2="23"></line>
                </svg>
                已拉黑
            `;
            btn.style.background = '#999';
            btn.style.boxShadow = 'none';
            btn.style.cursor = 'default';
            btn.title = '该用户已在黑名单中';
        } else {
            btn.innerHTML = `
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10"></circle>
                    <line x1="15" y1="9" x2="9" y2="15"></line>
                    <line x1="9" y1="9" x2="15" y2="15"></line>
                </svg>
                $${CONFIG.buttonText}
            `;
            btn.style.background = CONFIG.buttonColor;
            btn.style.boxShadow = '0 2px 8px rgba(255,77,79,0.3)';
            btn.style.cursor = 'pointer';
            btn.title = '点击立即拉黑该用户';
        }
    }

    // 创建一键拉黑按钮
    function createBlockButton() {
        // 检查是否已存在
        if (document.getElementById('wblk-block-btn')) return;

        const uid = getCurrentUID();
        if (!uid) {
            console.log('[微博一键拉黑] 未找到用户UID,跳过插入按钮');
            return;
        }

        currentUserInfo.uid = uid;
        currentUserInfo.nickname = getNickname();

        // 寻找插入位置 - 关注按钮旁边
        const insertTargets = [
            '._btn3_1yc79_119',           // 新版个人页关注/客服按钮区
            '.woo-button-main.woo-button-flat.woo-button-primary', // 关注按钮
            '[class*="_btn3_"]',          // 备用选择器
            '.woo-box-flex.woo-box-alignCenter._h3_1yc79_78', // 名字旁边的按钮区
        ];

        let targetContainer = null;
        for (let selector of insertTargets) {
            const el = document.querySelector(selector);
            if (el && el.parentElement) {
                targetContainer = el.parentElement;
                break;
            }
        }

        // 如果没找到特定容器,尝试在名字区域后面插入
        if (!targetContainer) {
            const nameArea = document.querySelector('._box1_1yc79_55, .woo-box-flex.woo-box-alignStart._box1_1yc79_55');
            if (nameArea) {
                targetContainer = nameArea;
            }
        }

        if (!targetContainer) {
            console.log('[微博一键拉黑] 未找到合适的插入位置');
            return;
        }

        // 创建按钮
        const btn = document.createElement('button');
        btn.id = 'wblk-block-btn';
        btn.innerHTML = `
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
                <circle cx="12" cy="12" r="10"></circle>
                <line x1="15" y1="9" x2="9" y2="15"></line>
                <line x1="9" y1="9" x2="15" y2="15"></line>
            </svg>
            $${CONFIG.buttonText}
        `;
        btn.style.cssText = `
            background: $${CONFIG.buttonColor};
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 20px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            transition: all 0.2s ease;
            box-shadow: 0 2px 8px rgba(255,77,79,0.3);
            margin-right: 8px;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            outline: none;
            line-height: 1;
        `;
        btn.title = '点击立即拉黑该用户';

        // 悬停效果
        btn.addEventListener('mouseenter', () => {
            if (!currentUserInfo.blocked) {
                btn.style.background = CONFIG.buttonHoverColor;
                btn.style.transform = 'translateY(-1px)';
                btn.style.boxShadow = '0 4px 12px rgba(255,77,79,0.4)';
            }
        });
        btn.addEventListener('mouseleave', () => {
            if (!currentUserInfo.blocked) {
                btn.style.background = CONFIG.buttonColor;
                btn.style.transform = 'translateY(0)';
                btn.style.boxShadow = '0 2px 8px rgba(255,77,79,0.3)';
            }
        });

        // 点击事件
        btn.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            if (currentUserInfo.blocked) {
                showToast('该用户已在黑名单中', 'warning');
                return;
            }
            blockUser(currentUserInfo.uid, currentUserInfo.nickname);
        });

        // 插入到目标容器
        if (targetContainer.classList && targetContainer.classList.contains('_box1_1yc79_55')) {
            // 如果是名字区域,插入到按钮区
            const btnArea = targetContainer.querySelector('.woo-box-flex') || targetContainer;
            const firstBtn = btnArea.querySelector('button, a');
            if (firstBtn && firstBtn.parentElement === btnArea) {
                btnArea.insertBefore(btn, firstBtn);
            } else {
                btnArea.appendChild(btn);
            }
        } else {
            targetContainer.insertBefore(btn, targetContainer.firstChild);
        }

        console.log(`[微博一键拉黑] 按钮已插入,目标用户: $${currentUserInfo.nickname}($${uid})`);
    }

    // 添加旋转动画样式
    function addStyles() {
        if (document.getElementById('wblk-styles')) return;

        const style = document.createElement('style');
        style.id = 'wblk-styles';
        style.textContent = `
            @keyframes wblk-spin {
                from { transform: rotate(0deg); }
                to { transform: rotate(360deg); }
            }
            #wblk-block-btn:active {
                transform: scale(0.95) !important;
            }
        `;
        document.head.appendChild(style);
    }

    // 初始化
    function init() {
        addStyles();
        createBlockButton();

        // 监听URL变化(单页应用路由切换)
        let lastUrl = location.href;
        const observer = new MutationObserver(() => {
            if (location.href !== lastUrl) {
                lastUrl = location.href;
                currentUserInfo.blocked = false;
                // 移除旧按钮,等待新页面加载完成后重新插入
                const oldBtn = document.getElementById('wblk-block-btn');
                if (oldBtn) oldBtn.remove();

                setTimeout(() => {
                    createBlockButton();
                }, 1500); // 等待页面渲染
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });

        // 也定期检查(备用方案)
        setInterval(() => {
            if (!document.getElementById('wblk-block-btn')) {
                createBlockButton();
            }
        }, 3000);
    }

    // 页面加载完成后初始化
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        setTimeout(init, 1000); // 等待微博JS初始化
    } else {
        document.addEventListener('DOMContentLoaded', () => setTimeout(init, 1000));
    }

    console.log('[微博一键拉黑] 脚本已加载');
})();
啊,第二个是搜索页面,多勾选框,一键勾选,批量拉黑。
// ==UserScript==
// @name         微博搜索批量拉黑(Kimi版)
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  在搜索结果页勾选用户,批量拉黑,无需手动获取token
// @match        https://s.weibo.com/user?*
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // ========== 配置 ==========
    const CONFIG = {
        buttonText: '批量拉黑选中',
        buttonColor: '#ff4d4f',
    };

    // ========== API 调用(完全复制 Kimi 的写法) ==========
    function blockUser(uid) {
        return new Promise((resolve, reject) => {
            const url = 'https://weibo.com/aj/filter/block?ajwvr=6';
            const data = `uid=$${uid}&filter_type=1&status=1&interact=1&follow=1&__rnd=$${Date.now()}`;

            GM_xmlhttpRequest({
                method: 'POST',
                url: url,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-Requested-With': 'XMLHttpRequest',
                    'Referer': location.href
                },
                data: data,
                onload: function(response) {
                    try {
                        const res = JSON.parse(response.responseText);
                        if (res.code === '100000' || res.code === 100000) {
                            resolve(true);
                        } else {
                            reject(new Error(res.msg || '操作失败,错误码:' + res.code));
                        }
                    } catch (e) {
                        reject(e);
                    }
                },
                onerror: function(err) {
                    reject(err);
                }
            });
        });
    }

    // ========== UI 组件 ==========

    // 创建工具栏
    function createToolbar() {
        const toolbar = document.createElement('div');
        toolbar.id = 'wblk-toolbar';
        toolbar.style.cssText = `
            padding: 10px 16px;
            background: #f7f7f7;
            border-bottom: 1px solid #e0e0e0;
            display: flex;
            align-items: center;
            gap: 20px;
            font-size: 14px;
            position: sticky;
            top: 0;
            z-index: 999;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        `;
        toolbar.innerHTML = `
            <label style="display:flex;align-items:center;gap:4px;cursor:pointer;">
                <input type="checkbox" id="wblk-select-all"> 全选
            </label>
            <button id="wblk-batch-block" style="
                background: $${CONFIG.buttonColor};
                color: white;
                border: none;
                padding: 6px 18px;
                border-radius: 16px;
                font-size: 14px;
                font-weight: 600;
                cursor: pointer;
                transition: background 0.2s;
            ">$${CONFIG.buttonText}</button>
            <span id="wblk-status" style="color: #666; font-size: 13px;"></span>
            <span id="wblk-progress" style="color: #1890ff; font-weight: bold;"></span>
        `;
        return toolbar;
    }

    // 添加复选框到每个卡片
    function addCheckboxes() {
        const cards = document.querySelectorAll('.card.card-user-b');
        cards.forEach(card => {
            if (card.querySelector('.wblk-checkbox')) return;

            // 获取 uid
            const followBtn = card.querySelector('button[uid]');
            let uid = followBtn ? followBtn.getAttribute('uid') : null;
            if (!uid) {
                const link = card.querySelector('.avator a');
                if (link) {
                    const match = link.href.match(/\/u\/(\d+)/);
                    if (match) uid = match[1];
                }
            }
            if (!uid) return;

            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.className = 'wblk-checkbox';
            checkbox.dataset.uid = uid;
            // 获取昵称
            const nameEl = card.querySelector('.info .name');
            checkbox.dataset.nickname = nameEl ? nameEl.textContent.trim() : uid;
            checkbox.style.cssText = `
                position: absolute;
                left: 6px;
                top: 6px;
                z-index: 10;
                width: 18px;
                height: 18px;
                cursor: pointer;
                transform: scale(1.1);
            `;
            card.style.position = 'relative';
            card.prepend(checkbox);
        });
    }

    // ========== 批量拉黑逻辑 ==========

    async function batchBlock() {
        const checkboxes = document.querySelectorAll('.wblk-checkbox:checked');
        const status = document.getElementById('wblk-status');
        const progress = document.getElementById('wblk-progress');
        const btn = document.getElementById('wblk-batch-block');

        if (!checkboxes.length) {
            status.textContent = '⚠️ 请至少选择一个用户';
            return;
        }

        const uids = Array.from(checkboxes).map(cb => cb.dataset.uid).filter(Boolean);
        if (!uids.length) {
            status.textContent = '❌ 未找到有效UID';
            return;
        }

        btn.disabled = true;
        status.textContent = `⏳ 正在拉黑 $${uids.length} 个用户...`;
        progress.textContent = '';

        let successCount = 0;
        let failCount = 0;

        for (let i = 0; i < uids.length; i++) {
            const uid = uids[i];
            const nickname = checkboxes[i]?.dataset?.nickname || uid;
            progress.textContent = `处理 $${i+1}/$${uids.length}`;
            try {
                await blockUser(uid);
                successCount++;
                // 自动取消已拉黑的复选框
                const cb = document.querySelector(`.wblk-checkbox[data-uid="$${uid}"]`);
                if (cb) cb.checked = false;
            } catch (e) {
                failCount++;
                console.error(`拉黑 $${uid} 失败:`, e);
            }
            // 避免请求过快
            await new Promise(r => setTimeout(r, 300));
        }

        status.textContent = `✅ 完成!成功 $${successCount},失败 $${failCount}`;
        progress.textContent = '';
        btn.disabled = false;

        if (successCount > 0) {
            // 桌面通知(如果 GM_notification 可用)
            if (typeof GM_notification !== 'undefined') {
                GM_notification({
                    title: '批量拉黑完成',
                    text: `成功拉黑 $${successCount} 个用户`,
                    timeout: 3000
                });
            }
        }
    }

    // ========== 初始化 ==========

    function init() {
        // 添加工具栏
        if (!document.getElementById('wblk-toolbar')) {
            const container = document.querySelector('.main-full');
            if (container) {
                const toolbar = createToolbar();
                container.prepend(toolbar);
            } else {
                console.warn('[批量拉黑] 未找到 .main-full');
                return;
            }
        }

        // 添加复选框
        addCheckboxes();

        // 事件绑定
        document.addEventListener('change', function(e) {
            if (e.target.id === 'wblk-select-all') {
                const checked = e.target.checked;
                document.querySelectorAll('.wblk-checkbox').forEach(cb => cb.checked = checked);
            }
        });

        document.addEventListener('click', function(e) {
            if (e.target.id === 'wblk-batch-block') {
                batchBlock();
            }
        });

        // 监听动态加载(翻页)
        const observer = new MutationObserver(() => addCheckboxes());
        const target = document.getElementById('pl_user_feedList') || document.body;
        observer.observe(target, { childList: true, subtree: true });

        console.log('[批量拉黑] 脚本已加载,可直接使用');
    }

    // 等待页面就绪
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        setTimeout(init, 800);
    } else {
        document.addEventListener('DOMContentLoaded', () => setTimeout(init, 800));
    }
})();

免费评分

参与人数 2吾爱币 +4 热心值 +2 收起 理由
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
SBKK123456 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
andy819 发表于 2026-7-7 15:17
厉害了~谢谢分享!
3#
sangern 发表于 2026-7-7 16:46
实用性强。微博现在确实恶心的,广告多,各种娱乐圈买热搜的多
4#
cao_jf 发表于 2026-7-7 17:13
5#
daymissed 发表于 2026-7-7 17:54
谢谢分享,觉得很实用。
6#
dujiu3611 发表于 2026-7-7 18:46
可以 啊,看起来就很厉害,还把它们三个都给使唤了一遍,好像是能力立显啊,很好奇是你是如何问它三个的  
7#
LucienLin722 发表于 2026-7-13 09:11
我再分享一个刷微博的时候,有加关注按钮就可以拉黑的代码
[JavaScript] 纯文本查看 复制代码
// ==UserScript==
// [url=home.php?mod=space&uid=170990]@name[/url]         微博信息流一键拉黑
// [url=home.php?mod=space&uid=467642]@namespace[/url]    http://tampermonkey.net/
// [url=home.php?mod=space&uid=1248337]@version[/url]      1.0
// @description  在微博信息流每条微博的关注按钮左侧添加一键拉黑按钮
// [url=home.php?mod=space&uid=195849]@match[/url]        https://weibo.com/*
// @match        https://*.weibo.com/*
// [url=home.php?mod=space&uid=609072]@grant[/url]        GM_xmlhttpRequest
// @grant        GM_notification
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // ========== 配置 ==========
    const CONFIG = {
        buttonText: '拉黑',
        buttonColor: '#ff4d4f',
        buttonHoverColor: '#ff7875',
    };

    // ========== 拉黑API ==========
    function blockUser(uid, nickname) {
        return new Promise((resolve, reject) => {
            if (!uid) {
                reject(new Error('未获取到用户ID'));
                return;
            }

            GM_xmlhttpRequest({
                method: 'POST',
                url: 'https://weibo.com/aj/filter/block?ajwvr=6',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-Requested-With': 'XMLHttpRequest',
                    'Referer': location.href
                },
                data: `uid=${uid}&filter_type=1&status=1&interact=1&follow=1&__rnd=${Date.now()}`,
                onload: function(response) {
                    try {
                        const res = JSON.parse(response.responseText);
                        if (res.code === '100000' || res.code === 100000) {
                            resolve(true);
                        } else {
                            reject(new Error(res.msg || '操作失败,错误码:' + res.code));
                        }
                    } catch (e) {
                        reject(e);
                    }
                },
                onerror: function(err) {
                    reject(err);
                }
            });
        });
    }

    // ========== Toast提示 ==========
    function showToast(text, type = 'success') {
        const toast = document.createElement('div');
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: ${type === 'success' ? 'rgba(0,0,0,0.85)' : 'rgba(255,77,79,0.95)'};
            color: white;
            padding: 12px 24px;
            border-radius: 24px;
            font-size: 14px;
            font-weight: 600;
            z-index: 999999;
            box-shadow: 0 4px 20px rgba(0,0,0,0.3);
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            pointer-events: none;
            transition: all 0.3s ease;
            opacity: 0;
            transform: translateX(-50%) translateY(-20px);
        `;
        toast.textContent = text;
        document.body.appendChild(toast);

        // 淡入
        setTimeout(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(-50%) translateY(0)';
        }, 10);

        // 淡出
        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(-50%) translateY(-20px)';
            setTimeout(() => toast.remove(), 300);
        }, 2500);
    }

    // ========== 从文章元素提取UID ==========
    function extractUid(articleElement) {
        // 方法1:从关注按钮的 user 属性获取
        const followBtn = articleElement.querySelector('button[user]');
        if (followBtn) {
            try {
                const userAttr = followBtn.getAttribute('user');
                const userObj = JSON.parse(userAttr);
                if (userObj.id) return String(userObj.id);
            } catch(e) {}
        }

        // 方法2:从关注按钮的 uid 属性获取
        const followBtn2 = articleElement.querySelector('button[uid]');
        if (followBtn2) {
            return followBtn2.getAttribute('uid');
        }

        // 方法3:从头像链接提取
        const avatarLink = articleElement.querySelector('a[href^="//weibo.com/u/"]');
        if (avatarLink) {
            const match = avatarLink.href.match(/\/u\/(\d+)/);
            if (match) return match[1];
        }

        // 方法4:从usercard属性提取
        const userCardEl = articleElement.querySelector('[usercard]');
        if (userCardEl) {
            const match = userCardEl.getAttribute('usercard').match(/\d+/);
            if (match) return match[0];
        }

        return null;
    }

    // ========== 从文章元素提取昵称 ==========
    function extractNickname(articleElement) {
        // 方法1:从标题name元素提取
        const nameEl = articleElement.querySelector('._name_ygi5b_120 span[title]');
        if (nameEl) return nameEl.textContent.trim();

        // 方法2:从链接文本提取
        const nameLink = articleElement.querySelector('a[usercard] ._cut_ygi5b_97');
        if (nameLink) return nameLink.textContent.trim();

        // 方法3:从普通name元素提取
        const nameEl2 = articleElement.querySelector('[class*="name"]');
        if (nameEl2) return nameEl2.textContent.trim();

        return '未知用户';
    }

    // ========== 为单个文章添加拉黑按钮 ==========
    function addBlockButton(articleElement) {
        // 检查是否已经添加过
        if (articleElement.querySelector('.wblk-block-btn-feed')) return;

        // 提取用户信息
        const uid = extractUid(articleElement);
        if (!uid) return;

        const nickname = extractNickname(articleElement);

        // 找到关注按钮容器(关注按钮的父级)
        const followBtn = articleElement.querySelector('.woo-button-main.woo-button-line.woo-button-primary.woo-button-s.woo-button-round');
        if (!followBtn) return;

        const container = followBtn.parentElement;
        if (!container) return;

        // 创建拉黑按钮
        const blockBtn = document.createElement('button');
        blockBtn.className = 'wblk-block-btn-feed';
        blockBtn.dataset.uid = uid;
        blockBtn.dataset.nickname = nickname;
        blockBtn.innerHTML = `
            <span style="display:flex;align-items:center;gap:3px;">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10"></circle>
                    <line x1="15" y1="9" x2="9" y2="15"></line>
                    <line x1="9" y1="9" x2="15" y2="15"></line>
                </svg>
                ${CONFIG.buttonText}
            </span>
        `;
        blockBtn.style.cssText = `
            background: ${CONFIG.buttonColor};
            color: white;
            border: none;
            padding: 4px 10px;
            border-radius: 16px;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
            display: inline-flex;
            align-items: center;
            gap: 4px;
            transition: all 0.2s ease;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            outline: none;
            line-height: 1.4;
            margin-right: 6px;
            flex-shrink: 0;
        `;

        // 悬停效果
        blockBtn.addEventListener('mouseenter', () => {
            blockBtn.style.background = CONFIG.buttonHoverColor;
            blockBtn.style.transform = 'scale(1.05)';
        });
        blockBtn.addEventListener('mouseleave', () => {
            blockBtn.style.background = CONFIG.buttonColor;
            blockBtn.style.transform = 'scale(1)';
        });

        // 点击拉黑
        blockBtn.addEventListener('click', async (e) => {
            e.preventDefault();
            e.stopPropagation();

            const uid = blockBtn.dataset.uid;
            const nickname = blockBtn.dataset.nickname;

            // 禁用按钮防止重复点击
            blockBtn.disabled = true;
            blockBtn.style.opacity = '0.6';
            blockBtn.style.cursor = 'default';
            blockBtn.innerHTML = `
                <span style="display:flex;align-items:center;gap:3px;">
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" style="animation: wblk-spin 0.8s linear infinite;">
                        <circle cx="12" cy="12" r="10" stroke-dasharray="60" stroke-dashoffset="20" stroke-linecap="round"/>
                    </svg>
                    处理中
                </span>
            `;

            try {
                await blockUser(uid, nickname);
                showToast(`&#9989; 已拉黑 @${nickname}`);
                
                // 成功后将按钮改为已拉黑状态
                blockBtn.innerHTML = `
                    <span style="display:flex;align-items:center;gap:3px;">
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
                            <path d="M20 6L9 17l-5-5"/>
                        </svg>
                        已拉黑
                    </span>
                `;
                blockBtn.style.background = '#999';
                blockBtn.style.cursor = 'default';
                blockBtn.disabled = true;

                // 桌面通知
                if (typeof GM_notification !== 'undefined') {
                    GM_notification({
                        title: '一键拉黑',
                        text: `已拉黑 @${nickname}`,
                        timeout: 3000
                    });
                }

            } catch (error) {
                console.error('[拉黑失败]', error);
                showToast(`&#10060; 拉黑失败:${error.message || '未知错误'}`, 'error');
                
                // 恢复按钮
                blockBtn.disabled = false;
                blockBtn.style.opacity = '1';
                blockBtn.style.background = CONFIG.buttonColor;
                blockBtn.innerHTML = `
                    <span style="display:flex;align-items:center;gap:3px;">
                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
                            <circle cx="12" cy="12" r="10"></circle>
                            <line x1="15" y1="9" x2="9" y2="15"></line>
                            <line x1="9" y1="9" x2="15" y2="15"></line>
                        </svg>
                        重试
                    </span>
                `;
            }
        });

        // 插入到关注按钮前面(在同一个父容器中)
        container.insertBefore(blockBtn, followBtn);

        // 检查如果关注按钮存在,在关注按钮前面插入
        // 如果存在更多按钮(X按钮),确保拉黑按钮在关注和X之间
        const moreBtn = container.querySelector('.woo-pop-wrap');
        if (moreBtn) {
            container.insertBefore(blockBtn, moreBtn);
        } else {
            container.insertBefore(blockBtn, followBtn);
        }
    }

    // ========== 处理所有文章 ==========
    function processArticles() {
        // 选择所有文章卡片(新版微博使用这个类)
        const articles = document.querySelectorAll('article.woo-panel-main._wrap_ecgcn_2');

        articles.forEach(article => {
            // 检查这个文章是否已经处理过
            if (article.dataset.wblkProcessed === 'true') return;
            article.dataset.wblkProcessed = 'true';

            addBlockButton(article);
        });
    }

    // ========== 添加旋转动画样式 ==========
    function addStyles() {
        if (document.getElementById('wblk-feed-styles')) return;

        const style = document.createElement('style');
        style.id = 'wblk-feed-styles';
        style.textContent = `
            @keyframes wblk-spin {
                from { transform: rotate(0deg); }
                to { transform: rotate(360deg); }
            }
            .wblk-block-btn-feed:active {
                transform: scale(0.95) !important;
            }
        `;
        document.head.appendChild(style);
    }

    // ========== 初始化 ==========
    function init() {
        addStyles();

        // 首次处理
        setTimeout(processArticles, 1500);

        // 监听新加载的内容(滚动加载)
        const observer = new MutationObserver((mutations) => {
            let shouldProcess = false;

            for (const mutation of mutations) {
                if (mutation.addedNodes.length > 0) {
                    shouldProcess = true;
                    break;
                }
            }

            if (shouldProcess) {
                // 延迟处理,等待DOM渲染完成
                clearTimeout(window.wblkProcessTimer);
                window.wblkProcessTimer = setTimeout(processArticles, 500);
            }
        });

        // 观察整个文档的变化
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

        // 每隔几秒检查一次(兜底)
        setInterval(processArticles, 5000);

        console.log('[微博信息流一键拉黑] 脚本已加载');
    }

    // 等待页面加载
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        init();
    } else {
        document.addEventListener('DOMContentLoaded', init);
    }

})();
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-19 06:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表