2025-11-21 油猴脚本完全指南:从入门到精通的浏览器自动化技巧

油猴脚本作为浏览器自动化的重要工具,能够极大提升网页使用体验和工作效率。本文将全面介绍油猴脚本的开发技巧,从基础语法到高级应用,帮助读者掌握浏览器自动化的核心技能。

## 油猴脚本基础入门

### 脚本元数据配置

每个油猴脚本都以特定的元数据块开始,定义脚本的基本信息和行为。

```javascript

// ==UserScript==

// @name        网页自动化助手

// @namespace    http://tampermonkey.net/

// @version      1.2.0

// @description  自动完成网页操作,提升浏览效率

// @author      开发者名称

// @match        https://*.example.com/*

// @match        https://www.sample-site.com/path/*

// @exclude      https://admin.example.com/*

// @grant        GM_setValue

// @grant        GM_getValue

// @grant        GM_notification

// @grant        GM_xmlhttpRequest

// @require      https://code.jquery.com/jquery-3.6.0.min.js

// @connect      api.example.com

// @run-at      document-end

// ==/UserScript==

```

### 基础脚本结构

理解油猴脚本的基本结构和执行流程。

```javascript

(function() {

    'use strict';


    // 配置常量

    const CONFIG = {

        autoRefresh: true,

        refreshInterval: 30000, // 30秒

        enableFeatures: ['autoFill', 'removeAds', 'enhanceUI']

    };


    // 主函数

    function init() {

        console.log('油猴脚本开始执行');


        // 等待页面加载完成

        if (document.readyState <"gold.kandy58.cn">=== 'loading') {

            document.addEventListener('DOMContentLoaded', main);

        } else {

            main();

        }

    }


    // 主要逻辑

    function main() {

        try {

            // 执行各个功能模块

            if (CONFIG.autoRefresh) {

                setupAutoRefresh();

            }


            if (CONFIG.enableFeatures.includes('autoFill')) {

                setupAutoFill();

            }


            if (CONFIG.enableFeatures.includes('removeAds')) {

                removeAdvertisements();

            }


            if (CONFIG.enableFeatures.includes('enhanceUI')) {

                enhanceUserInterface();

            }


            // 监听页面变化(单页应用)

            observePageChanges();


        } catch (error) {

            console.error('脚本执行错误:', error);

            showNotification('脚本执行出现错误', 'error');

        }

    }


    // 启动脚本

    init();

})();

```

## 实用功能开发

### 表单自动填充

自动化填写常见表单字段,节省重复输入时间。

