// ==UserScript== // @name 数据发送工具 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 向本地后端发送当前页面的URL和Cookies // @author You // @match *://*/* // @grant GM_xmlhttpRequest // @connect 127.0.0.1 // @connect localhost // ==/UserScript== (function() { 'use strict'; // 配置:您可以修改这些变量来自定义行为 const TARGET_SELECTOR = 'body'; // 按钮插入位置的选择器 const BACKEND_IP = '127.0.0.1'; // 后端IP地址 const BACKEND_PORT = '5100'; // 后端端口号 // 构建后端基础URL const BACKEND_BASE_URL = `http://${BACKEND_IP}:${BACKEND_PORT}`; function addButton() { if (document.getElementById('data-sender-button')) { return; } const button = document.createElement('button'); button.id = 'data-sender-button'; button.textContent = "send data"; button.style.position = "fixed"; button.style.top = "12.5%"; button.style.right = "1%"; button.style.transform = "translateY(-50%)"; button.style.padding = "3px 8px"; button.style.fontSize = "10px"; button.style.backgroundColor = "#007baf"; button.style.color = "#fff"; button.style.border = "none"; button.style.borderRadius = "5px"; button.style.cursor = "pointer"; button.style.zIndex = "10000"; button.addEventListener('click', function() { sendDataToBackend(); }); const targetElement = document.querySelector(TARGET_SELECTOR); if (targetElement && TARGET_SELECTOR !== 'body') { const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'inline-block'; buttonContainer.style.marginLeft = '10px'; button.style.position = 'relative'; button.style.top = 'auto'; button.style.right = 'auto'; button.style.transform = 'none'; button.style.margin = '0'; buttonContainer.appendChild(button); if (targetElement.nextSibling) { targetElement.parentNode.insertBefore(buttonContainer, targetElement.nextSibling); } else { targetElement.parentNode.appendChild(buttonContainer); } } else { document.body.appendChild(button); } } function sendDataToBackend() { const currentUrl = window.location.href; const cookies = document.cookie; const data = { url: currentUrl, cookies: cookies, timestamp: new Date().toISOString() }; // 禁用按钮防止重复点击 const button = document.getElementById('data-sender-button'); if (button) { button.disabled = true; button.textContent = "任务进行中..."; button.style.backgroundColor = "#6c757d"; } // 发送任务请求 GM_xmlhttpRequest({ method: "POST", url: `${BACKEND_BASE_URL}/start-crawl`, headers: { "Content-Type": "application/json" }, data: JSON.stringify(data), onload: function(response) { if (response.status === 200) { const result = JSON.parse(response.responseText); if (result.task_id) { alert("爬虫任务已启动!任务ID: " + result.task_id); // 开始轮询任务状态 pollTaskStatus(result.task_id); } else { alert("任务启动失败: " + (result.message || "未知错误")); resetButton(); } } else { alert("请求失败,状态码: " + response.status); resetButton(); } }, onerror: function(error) { console.error("数据发送失败:", error); alert("数据发送失败,请检查后端服务是否运行"); resetButton(); } }); } function pollTaskStatus(taskId) { let pollCount = 0; const maxPolls = 300; // 最多轮询300次(5分钟,每秒一次) const pollInterval = setInterval(() => { pollCount++; GM_xmlhttpRequest({ method: "GET", url: `${BACKEND_BASE_URL}/task-status/${taskId}`, onload: function(response) { if (response.status === 200) { const result = JSON.parse(response.responseText); // 更新按钮状态显示进度 const button = document.getElementById('data-sender-button'); if (button) { button.textContent = `任务中...${pollCount}s`; } if (result.status === 'completed') { clearInterval(pollInterval); alert("爬虫任务完成!\n结果: " + JSON.stringify(result.result, null, 2)); resetButton(); } else if (result.status === 'failed') { clearInterval(pollInterval); alert("爬虫任务失败: " + result.error); resetButton(); } // 如果状态是 'running',继续轮询 } else { console.error("获取任务状态失败:", response.status); } }, onerror: function(error) { console.error("轮询任务状态失败:", error); } }); // 超过最大轮询次数,停止轮询 if (pollCount >= maxPolls) { clearInterval(pollInterval); alert("任务超时,请稍后手动检查结果"); resetButton(); } }, 1000); // 每秒轮询一次 } function resetButton() { const button = document.getElementById('data-sender-button'); if (button) { button.disabled = false; button.textContent = "send data"; button.style.backgroundColor = "#007baf"; } } // 初始尝试添加按钮 addButton(); // 使用MutationObserver监听DOM变化 const observer = new MutationObserver(function(mutations) { addButton(); }); observer.observe(document.body, { childList: true, subtree: true }); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', addButton); } else { addButton(); } })();