// ==UserScript== // @name 韭研公社涨停板跟踪 // @author binary4cat // @namespace http://tampermonkey.net/ // @version 1.0.3 // @description 在韭研公社action页面添加异动第二天涨幅跟踪功能 // @license Proprietary; All rights reserved. Redistribution or modification prohibited. // @copyright 2025 binary4cat. Unauthorized copying or distribution is strictly forbidden. // @match https://www.jiuyangongshe.com/action // @match https://www.jiuyangongshe.com/action/* // @connect push2ex.eastmoney.com // @grant GM_addStyle // @grant GM_xmlhttpRequest // @downloadURL https://update.greasyfork.icu/scripts/553748/%E9%9F%AD%E7%A0%94%E5%85%AC%E7%A4%BE%E6%B6%A8%E5%81%9C%E6%9D%BF%E8%B7%9F%E8%B8%AA.user.js // @updateURL https://update.greasyfork.icu/scripts/553748/%E9%9F%AD%E7%A0%94%E5%85%AC%E7%A4%BE%E6%B6%A8%E5%81%9C%E6%9D%BF%E8%B7%9F%E8%B8%AA.meta.js // ==/UserScript== (function () { 'use strict'; // 添加按钮样式 GM_addStyle(` #data-extract-button { position: fixed; top: 20px; right: 20px; z-index: 9999; padding: 10px 20px; background-color: #1890ff; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; font-weight: bold; box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3); } #data-extract-button:hover { background-color: #40a9ff; } `); /** * 从页面提取数据 * @returns {Object} 提取的数据数组 */ function extractDataFromPage () { // 查找class为"module-box jc0"的ul标签 const targetUl = document.querySelector('ul.module-box.jc0'); if (!targetUl) { console.error('未找到class为"module-box jc0"的ul元素'); return []; } // 获取所有li标签 const listItems = targetUl.querySelectorAll('li.module'); const dataArray = { data: [] }; listItems.forEach((item, index) => { const sectorData = {}; // 检查li下是否有class为"hsh-flex-upDown jc-bline"的div const targetDiv = item.querySelector('div.hsh-flex-upDown.jc-bline'); if (!targetDiv) { // 如果没有找到目标div,跳过当前循环 return; } // 获取item的直接子div(一级div) const allDivs = Array.from(item.children).filter(child => child.tagName === 'DIV'); if (allDivs.length < 2) { // 如果没有找到第二个div,跳过当前循环 return; } // 在第一个div下查找class为"fs18-bold lf"的div内容 const sectorNameDiv = allDivs[0].querySelector('div.fs18-bold.lf'); const sectorName = sectorNameDiv ? sectorNameDiv.textContent.trim() : ''; // 跳过ST板块 if (sectorName === 'ST板块') { return; } // 在第一个div下查找class为"number lf"的div内容 const sectorCountDiv = allDivs[0].querySelector('div.number.lf'); const sectorCount = sectorCountDiv ? sectorCountDiv.textContent.trim() : ''; // 必须有板块名称 if (!sectorName) { return; } sectorData.sectorName = sectorName; sectorData.sectorCount = sectorCount; sectorData.stockList = []; // 在第二个div下查找class为"td-box"的ul元素 const tdBoxUl = allDivs[1].querySelector('ul.td-box'); if (!tdBoxUl) { // 如果没有找到class为"td-box"的ul,跳过当前循环 return; } // 获取td-box下的所有li元素 const tdBoxItems = tdBoxUl.querySelectorAll('li'); tdBoxItems.forEach((tdItem, tdIndex) => { const stock = {}; // 首先找到class为hsh-flex-both alcenter的div const stockInfoDiv = tdItem.querySelector('div.hsh-flex-both.alcenter'); if (stockInfoDiv) { // 股票名称:class为shrink fs15-bold的div的内容 const stockNameDiv = stockInfoDiv.querySelector('div.shrink.fs15-bold'); stock.name = stockNameDiv ? stockNameDiv.textContent.trim() : 'N/A'; // 股票代码:class为shrink fs12-bold-ash force-wrap的div的内容 const stockCodeDiv = stockInfoDiv.querySelector('div.shrink.fs12-bold-ash.force-wrap'); stock.code = stockCodeDiv ? stockCodeDiv.textContent.trim() : 'N/A'; // 股票价格:class为shrink number的div的内容 const stockPriceDiv = stockInfoDiv.querySelector('div.shrink.number'); stock.price = stockPriceDiv ? stockPriceDiv.textContent.trim() : 'N/A'; // 股票涨停时间:class为shrink fs15的div的内容 const stockLimitTimeDiv = stockInfoDiv.querySelector('div.shrink.fs15'); stock.limitTime = stockLimitTimeDiv ? stockLimitTimeDiv.textContent.trim() : 'N/A'; // 股票连板数:class为sort的div的内容 const stockBoardDiv = stockInfoDiv.querySelector('div.sort'); stock.continuousBoards = stockBoardDiv ? stockBoardDiv.textContent.trim() : '首板'; // 如果涨停时间为“--”,则说明不是涨停 if (stock.limitTime === '--') { stock.continuousBoards = '异动'; } // 股票涨跌幅:class为shrink cred的div的内容 const stockChangeDiv = stockInfoDiv.querySelector('div.shrink.cred'); stock.changePercent = stockChangeDiv ? stockChangeDiv.textContent.trim() : 'N/A'; // 股票涨停原因:class为pre tl expound noneHile的pre标签下的a标签的内容 const reasonPreTag = stockInfoDiv.querySelector('pre'); stock.reason = reasonPreTag ? reasonPreTag.textContent.trim() : 'N/A'; // 添加到股票列表 sectorData.stockList.push(stock); } }); dataArray.data.push(sectorData); }); return dataArray; } /** * 创建并打开新标签页展示数据 * @param {Array} data 要展示的数据 */ function openDataViewer (data) { try { // 创建新窗口 const newTab = window.open('', '_blank'); if (newTab) { // 构建HTML内容,使用函数字符串传递数据 const pageHtml = dataHTML(data); // 写入页面内容 newTab.document.open(); newTab.document.write(pageHtml); newTab.document.close(); } } catch (e) { alert('打开数据查看器失败: ' + e.message); console.error('打开数据查看器错误:', e); } } function sleep (ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function addExtractButton () { for (let i = 0; i < 50; i++) { // 尝试查找标签元素 const activeTab = document.querySelector('ul.module-box.jc0'); // 如果找到标签,则继续添加按钮 if (activeTab) { console.log('检测到"全部异动解析"标签,准备添加提取按钮'); break; } else { console.log(`第${i + 1}次尝试:未检测到"全部异动解析"标签`); await sleep(2000); continue; } } // 查找目标容器 const targetContainer = document.querySelector('div.yd-top.hsh-flex-upDown.straight-line'); if (targetContainer) { // 获取容器下的所有div元素 const childDivs = targetContainer.querySelectorAll('div'); if (childDivs.length > 0) { // 获取最后一个div const lastDiv = childDivs[childDivs.length - 1]; // 创建按钮容器div(仿照指定格式) const buttonContainer = document.createElement('div'); buttonContainer.className = 'yd-tabs_item is-top'; buttonContainer.setAttribute('data-v-2cbcafa3', ''); // 创建内部文本div const innerTextDiv = document.createElement('div'); innerTextDiv.setAttribute('data-v-2cbcafa3', ''); innerTextDiv.textContent = '查看异动实时数据'; // 将内部文本div添加到按钮容器 buttonContainer.appendChild(innerTextDiv); // 添加点击事件 buttonContainer.addEventListener('click', () => { try { const extractedData = extractDataFromPage(); if (extractedData.data && extractedData.data.length > 0) { openDataViewer(extractedData.data); } else { alert('未提取到数据,请检查页面结构是否正确'); } } catch (error) { console.error('提取数据失败:', error); alert('提取数据时发生错误,请查看控制台'); } }); // 添加样式使其看起来像一个可点击的标签 buttonContainer.style.transition = 'background-color 0.3s'; buttonContainer.style.fontSize = 'xx-small' buttonContainer.style.color = 'red' buttonContainer.addEventListener('mouseenter', () => { buttonContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.05)'; }); buttonContainer.addEventListener('mouseleave', () => { buttonContainer.style.backgroundColor = ''; }); // 在最后一个div后面插入按钮容器 lastDiv.parentNode.insertBefore(buttonContainer, lastDiv.nextSibling); return; } } // 如果找不到目标容器,回退到原有的添加方式 const button = document.createElement('button'); button.id = 'data-extract-button'; button.textContent = '查看涨停板数据'; button.addEventListener('click', () => { try { const extractedData = extractDataFromPage(); if (extractedData.data && extractedData.data.length > 0) { openDataViewer(extractedData.data); } else { alert('未提取到数据,请检查页面结构是否正确'); } } catch (error) { console.error('提取数据失败:', error); alert('提取数据时发生错误,请查看控制台'); } }); document.body.appendChild(button); } function dataHTML (data) { return ` 韭研公社全部异动票跟踪

韭研公社涨停板数据

最后更新时间: 加载中...
板块名称 股票名称 股票代码 股票价格 涨跌幅 实时涨幅 连续板数 涨停时间 涨停原因
数据加载中...
` } // 等待页面加载完成后添加按钮 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', addExtractButton); } else { addExtractButton(); } })();