```javascript

// 表单自动填充功能

function setupAutoFill() {

    const formData =<"EPL.kandy58.cn"> {

        username: 'my_username',

        email: 'user@example.com',

        phone: '13800138000',

        address: '示例地址'

    };


    // 自动填充函数

    function autoFillForm() {

        const forms = document.querySelectorAll('form');


        forms.forEach(form => {

            // 根据输入框的name、id或placeholder自动填充

            Object.keys(formData).forEach(key => {

                const selectors = [

                    `input[name="${key}"]`,

                    `input[id="${key}"]`,

                    `input[placeholder*="${key}"]`,

                    `textarea[name="${key}"]`

                ];


                selectors.forEach(selector => {

                    const element = form.querySelector(selector);

                    if (element && !element.value) {

                        element.value = formData[key];


                        // 触发输入事件,确保验证通过

                        element.dispatchEvent(new Event('input', { bubbles: true }));

                        element.dispatchEvent(new Event('change', { bubbles: true }));

                    }

                });

            });

        });

    }


    // 立即执行一次

    autoFillForm();


    // 监听动态加载的表单

    const observer = new MutationObserver(() => {

        autoFillForm();

    });


    observer.observe(document.body, {

        childList: true,

        subtree: true

    });

}

// 智能表单填充(根据上下文)

function smartFormFiller() {

    // 检测页面类型并智能填充

    const pageType = detectPageType();


    switch (pageType) {

        case 'login':

            autoFillLoginForm();

            break<"CFL.kandy58.cn">;

        case 'registration':

            autoFillRegistrationForm();

            break;

        case 'shipping':

            autoFillShippingForm();

            break;

        case 'payment':

            autoFillPaymentForm();

            break;

    }

}

function detectPageType() {

    const url = window.location.href;

    const title = document.title.toLowerCase();


    if (url.includes('login') || title.includes('登录')) return 'login';

    if (url.includes('register') || title.includes('注册')) return 'registration';

    if (url.includes('shipping') || title.includes('配送')) return 'shipping';

    if (url.includes('payment') || title.includes('支付')) return 'payment';


    return 'unknown';

}

function autoFillLoginForm() {

    const savedUsername = GM_getValue('username', '');

    const savedPassword = GM_getValue('password', '');


    if (savedUsername) {

        const usernameField = document.querySelector('input[type="text"], input[type="email"], input[name="username"]');

        if (usernameField) usernameField.value = savedUsername;

    }

}

function autoFillRegistrationForm() {

    // 注册表单的智能填充逻辑

    const userInfo = {

        nickname: '用户昵称',

        birthday: '1990-01-01',

        gender: 'male'

    };


    // 填充昵称

    const nicknameFields <"SerieA.kandy58.cn">= [

        'input[name="nickname"]',

        'input[name="display_name"]',

        'input[placeholder*="昵称"]'

    ];


    nicknameFields.forEach(selector => {

        const field = document.querySelector(selector);

        if (field) field.value = userInfo.nickname;

    });

}

```

### 广告屏蔽与内容清理

移除网页中的广告和干扰元素。

```javascript

// 广告屏蔽功能

function removeAdvertisements() {

    // 广告选择器列表

    const adSelectors = [

        '.ad-container',

        '.advertisement',

        '[class*="ad"]',

        '[id*="ad"]',

        'iframe[src*="ads"]',

        'ins.adsbygoogle',

        '.ad-banner',

        '.popup-ad',

        '.ad-sidebar',

        '.sponsored-content'

    ];


    // 移除广告元素

    function removeAds() {

        adSelectors.forEach(selector => {

            const elements = document.querySelectorAll(selector);

            elements.forEach(element => {

                // 检查元素是否可见

                const style = window.getComputedStyle(element);

                if (style.display !== 'none') {

                    element.remove();

                    console.log('移除广告元素:', selector);

                }

            });

        });

    }


    // 屏蔽广告请求

    function blockAdRequests() {

        const originalFetch = window.fetch;

        window.fetch = function(...args) {

            const url = args[0];

            if (typeof url === 'string' && isAdUrl(url)) {

                console.log('屏蔽广告请求:', url);

                return Promise.reject(new Error('广告请求被屏蔽'));

            }

            return originalFetch.apply(this, args);

        };


        // 重写XMLHttpRequest

        const originalOpen <"LFP.kandy58.cn">= XMLHttpRequest.prototype.open;

        XMLHttpRequest.prototype.open = function(method, url) {

            if (isAdUrl(url)) {

                console.log('屏蔽XHR广告请求:', url);

                this._isAdRequest = true;

                return;

            }

            originalOpen.apply(this, arguments);

        };

    }


    function isAdUrl(url) {

        const adKeywords = ['adsystem', 'doubleclick', 'googleads', 'adservice', 'adsafeprotected'];

        return adKeywords.some(keyword => url.includes(keyword));

    }


    // 执行广告移除

    removeAds();

    blockAdRequests();


    // 持续监控新出现的广告

    const adObserver = new MutationObserver(mutations => {

        mutations.forEach(mutation => {

            mutation.addedNodes.forEach(node => {

                if (node.nodeType === 1) { // Element node

                    adSelectors.forEach(selector => {

                        if (node.matches && node.matches(selector)) {

                            node.remove();

                        } else if (node.querySelector) {

                            const ads = node.querySelectorAll(selector);

                            ads.forEach(ad => ad.remove());

                        }

                    });

                }

            });

        });

    });


    adObserver.observe(document.body, {

        childList: true,

        subtree: true

    });

}

// 页面内容清理

function cleanPageContent<"LaLiga.kandy58.cn">() {

    // 移除干扰元素

    const elementsToRemove = [

        '.social-share',    // 社交分享按钮

        '.popup',          // 弹窗

        '.newsletter',    // 邮件订阅

        '.recommendation', // 推荐内容

        '.floating-bar'    // 浮动栏

    ];


    elementsToRemove.forEach(selector => {

        document.querySelectorAll(selector).forEach(element => {

            element.remove();

        });

    });


    // 清理样式

    const style = document.createElement('style');

    style.textContent = `

        /* 隐藏不需要的元素 */

        .social-buttons,

        .share-widget,

        .floating-ad {

            display: none !important;

        }


        /* 改善阅读体验 */

        .article-content {

            max-width: 800px !important;

            margin: 0 auto !important;

            line-height: 1.6 !important;

            font-size: 16px !important;

        }


        /* 移除背景广告 */

        body {

            background-image: none !important;

        }

    `;

    document.head.appendChild(style);

}

```

