// ==UserScript== // @name Bing自动随机搜索工具 // @namespace https://github.com/fuchen // @version 1.0 // @description 在Bing上进行自动随机搜索,支持自定义关键词和全随机模式 // @author 浮沉㗊 // @match https://www.bing.com/* // @match https://cn.bing.com/* // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== (function() { 'use strict'; // 配置参数 const config = { searchInterval: 5000, // 默认间隔时间(ms) totalSearches: 10, // 默认总搜索次数 running: false, // 运行状态 currentCount: 0, // 当前搜索次数 currentWord: '', // 当前搜索词 lastSearchTime: 0, // 上次搜索时间 searchMode: 'random', // 搜索模式: random-随机模式, custom-自定义模式 customKeywords: [] // 自定义关键词数组 }; // 中文常用字库(用于全随机模式) const commonChineseChars = '的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严'; // 创建UI元素 function createUI() { // 如果UI已存在,先移除 const existingUI = document.getElementById('bing-auto-search-container'); if (existingUI) { existingUI.remove(); } // 主容器 const container = document.createElement('div'); container.id = 'bing-auto-search-container'; container.style.cssText = ` position: fixed; top: 10px; right: 10px; width: 350px; background: white; border: 2px solid #0078d7; border-radius: 10px; padding: 15px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); z-index: 10000; font-family: 'Segoe UI', Arial, sans-serif; max-height: 80vh; overflow-y: auto; `; // 标题 const title = document.createElement('h3'); title.textContent = 'Bing自动搜索工具'; title.style.cssText = ` margin: 0 0 15px 0; color: #0078d7; text-align: center; border-bottom: 2px solid #f0f0f0; padding-bottom: 10px; cursor: move; user-select: none; `; container.appendChild(title); // 状态指示器 const statusIndicator = document.createElement('div'); statusIndicator.id = 'status-indicator'; statusIndicator.style.cssText = ` display: flex; align-items: center; margin-bottom: 15px; padding: 10px; background: #f8f9fa; border-radius: 6px; `; const statusLight = document.createElement('div'); statusLight.id = 'status-light'; statusLight.style.cssText = ` width: 12px; height: 12px; border-radius: 50%; background: #d13438; margin-right: 10px; flex-shrink: 0; `; const statusText = document.createElement('span'); statusText.id = 'status-text'; statusText.textContent = '状态: 已停止'; statusText.style.fontWeight = 'bold'; statusIndicator.appendChild(statusLight); statusIndicator.appendChild(statusText); container.appendChild(statusIndicator); // 计数器显示 const counterDisplay = document.createElement('div'); counterDisplay.id = 'counter-display'; counterDisplay.style.cssText = ` margin-bottom: 15px; padding: 10px; background: #eef6ff; border-radius: 6px; `; const countText = document.createElement('div'); countText.id = 'count-text'; countText.textContent = '已完成: 0 / 0'; countText.style.marginBottom = '5px'; const currentWordText = document.createElement('div'); currentWordText.id = 'current-word-text'; currentWordText.textContent = '当前搜索词: 无'; currentWordText.style.marginBottom = '5px'; const modeText = document.createElement('div'); modeText.id = 'mode-text'; modeText.textContent = '模式: 随机模式'; modeText.style.marginBottom = '5px'; const nextSearchText = document.createElement('div'); nextSearchText.id = 'next-search-text'; nextSearchText.textContent = '下次搜索: --'; counterDisplay.appendChild(countText); counterDisplay.appendChild(currentWordText); counterDisplay.appendChild(modeText); counterDisplay.appendChild(nextSearchText); container.appendChild(counterDisplay); // 配置面板 const configPanel = document.createElement('div'); configPanel.style.marginBottom = '15px'; // 搜索次数输入 const countLabel = document.createElement('label'); countLabel.textContent = '搜索次数:'; countLabel.style.display = 'block'; countLabel.style.marginBottom = '5px'; countLabel.style.fontWeight = 'bold'; const countInput = document.createElement('input'); countInput.id = 'search-count-input'; countInput.type = 'number'; countInput.min = '1'; countInput.max = '100'; countInput.value = config.totalSearches; countInput.style.cssText = ` width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; margin-bottom: 10px; `; // 间隔时间输入 const intervalLabel = document.createElement('label'); intervalLabel.textContent = '间隔时间(ms):'; intervalLabel.style.display = 'block'; intervalLabel.style.marginBottom = '5px'; intervalLabel.style.fontWeight = 'bold'; const intervalInput = document.createElement('input'); intervalInput.id = 'interval-input'; intervalInput.type = 'number'; intervalInput.min = '3000'; intervalInput.max = '30000'; intervalInput.value = config.searchInterval; intervalInput.style.cssText = ` width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; margin-bottom: 15px; `; // 关键词输入框 const keywordsLabel = document.createElement('label'); keywordsLabel.textContent = '自定义关键词(用逗号分隔,1-10个字符):'; keywordsLabel.style.display = 'block'; keywordsLabel.style.marginBottom = '5px'; keywordsLabel.style.fontWeight = 'bold'; const keywordsInput = document.createElement('textarea'); keywordsInput.id = 'keywords-input'; keywordsInput.placeholder = '例如: 科技,人工智能,机器学习'; keywordsInput.style.cssText = ` width: 100%; height: 60px; padding: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; margin-bottom: 10px; resize: vertical; font-family: inherit; `; // 模式选择 const modeLabel = document.createElement('label'); modeLabel.textContent = '搜索模式:'; modeLabel.style.display = 'block'; modeLabel.style.marginBottom = '5px'; modeLabel.style.fontWeight = 'bold'; const modeSelect = document.createElement('select'); modeSelect.id = 'mode-select'; modeSelect.style.cssText = ` width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; margin-bottom: 15px; background: white; `; const optionRandom = document.createElement('option'); optionRandom.value = 'random'; optionRandom.textContent = '随机模式(2-10字中文随机组合)'; const optionCustom = document.createElement('option'); optionCustom.value = 'custom'; optionCustom.textContent = '自定义关键词模式'; modeSelect.appendChild(optionRandom); modeSelect.appendChild(optionCustom); configPanel.appendChild(countLabel); configPanel.appendChild(countInput); configPanel.appendChild(intervalLabel); configPanel.appendChild(intervalInput); configPanel.appendChild(keywordsLabel); configPanel.appendChild(keywordsInput); configPanel.appendChild(modeLabel); configPanel.appendChild(modeSelect); container.appendChild(configPanel); // 按钮容器 const buttonContainer = document.createElement('div'); buttonContainer.style.cssText = ` display: flex; gap: 10px; margin-bottom: 15px; `; // 开始按钮 const startButton = document.createElement('button'); startButton.id = 'start-button'; startButton.textContent = '开始搜索'; startButton.style.cssText = ` flex: 1; padding: 12px; background: #0078d7; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; `; // 停止按钮 const stopButton = document.createElement('button'); stopButton.id = 'stop-button'; stopButton.textContent = '停止搜索'; stopButton.disabled = true; stopButton.style.cssText = ` flex: 1; padding: 12px; background: #d13438; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; opacity: 0.6; `; buttonContainer.appendChild(startButton); buttonContainer.appendChild(stopButton); container.appendChild(buttonContainer); // 添加到页面 document.body.appendChild(container); // 事件监听 startButton.addEventListener('click', startSearch); stopButton.addEventListener('click', stopSearch); modeSelect.addEventListener('change', updateMode); // 使UI可拖动 makeDraggable(container, title); // 更新模式显示 updateMode(); } // 更新模式显示 function updateMode() { const modeSelect = document.getElementById('mode-select'); const keywordsInput = document.getElementById('keywords-input'); if (modeSelect.value === 'custom') { keywordsInput.disabled = false; keywordsInput.style.opacity = '1'; } else { keywordsInput.disabled = true; keywordsInput.style.opacity = '0.7'; } } // 使元素可拖动 function makeDraggable(element, handle) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; handle.onmousedown = dragMouseDown; if ('ontouchstart' in window) { handle.ontouchstart = dragTouchStart; } function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function dragTouchStart(e) { const touch = e.touches[0]; pos3 = touch.clientX; pos4 = touch.clientY; document.ontouchend = closeDragElement; document.ontouchmove = elementDragTouch; e.preventDefault(); } function elementDrag(e) { e = e || window.event; e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px"; } function elementDragTouch(e) { const touch = e.touches[0]; pos1 = pos3 - touch.clientX; pos2 = pos4 - touch.clientY; pos3 = touch.clientX; pos4 = touch.clientY; element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px"; e.preventDefault(); } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; document.ontouchend = null; document.ontouchmove = null; } } // 获取随机搜索词 function getRandomWord() { const modeSelect = document.getElementById('mode-select'); if (modeSelect.value === 'custom') { // 自定义关键词模式 if (config.customKeywords.length === 0) { return "请设置关键词"; } return config.customKeywords[Math.floor(Math.random() * config.customKeywords.length)]; } else { // 随机模式:生成2-10个字的随机中文词 const wordLength = Math.floor(Math.random() * 9) + 2; let word = ''; for (let i = 0; i < wordLength; i++) { word += commonChineseChars[Math.floor(Math.random() * commonChineseChars.length)]; } return word; } } // 更新UI状态 function updateUI() { const statusLight = document.getElementById('status-light'); const statusText = document.getElementById('status-text'); const countText = document.getElementById('count-text'); const currentWordText = document.getElementById('current-word-text'); const modeText = document.getElementById('mode-text'); const nextSearchText = document.getElementById('next-search-text'); const startButton = document.getElementById('start-button'); const stopButton = document.getElementById('stop-button'); const modeSelect = document.getElementById('mode-select'); if (config.running) { statusLight.style.background = '#107c10'; statusText.textContent = '状态: 运行中'; startButton.disabled = true; startButton.style.opacity = '0.6'; stopButton.disabled = false; stopButton.style.opacity = '1'; // 计算下次搜索时间 if (config.lastSearchTime > 0) { const nextSearchTime = config.lastSearchTime + config.searchInterval; const now = Date.now(); const timeLeft = nextSearchTime - now; if (timeLeft > 0) { nextSearchText.textContent = `下次搜索: ${Math.ceil(timeLeft/1000)}秒后`; } else { nextSearchText.textContent = '下次搜索: 即将开始'; } } } else { statusLight.style.background = '#d13438'; statusText.textContent = '状态: 已停止'; startButton.disabled = false; startButton.style.opacity = '1'; stopButton.disabled = true; stopButton.style.opacity = '0.6'; nextSearchText.textContent = '下次搜索: --'; } // 更新模式显示 modeText.textContent = `模式: ${modeSelect.value === 'custom' ? '自定义关键词' : '随机模式'}`; countText.textContent = `已完成: ${config.currentCount} / ${config.totalSearches}`; currentWordText.textContent = `当前搜索词: ${config.currentWord || '无'}`; } // 执行搜索 function performSearch() { if (config.currentCount >= config.totalSearches) { stopSearch(); showNotification('完成', `已完成所有 ${config.totalSearches} 次搜索`); return; } config.currentCount++; config.currentWord = getRandomWord(); config.lastSearchTime = Date.now(); updateUI(); // 在Bing搜索框中输入关键词 const searchBox = document.getElementById('sb_form_q'); if (searchBox) { searchBox.value = config.currentWord; // 提交搜索表单 const searchForm = document.getElementById('sb_form'); if (searchForm) { searchForm.submit(); } else { // 如果找不到表单,模拟点击搜索按钮 const searchButton = document.getElementById('search_icon'); if (searchButton) { searchButton.click(); } else { // 最后的备选方案 const enterEvent = new KeyboardEvent('keydown', { key: 'Enter', keyCode: 13, which: 13, bubbles: true }); searchBox.dispatchEvent(enterEvent); } } } else { console.error('找不到Bing搜索框'); stopSearch(); } } // 开始搜索 function startSearch() { if (config.running) return; const countInput = document.getElementById('search-count-input'); const intervalInput = document.getElementById('interval-input'); const keywordsInput = document.getElementById('keywords-input'); const modeSelect = document.getElementById('mode-select'); config.totalSearches = parseInt(countInput.value) || 10; config.searchInterval = parseInt(intervalInput.value) || 5000; config.currentCount = 0; config.running = true; config.searchMode = modeSelect.value; // 处理自定义关键词 if (config.searchMode === 'custom') { const keywordsText = keywordsInput.value.trim(); if (keywordsText) { config.customKeywords = keywordsText.split(',').map(k => k.trim()).filter(k => { if (k.length < 1 || k.length > 10) { showNotification('错误', `关键词"${k}"长度不符合要求(1-10个字符)`); return false; } return true; }); if (config.customKeywords.length === 0) { showNotification('错误', '没有有效的关键词'); config.running = false; updateUI(); return; } } else { showNotification('错误', '请输入自定义关键词'); config.running = false; updateUI(); return; } } updateUI(); // 保存设置 GM_setValue('totalSearches', config.totalSearches); GM_setValue('searchInterval', config.searchInterval); GM_setValue('searchMode', config.searchMode); GM_setValue('customKeywords', config.customKeywords.join(',')); // 使用setTimeout而不是setInterval,确保页面完全加载后再执行下一次搜索 performSearch(); } // 停止搜索 function stopSearch() { if (!config.running) return; config.running = false; updateUI(); // 清除任何计划中的搜索 if (config.timeoutId) { clearTimeout(config.timeoutId); } } // 检查是否需要执行下一次搜索 function checkForNextSearch() { if (!config.running) return; const now = Date.now(); const timeSinceLastSearch = now - config.lastSearchTime; if (timeSinceLastSearch >= config.searchInterval) { // 时间到了,执行下一次搜索 performSearch(); } else { // 计划下一次检查 const timeUntilNextSearch = config.searchInterval - timeSinceLastSearch; config.timeoutId = setTimeout(checkForNextSearch, Math.min(1000, timeUntilNextSearch)); } updateUI(); } // 显示通知 function showNotification(title, message) { // 简单的alert通知 alert(`${title}: ${message}`); } // 初始化 function init() { // 加载保存的设置 const savedSearches = GM_getValue('totalSearches'); const savedInterval = GM_getValue('searchInterval'); const savedMode = GM_getValue('searchMode'); const savedKeywords = GM_getValue('customKeywords'); if (savedSearches) config.totalSearches = savedSearches; if (savedInterval) config.searchInterval = savedInterval; if (savedMode) config.searchMode = savedMode; if (savedKeywords) config.customKeywords = savedKeywords.split(','); // 创建UI createUI(); updateUI(); // 设置页面加载检查 let pageLoaded = false; // 检查页面是否已完全加载 if (document.readyState === 'complete') { pageLoaded = true; } else { window.addEventListener('load', function() { pageLoaded = true; }); } // 定期检查是否需要执行下一次搜索 setInterval(function() { if (config.running && pageLoaded) { checkForNextSearch(); } }, 1000); console.log('Bing自动搜索工具已加载'); } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();