您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
比较现在和上次记录的价格
// ==UserScript== // @name 天巡历史价格记录 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 比较现在和上次记录的价格 // @author 你的名字 // @match https://www.tianxun.com/transport/flights/* // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== (function() { 'use strict'; // 等待页面加载完成 function waitForElement(selector, callback) { console.log('等待页面中出现' + selector + '元素'); const el = document.querySelector(selector); if (el) { callback(el); } else { setTimeout(() => waitForElement(selector, callback), 500); } } // 等待页面中出现"条结果"文本 function waitForText(text, callback) { console.log('等待页面中出现"条结果"文本'); const el = Array.from(document.querySelectorAll('body *')).find(e => e.textContent.includes(text)); if (el) { callback(el); } else { setTimeout(() => waitForText(text, callback), 1000); } } waitForText('条结果', () => { waitForElement('[class^="FlightsResults_dayViewItems__"]', (container) => { // 获取当前搜索结果的日期 const dateInput = document.getElementById('outbound_date'); const searchDate = dateInput ? dateInput.value : ''; // 添加一个key,从<div class="SearchDetails_location__NDZmN">下的文本获取 const searchLocation = document.querySelector('.SearchDetails_location__NDZmN')?.textContent.trim(); // 获取所有子div const divs = Array.from(container.children); if (divs.length <= 1) return; // 排除第一个div .slice(1) 有时候不能排除第一个 divs.forEach(div => { debugger // 获取航司名 const airlineSpan = div.querySelector('[class^="LogoImage_label__"]'); // 如果选择不到就得到null const airline = airlineSpan ? airlineSpan.textContent.trim() : ''; // 获取出发和到达时间 const departDiv = div.querySelector('[class^="LegInfo_routePartialDepart__"]'); const departTime = departDiv ? departDiv.textContent.trim() : ''; // 获取到达时间 const arriveDiv = div.querySelector('[class^="LegInfo_routePartialArrive__"]'); const arriveTime = arriveDiv ? arriveDiv.textContent.trim() : ''; // 获取价格 const priceDiv = div.querySelector('[class^="Price_mainPriceContainer__"]'); const price = priceDiv ? priceDiv.textContent.trim() : ''; if (airline && departTime && price && searchDate) { const key = `${airline}_${departTime}__${arriveTime}_${searchLocation}_${searchDate}`; // 这里添加代码 let record = GM_getValue(key, null); let lastPrice = null; let minPrices = []; if (record) { try { record = JSON.parse(record); lastPrice = record.lastPrice; minPrices = Array.isArray(record.minPrices) ? record.minPrices : (record.minPrice ? [record.minPrice] : []); } catch (e) { lastPrice = record; minPrices = [record]; } } const infoSpan = document.createElement('span'); infoSpan.style.marginLeft = '10px'; infoSpan.style.color = '#f60'; if (lastPrice !== null) { if (lastPrice === price) { infoSpan.textContent = '没有变化'; } else { infoSpan.textContent = `上次价格:${lastPrice}`; } if (minPrices.length > 0) { infoSpan.textContent += ` / 历史价格:${minPrices.join('、')}`; } div.appendChild(infoSpan); // 更新lastPrice和minPrices // 只保留最多7个最低价,升序 修改,不只保留最低价了,只有最低价不好看这个价格变化的趋势 debugger let allPrices = minPrices.concat([price]); // allPrices = Array.from(new Set(allPrices.map(p => p.replace(/[^\d.]/g, '')))); // 去重,仅保留数字部分 // allPrices = allPrices.map(Number).filter(n => !isNaN(n)).sort((a, b) => a - b).slice(0, 7); // 还原为带货币符号的字符串(用当前price的格式) // const formatPrice = n => price.replace(/([\d.]+)/, n); // 去重,仅保留数字部分 allPrices = Array.from(new Set(allPrices.map(p => p.replace(/[^\d.]/g, '')))); allPrices = allPrices.map(Number).filter(n => !isNaN(n)); // 还原为字符串 const formatPrice = n => n.toString(); const minPricesStr = allPrices.slice(-15).map(formatPrice); GM_setValue(key, JSON.stringify({ lastPrice: price, minPrices: minPricesStr })); } else { // 首次保存 GM_setValue(key, JSON.stringify({ lastPrice: price, minPrices: [price] })); console.log(`已保存: ${key} => ${price}`); } } }); }); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址