## 高级自动化技巧

### 页面内容监控与自动操作

监控页面变化并自动执行操作。

```javascript

// 页面监控与自动操作

function observePageChanges() {

    let lastUrl = location.href;


    // 监听URL变化(单页应用)

    new MutationObserver(() => {

        const url = location.href;

        if (url !== lastUrl) {

            lastUrl =<"Bundesliga.kandy58.cn"> url;

            onPageChange(url);

        }

    }).observe(document, { subtree: true, childList: true });


    // 监听元素出现

    function waitForElement(selector, timeout = 10000) {

        return new Promise((resolve, reject) => {

            if (document.querySelector(selector)) {

                return resolve(document.querySelector(selector));

            }


            const observer = new MutationObserver(() => {

                if (document.querySelector(selector)) {

                    observer.disconnect();

                    resolve(document.querySelector(selector));

                }

            });


            observer.observe(document.body, {

                childList: true,

                subtree: true

            });


            setTimeout(() => {

                observer.disconnect();

                reject(new Error(`等待元素超时: ${selector}`));

            }, timeout);

        });

    }


    // 自动点击"加载更多"

    function autoLoadMore() {

        const loadMoreSelectors = [

            '.load-more',

            '.show-more',

            '[class*="load"]',

            'button:contains("加载更多")'

        ];


        setInterval(() => {

            loadMoreSelectors.forEach(selector => {

                const button = document.querySelector(selector);

                if (button && isElementInViewport(button)) {

                    button.click();

                    console.log('自动点击加载更多按钮');

                }

            });

        }, 3000);

    }


    function isElementInViewport(el) {

        const rect = el.getBoundingClientRect();

        return (

            rect.top >= 0 &&

            rect.left >= 0 &&

            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&

            rect.right <= (window.innerWidth || document.documentElement.clientWidth)

        );

    }

}

// 自动分页

function autoPagination() {

    let currentPage = 1;


    function navigateToNextPage() {

        const nextPageSelectors = [

            '.next-page',

            '.pagination-next',

            'a[rel="next"]',

            'a:contains("下一页")'

        ];


        for (const selector of nextPageSelectors) {

            const nextButton = document.querySelector(selector);

            if (nextButton && !nextButton.disabled) {

                currentPage++;

                console.log(`自动翻页到第 ${currentPage} 页`);

                nextButton.click();

                return true;

            }

        }

        return false;

    }


    // 每30秒尝试翻页

    setInterval(()<"UEFA.kandy58.cn"> => {

        // 检查是否到达页面底部

        const isAtBottom = (window.innerHeight + window.scrollY) >= document.body.offsetHeight - 100;


        if (isAtBottom) {

            navigateToNextPage();

        }

    }, 30000);

}

```

### 数据抓取与导出

自动抓取网页数据并导出。

```javascript

// 数据抓取功能

function setupDataScraping() {

    // 配置抓取规则

    const scrapeRules = {

        'product-list': {

            container: '.product-list, .items-grid',

            items: '.product-item, .item',

            fields: {

                name: '.product-name, .title',

                price: '.price, .cost',

                image: '.product-image img',

                link: 'a'

            }

        },

        'article-list': {

            container: '.article-list, .posts',

            items: '.article, .post',

            fields: {

                title: 'h2, h3, .title',

                summary: '.summary, .excerpt',

                date: '.date, time',

                author: '.author, .byline'

            }

        }

    };


    // 抓取数据

    function scrapeData(ruleName) {

        const rule = scrapeRules[ruleName];

        if (!rule) return [];


        const container = document.querySelector(rule.container);

        if (!container) return [];


        const items = container.querySelectorAll(rule.items);

        const results = [];


        items.forEach(item => {

            const data = {};


            Object.keys(rule.fields).forEach(field => {

                const selector = rule.fields[field];

                const element = item.querySelector(selector);


                if (element) {

                    if (field === 'image') {

                        data[field] = element.src;

                    } else if (field === 'link') {

                        data[field] = element.href;

                    } else {

                        data[field] = <"blog.maicaixia.cn">element.textContent.trim();

                    }

                }

            });


            if (Object.keys(data).length > 0) {

                results.push(data);

            }

        });


        return results;

    }


    // 导出数据

    function exportData(data, format = 'json') {

        let content, mimeType, filename;


        switch (format) {

            case 'json':

                content = JSON.stringify(data, null, 2);

                mimeType = 'application/json';

                filename = 'data.json';

                break;

            case 'csv':

                content = convertToCSV(data);

                mimeType = 'text/csv';

                filename = 'data.csv';

                break;

            case 'excel':

                content = convertToExcel(data);

                mimeType = 'application/vnd.ms-excel';

                filename = 'data.xls';

                break;

        }


        const blob = new Blob([content], { type: mimeType });

        const url = URL.createObjectURL(blob);

        const link = document.createElement('a');

        link.href = url;

        link.download = filename;

        link.click();

        URL.revokeObjectURL(url);

    }


    function convertToCSV(data) {

        if (data.length === 0) return '';


        const headers = Object.keys(data[0]);

        const csvRows = [headers.join(',')];


        data.forEach(row => {

            const values = headers.map(header => {

                const value = row[header] || '';

                return `"${value.toString().replace(/"/g, '""')}"`;

            });

            csvRows.push(values.join(','));

        });


        return csvRows.join('\n');

    }


    // 添加快捷键

    document.addEventListener('keydown', (e) => {

        // Ctrl+Shift+S 抓取数据

        if (e.ctrlKey && e.shiftKey && e.key === 'S') {

            e.preventDefault();

            const data = scrapeData('product-list');

            exportData(data, 'json');

            showNotification(`成功导出 ${data.length} 条数据`, 'success');

        }

    });

}

```

## 用户界面增强

### 自定义控制面板

为脚本添加可视化控制界面。

```javascript

// 创建控制面板

function createControlPanel() {

    // 检查是否已存在面板

    if (document.getElementById('tm-control-panel')) {

        return;

    }


    const panel = document.createElement('div');

    panel.id = 'tm-control-panel';

    panel.innerHTML = `

        <div class=<"key.maicaixia.cn">"tm-panel-header">

            <h3>脚本控制面板</h3>

            <button class="tm-close-btn">×</button>

        </div>

        <div class="tm-panel-body">

            <div class="tm-control-group">

                <label>

                    <input type="checkbox" id="tm-auto-refresh"> 自动刷新

                </label>

                <label>

                    <input type="checkbox" id="tm-auto-fill" checked> 自动填充

                </label>

                <label>

                    <input type="checkbox" id="tm-remove-ads" checked> 移除广告

                </label>

            </div>

            <div class="tm-control-group">

                <button id="tm-export-data" class="tm-btn">导出数据</button>

                <button id="tm-clear-data" class="tm-btn">清除数据</button>

            </div>

            <div class="tm-control-group">

                <label>刷新间隔:</label>

                <select id="tm-refresh-interval">

                    <option value="30000">30秒</option>

                    <option value="60000">1分钟</option>

                    <option value="300000">5分钟</option>

                </select>

            </div>

        </div>

    `;


    // 添加样式

    const style = document.createElement('style');

    style.textContent = `

        #tm-control-panel {

            position: fixed;

            top: 20px;

            right: 20px;

            width: 300px;

            background: white;

            border: 1px solid #ccc;

            border-radius: 8px;

            box-shadow: 0 4px 12px rgba(0,0,0,0.1);

            z-index: 10000;

            font-family: Arial, sans-serif;

        }

        .tm-panel-header {

            background: #f5f5f5;

            padding: 10px;

            border-bottom: 1px solid #ddd;

            display: flex;

            justify-content: space-between;

            align-items: center;

        }

        .tm-panel-header h3 {

            margin: 0;

            font-size: 14px;

        }

        .tm-close-btn {

            background: none;

            border: none;

            font-size: 18px;

            cursor: pointer;

        }

        .tm-panel-body {

            padding: 15px;

        }

        .tm-control-group {

            margin-bottom: 15px;

        }

        .tm-control-group label {

            display: block;

            margin-bottom: 8px;

            cursor: pointer;

        }

        .tm-btn {

            background: #007cba;

            color: white;

            border: none;

            padding: 8px 12px;

            border-radius: 4px;

            cursor: pointer;

            margin-right: <"lmd.maicaixia.cn">10px;

        }

        .tm-btn:hover {

            background: #005a87;

        }

    `;

    document.head.appendChild(style);

    document.body.appendChild(panel);


    // 事件处理

    setupPanelEvents(panel);

}

function setupPanelEvents(panel) {

    // 关闭按钮

    panel.querySelector('.tm-close-btn').addEventListener('click', () => {

        panel.style.display = 'none';

    });


    // 复选框事件

    panel.querySelector('#tm-auto-refresh').addEventListener('change', (e) => {

        GM_setValue('autoRefresh', e.target.checked);

    });


    panel.querySelector('#tm-auto-fill').addEventListener('change', (e) => {

        GM_setValue('autoFill', e.target.checked);

    });


    // 按钮事件

    panel.querySelector('#tm-export-data').addEventListener('click', () => {

        // 导出数据逻辑

        showNotification('数据导出功能', 'info');

    });


    // 恢复设置

    restorePanelSettings(panel);

}

function restorePanelSettings(panel) {

    panel.querySelector('#tm-auto-refresh').checked = GM_getValue('autoRefresh', false);

    panel.querySelector('#tm-auto-fill').checked = GM_getValue('autoFill', true);

    panel.querySelector('#tm-remove-ads').checked = GM_getValue('removeAds', true);

}

```

## 实用工具函数

### 通用辅助函数

```javascript

// 工具函数集合

const TMUtils = {

    // 显示通知

    showNotification(message, type = 'info', duration = 3000) {

        GM_notification({

            text: message,

            title: '油猴脚本提示',

            image: type === 'success' ? 'https://example.com/success.png' :

                  type === 'error' ? 'https://example.com/error.png' :

                  'https://example.com/info.png',

            timeout: duration

        });

    },


    // 防抖函数

    debounce(func, wait) {

        let timeout;

        return function executedFunction(...args) {

            const later = () => {

                clearTimeout(timeout);

                func(...args);

            };

            clearTimeout(timeout);

            timeout = setTimeout(later, wait);

        };

    },


    // 节流函数

    throttle(func, limit) {

        let inThrottle;

        return function(...args) {

            if (!inThrottle) {

                func.apply(this, args);

                inThrottle = true;

                setTimeout(() => inThrottle = false, limit);

            }

        };

    },


    // 等待函数

    wait(ms) {

        return new Promise(resolve => setTimeout(resolve, ms));

    },


    // 安全查询选择器

    safeQuery(selector, context = document) {

        try {

            return context.querySelector(selector);

        } catch (error) {

            console.error('选择器错误:', selector, error);

            return null;

        }

    },


    // 生成随机ID

    generateId() {

        return Math.random().toString(36).substr(2, 9);

    }

};

// 键盘快捷键管理

class ShortcutManager {

    constructor() {

        this.shortcuts = new Map();

        this.setupGlobalListener();

    }


    register(keys, callback, description = '') {

        this.shortcuts.set(keys, { callback, description });

    }


    setupGlobalListener() {

        document.addEventListener('keydown', (e) => {

            const key = this.getKeyString(e);


            for (const [keys, { callback }] of this.shortcuts) {

                if (keys === key) {

                    e.preventDefault();

                    callback();

                    break;

                }

            }

        });

    }


    getKeyString(e) {

        const parts = [];

        if (e.ctrlKey) parts.push('ctrl');

        if (e.shiftKey) parts.push('shift');

        if (e.altKey) parts.push('alt');

        parts.push(e.key.toLowerCase());

        return parts.join('+');

    }

}

// 初始化快捷键管理器

const shortcutManager = new ShortcutManager();

// 注册常用快捷键

shortcutManager.register('ctrl+shift+p', () => {

    createControlPanel();

}, '打开控制面板');

shortcutManager.register('ctrl+shift+e', () => {

    const data = scrapeData('product-list');

    exportData(data, 'json');

}, '导出数据');

```

## 脚本部署与维护

### 开发与调试技巧

```javascript

// 调试工具

function setupDebugTools() {

    // 只在开发环境启用

    if (!GM_getValue('debugMode', false)) return;


    // 添加调试面板

    const debugPanel = document.createElement('div');

    debugPanel.style.cssText = `

        position: fixed;

        bottom: 10px;

        right: 10px;

        background: rgba(0,0,0,0.8);

        color: white;

        padding: 10px;

        border-radius: 5px;

        font-family: monospace;

        font-size: 12px;

        z-index: 9999;

    `;


    function updateDebugInfo() {

        debugPanel.innerHTML = `

            URL: ${location.href}<br>

            脚本状态: 运行中<br>

            内存使用: ${Math.round(performance.memory.usedJSHeapSize / 1024 / 1024)}MB<br>

            时间: ${new Date().toLocaleTimeString()}

        `;

    }


    setInterval(updateDebugInfo, 1000);

    document.body.appendChild(debugPanel);

}

// 错误监控

window.addEventListener('error', (e) => {

    console.error('油猴脚本错误:', e.error);

    GM_setValue('lastError', {

        message: e.error.message,

        stack: e.error.stack,

        timestamp: new Date().toISOString()

    });

});

// 性能监控

const scriptStartTime = Date.now();

window.addEventListener('beforeunload', () => {

    const duration = Date.now() - scriptStartTime;

    console.log(`脚本运行时长: ${duration}ms`);

});

```

## 结语

油猴脚本为浏览器自动化提供了强大的能力,从简单的表单填充到复杂的数据抓取,都能通过脚本实现。掌握油猴脚本开发不仅能够提升个人浏览体验,还能在工作和学习中创造巨大的效率提升。

随着对脚本开发的深入理解,读者可以进一步探索更复杂的应用场景,如API集成、数据处理、用户界面定制等,让浏览器真正成为个性化的生产力工具。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容