同一份行程,Trip.com 的不同語言站常常開出不同報價。這裡把你的行程一鍵展開成 24 個語言站的深連結——統一台幣計價,逐站回填參考價,立刻看出哪個語言最省。
Trip.com 的每個語言站其實是不同市場的銷售站點:各站的促銷活動、定價策略、庫存艙等釋出可能都不同,於是同一趟行程在台灣站、日本站、泰國站看到的價格經常有落差——有時差幾十元,有時差上千元。
24 個語言站的行程帶入與台幣顯示皆已於 2026-07/08 逐站實測(阿拉伯文因 Trip.com 無獨立網域未列入);Trip.com 介面與參數可能改版,若開啟後行程沒帶入請回報。價格為你回填當下的參考價,隨時變動,實際以訂票網結帳頁為準。
同時比好幾趟行程?把每一趟存成一個比價案——行程、乘客艙等、24 站回填價格全部一起記住,下次回來點一下就接著比。免登入,資料存在這台裝置的瀏覽器,不會上傳。
目前正在編輯的比價案會自動存檔(改行程、回填價格都會即時記住)。清除瀏覽器資料會一併清掉——要留底或換電腦,按「📤 匯出存檔」把所有比價案(含 24 站回填價)存成一個 .json 檔,到另一台裝置按「📥 匯入存檔」讀回來(匯入是新增合併,不會蓋掉現有比價案)。只想傳行程給別人比,用「🔗 複製分享連結」(不含價格)。
經濟/商務艙代碼已於 2026-07 逐站實測會帶入,Trip.com 若改版可能失效,請以開啟後頁面實際顯示為準;頭等與「只看直飛」同樣以頁面實際顯示為準。嬰兒票請在 Trip.com 頁面上自行調整;兒童票價多依年齡而異,連結只帶「兒童人數」,開啟後請在該站頁面確認兒童年齡設定再看價。
每列一個語言站(依 Trip.com 語言選單順序,共 24 站);單程、來回、多段行程都可以比。點 🔍 開啟該站的同行程搜尋(新分頁重複使用),把看到的總價回填,最省的列會亮起來。小技巧:Ctrl/Cmd+點 🔍 可各開一個分頁,多站並排對照。
💡 所有連結一律帶 curr=TWD:24 個語言站都直接以台幣顯示(2026-07/08 逐站實測有效;Trip.com 若改版,以開啟後頁面實際顯示為準),回填後直接比大小,不用換匯。
目前為逐一開啟模式(未勾選已裝腳本):按「🔗 逐一開啟下一站」會依序開一個語言站,看到總價後填回該列即可;手機/平板請用這個方式,或改用外站多段區間掃描的雲端查價。想全自動請在電腦安裝腳本後勾選上方選項。
⚠️ 回填的是參考價:同一分鐘不同裝置/瀏覽器/登入狀態看到的價格都可能不同,顯示價與最終結帳價也可能有落差(稅費計算方式未必相同),下單前一律以該站結帳頁為準。多位乘客時,請確認每一站顯示的都是全部乘客合計價再回填——部分站可能預設顯示單人價,基準不同就比不出結果。
登入後,把行程「送去工作站」——家裡/公司常開的電腦開著工作站模式、裝好自動輪查腳本,就會自動領單、一次多開跑完 24 個語言站,價格同步回來,手機直接看結果、一鍵套用進比價矩陣。沒登入完全照舊,純本機可用。
任務與結果只存在你的私人雲端(僅本人讀寫,與區間掃描同一組帳號)。價格是工作站電腦上 Trip.com 頁面顯示的參考價,下單前一律以結帳頁為準。Trip.com 若跳出人機驗證,工作站會暫停並通知你(這裡會出現紅色提示)——要用遠端桌面到工作站自己完成驗證再按「繼續」;本工具不會、也不該繞過驗證。
每次回填價格都會自動留下時間戳。不同日期/時段查同一趟行程,這裡可以看出每一輪的最省價怎麼變,以及各站相對上一次是漲是跌。
紀錄以「行程設定指紋」分開存放:改了日期/艙等/人數會另計一組,不會把不同行程的價格混在一起比。資料只存在這台裝置(localStorage),最多保留 2000 筆,超過會自動刪最舊的。
不想手動打 11 次價格?用書籤讓價格自己飛回來:書籤會讀取你當下開著的 Trip.com 頁面上顯示的最低票價,自動辨識是哪個語言站並回填矩陣——不呼叫任何查價 API,讀的就是你眼睛看到的數字。
書籤讀取的是頁面上顯示的參考價(通常是該行程的最低票價,未含後續加購),與你手動回填一樣以結帳頁為準;Trip.com 版面改版時書籤可能抓不到,屆時仍可手動回填。書籤本體不含任何外部程式碼,只在你主動點擊時執行。
想連書籤都不按?安裝下方使用者腳本(需 Tampermonkey 之類的腳本管理器,跟本站「抓價書籤/自動送回」同一套模式)。安裝後按「⚡ 自動輪查」:腳本會在每個 Trip.com 語言站等價格載入穩定後自動送回,並自動前往下一站——由本頁啟動的這一輪可以一路自動跑完 24 站,你只要看著矩陣被填滿。
⬆️ 「⚡ 自動輪查」「🚀 一次多開」按鈕已移到上方比價矩陣標題下,方便邊按邊看。
https://cuijian-home-tw.web.app/flights/cuijian-trip-autograb.user.js;或按「複製腳本」→「新增腳本」→ 全選貼上 → 儲存(Ctrl+S)。安全設計:腳本 @grant none(不要求任何特權)、只對 trip.com 網域生效,且只在網址帶著本頁發出的 _agrab=1 標記時才動作——平常自己逛 Trip.com 完全不會被讀取或跳轉;單輪有 20 分鐘與 60 站次上限,隨時可按「停止輪查」。抓到的一律是頁面顯示的參考價。
// ==UserScript==
// @name 外站票情報站:Trip.com 自動輪查
// @namespace https://cuijian-home-tw.web.app/
// @version 1.4.3
// @description 只在從「Trip.com 語言比價室」按下自動輪查(網址帶 _agrab=1)時,讀取頁面顯示的最低 TWD 參考價送回工具;支援多分頁並行(背景分頁被瀏覽器節流時會耐心等待,不會誤判逾時)。平常瀏覽 Trip.com 完全不會動作。
// @match https://*.trip.com/*
// @grant none
// @run-at document-idle
// @updateURL https://cuijian-home-tw.web.app/flights/cuijian-trip-autograb.user.js
// @downloadURL https://cuijian-home-tw.web.app/flights/cuijian-trip-autograb.user.js
// ==/UserScript==
// v1.2.0(2026-10-11):加上 @updateURL / @downloadURL —— 可一鍵安裝,之後 Tampermonkey 會自動更新(只從本站下載這一個檔,不連第三方)。抓價邏輯與 v1.1.0 相同。
// v1.3.0(2026-10-14):修正「抓到的價格比實際低很多」—— 舊版取「整頁所有 TWD 數字的最小值」,會抓到頁首日期列
// (其他日期組合的價格,如 11/16–11/20 TWD4,572)、價格提醒框(推薦 TWD7,270)、加價金額(+TWD 632)。
// 改成只讀「航班卡片」上的價格:卡片 = 價格往上最近一層含 ≥2 個時刻(03:05 / 06:05)的區塊,且該區塊只含 1~2 種價格
// (整串清單或提醒框會含很多價格,排除);「+」開頭的加價金額排除。實測 tw 站 TPE⇄CJU 11/18–11/22:舊版 4,572 → 新版 7,503(與頁面「最低價」一致)。
// 讀不到任何航班卡片價格時回報「沒抓到價」,寧可空白也不回報錯的價格。
// v1.3.1(2026-10-14):等「最低價」也穩定 6 秒、且首次出現價格後至少 12 秒才送 —— 避開 Trip.com 先顯示的暫時價(實測偏低約 6%)。
// v1.3.2(2026-10-15):卡片必須含 ≥2 個機場代碼(TPE/CJU…)—— 實測 nl 站左側篩選面板「Depart | 00:00 | 23:59 | TWD 7.836」會被當成卡片。
// v1.3.3(2026-10-15):①優先讀排序分頁「最低價」(清單逐步載入,最便宜的班次可能還沒出現;實測 tw TPE⇄OSA 15,571→15,496 與頁面一致)
// ②送回時附上查詢日期,工具端行程不同就不收(避免改行程後舊分頁把別的行程的價格填進來)。
// v1.4.0(2026-10-15):有指定航空公司時,自動「選取」最便宜的去程、進到回程(多段則逐段),讀最後一步的價格
// —— 確保去回程都是指定的航司(第 1 步的價格是「該航司去程 + 任何航司最便宜回程」,會偏低)。
// 換頁後同一個分頁用 sessionStorage 記住是工具開的(15 分鐘);沒指定航司時行為與 v1.3.3 相同(第 1 步就是全航司最低來回價)。
// v1.4.1(2026-10-16):從沒被看見過的背景分頁不因 10 分鐘牆鐘放棄(背景分頁清單不載入,輪到前景才會載),最多等 30 分鐘。
// v1.4.2(2026-10-16):遇到「搜尋結果已逾期」彈窗、或在背景等超過 8 分鐘才輪到前景 → 自動重新整理拿最新價(同頁最多 2 次)。
// v1.4.3(2026-10-16):逾時還沒完成(在前景 90 秒清單沒出來、或按不到「選取」)→ 先自動重新整理再試,兩次都不行才回報沒抓到。
(function () {
"use strict";
if (!/\/flights\//.test(location.pathname)) return;
// v1.4.0:有指定航空公司(網址 airline=)時要「去回程都是該航司」—— 第 1 步顯示的是「該航司去程 + 任何航司最便宜回程」
// (業主實測 RMQ⇄ICN 只查 KE:第 1 步 16,903 = 大韓去程 + 廉航回程;選了大韓去程後第 2 步才是大韓來回 18,614)。
// 所以有航司篩選時:第 1 步選最便宜那班 → 下一步 → … → 最後一步才讀價送回。換頁後網址沒有 _agrab,
// 改用這個分頁的 sessionStorage 記住「這是工具開的查價分頁」(15 分鐘內有效,只在同一分頁)。
var ARM_KEY = "cj_agrab_arm_v1", arm = null;
try { arm = JSON.parse(sessionStorage.getItem(ARM_KEY) || "null"); } catch (e) { arm = null; }
if (/[?&]_agrab=1/.test(location.search)) {
var q0 = String(location.search);
var legs0 = /[?&]triptype=rt\b/i.test(q0) ? 2 : /[?&]triptype=ow\b/i.test(q0) ? 1 : ((q0.match(/[?&]multddate\d+=/gi) || []).length || 1);
arm = { t: Date.now(), legs: legs0, al: /[?&]airline=[A-Za-z0-9]/.test(q0), d: datesIn(q0), step: 1 };
try { sessionStorage.setItem(ARM_KEY, JSON.stringify(arm)); } catch (e) {}
} else if (!(arm && typeof arm === "object" && Date.now() - Number(arm.t) < 900000 && arm.al)) {
return; // 非自動輪查模式(或不是工具開的分頁):什麼都不做
}
function datesIn(s) {
var ds = String(s).match(/\d{4}-\d{2}-\d{2}/g) || [], out = [];
for (var i = 0; i < ds.length && out.length < 8; i++) if (out.indexOf(ds[i]) < 0) out.push(ds[i]);
return out;
}
function curStep() { var m = /[?&]currentseqno=(\d+)/i.exec(location.search); var n = m ? parseInt(m[1], 10) : 1; return n >= 1 && n <= 9 ? n : 1; }
function disarm() { try { sessionStorage.removeItem(ARM_KEY); } catch (e) {} }
var TOOL = "https://cuijian-home-tw.web.app/flights/triplang.html";
var START = Date.now(), done = false;
var visibleMs = 0, lastTick = Date.now(); // 只累計「分頁可見」的時間:背景分頁被瀏覽器節流時不算逾時
function b64url(s) { return btoa(unescape(encodeURIComponent(s))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); }
// v1.3.0:只讀「航班卡片」上的價格(見檔頭說明)。整數 TWD(含 7,503 / 7 503 / 7.503 千分位寫法)。
var PRICE_RE = /(?:TWD|NT\$)\s?([0-9]{1,3}(?:[.,\u00a0\u202f ][0-9]{3})+|[0-9]{3,7})(?![0-9])|([0-9]{1,3}(?:[.,\u00a0\u202f ][0-9]{3})+|[0-9]{3,7})\s?TWD/;
var PRICE_RE_G = new RegExp(PRICE_RE.source, "g");
var TIME_RE_G = /(?:^|[^\d:\u2013-])\d{1,2}:\d{2}(?![\d:])(?!\s*[\u2013-]\s*\d)/g; // 單一時刻;「00:00–24:00」這種篩選範圍不算
function priceOf(m) { var n = Number(String(m[1] || m[2] || "").replace(/[^0-9]/g, "")); return (isFinite(n) && n >= 500 && n <= 2000000000) ? n : null; }
function scan() {
var vals = [], cards = [], cheap = null, cheapN = Infinity;
var els = document.body ? document.body.getElementsByTagName("*") : [];
for (var i = 0; i < els.length; i++) {
var el = els[i];
if (el.children.length > 3) continue;
var own = (el.innerText || "").trim();
if (!own || own.length > 30) continue;
var m = PRICE_RE.exec(own);
if (!m || own.indexOf("+") >= 0) continue; // 「+TWD 632」是加價金額,不是票價
var p = el, card = null;
for (var k = 0; k < 8 && p; k++) {
p = p.parentElement;
if (!p) break;
var tx = p.innerText || "";
if (tx.length > 500) break;
var tm = tx.match(TIME_RE_G);
if (tm && tm.length >= 2) { card = p; break; }
}
if (!card || cards.indexOf(card) >= 0) continue;
var uniq = {}, nu = 0, all = card.innerText.match(PRICE_RE_G) || [];
for (var j = 0; j < all.length; j++) { var key = all[j].replace(/[^0-9]/g, ""); if (!uniq[key]) { uniq[key] = 1; nu++; } }
if (nu > 2) continue; // 含很多價格的是整串清單/提醒框,不是單一航班卡
// v1.3.2:航班卡一定有機場代碼(TPE / CJU);篩選面板的「出發 00:00 | 23:59 TWD…」沒有,排除
var codes = (card.innerText.match(/\b[A-Z]{3}\b/g) || []).filter(function (c) { return c !== "TWD"; });
if (codes.length < 2) continue;
cards.push(card);
// v1.4.0:一張卡只取「第一個」價格(班次票價),後面的價格不算 —— 只有一班時,價格提醒框
// (推薦:TWD11,507)會和航班卡被認成同一塊(實測 tw RMQ⇄ICN 只查 KE);「總額」也排在每人票價後面。
var n = firstCardPrice(card);
if (n != null) { vals.push(n); if (n < cheapN) { cheapN = n; cheap = card; } }
}
var cardMin = vals.length ? Math.min.apply(null, vals) : null;
// v1.3.3:優先採用清單上方的排序分頁(推薦 / 直飛優先 / 最低價)—— 「最低價」那格是 Trip.com 對整份清單算的最低價;
// 清單是逐步載入的,最便宜的那班可能還沒出現在畫面上(實測 tw TPE⇄OSA:卡片最低 15,571、分頁「最低價」15,496)。
var bar = cards.length ? sortBarPrices(cards[0]) : null;
var min = cardMin;
if (bar) { var bm = Math.min.apply(null, bar); if (cardMin == null || bm >= cardMin * 0.7) min = bm; } // 離譜地低=認錯區塊,不採用
return { count: vals.length, min: min, bar: bar ? bar.join(",") : "", cheapCard: cheap };
}
function firstCardPrice(card) {
var tx = card.innerText || "", mm;
PRICE_RE_G.lastIndex = 0;
while ((mm = PRICE_RE_G.exec(tx))) {
if (tx.charAt(mm.index - 1) === "+" || /\+\s*$/.test(tx.slice(Math.max(0, mm.index - 3), mm.index))) continue; // +TWD 632 加價
PRICE_RE_G.lastIndex = 0;
return priceOf(mm);
}
PRICE_RE_G.lastIndex = 0;
return null;
}
// v1.4.0:按下航班卡上的「選取」(各語言字不同,用結構找:卡片內最後一個可點、短字、不含數字的元素)
function clickSelect(card) {
if (!card) return false;
var pick = null, c, t, i;
var btns = card.querySelectorAll("button,[role=button],a");
for (i = 0; i < btns.length; i++) { t = (btns[i].innerText || "").trim(); if (t && t.length <= 20 && !/\d/.test(t)) pick = btns[i]; }
if (!pick) {
var leaves = card.getElementsByTagName("*");
for (i = 0; i < leaves.length; i++) {
c = leaves[i]; if (c.children.length) continue;
t = (c.innerText || "").trim();
if (!t || t.length > 15 || /\d/.test(t)) continue;
try { if (getComputedStyle(c).cursor === "pointer" || getComputedStyle(c.parentElement).cursor === "pointer") pick = c; } catch (e) {}
}
}
if (!pick) return false;
try { pick.click(); return true; } catch (e) { return false; }
}
// 從第一張航班卡往「前面」找:含 2~4 個價格、每格只有「文字標籤+價格」(標籤不含數字)、沒有時刻的那一排 = 排序分頁
function sortBarPrices(firstCard) {
var all = document.body.getElementsByTagName("*"), idx = -1;
for (var i = 0; i < all.length; i++) { if (all[i] === firstCard) { idx = i; break; } }
for (var x = idx - 1; x >= 0 && x > idx - 400; x--) {
var c = all[x], kids = c.children;
if (kids.length < 3 || kids.length > 6) continue;
var tx = c.innerText || "";
if (tx.length > 200 || /\d{1,2}:\d{2}/.test(tx)) continue;
var prices = [], bad = false;
for (var j = 0; j < kids.length; j++) {
var kt = (kids[j].innerText || "").trim(), m = PRICE_RE.exec(kt);
if (!m) continue;
if (kt.length > 40 || /\d/.test(kt.replace(m[0], ""))) { bad = true; break; }
var n = priceOf(m);
if (n != null) prices.push(n);
}
// 排序分頁固定 3 格(推薦 / 直飛優先 / 最低價;各語言同結構)—— 左側篩選「大型飛機 / 中型飛機」只有 2 格,排除
if (!bad && prices.length === 3) return prices;
}
return null;
}
function go(url) { if (done) return; done = true; location.href = url; }
// v1.3.1:不只「卡片數量」要穩定,「最低價」也要穩定才送 —— Trip.com 會先顯示一批暫時價格再換成即時價,
// 卡片數不變但價格還在變;舊版數量穩定 5 秒就送,抓到偏低的暫時價(業主實測 nl 7,316 vs 實際 7,763)。
var lastSig = "", stableAt = Date.now(), firstPriceAt = 0;
var STABLE_MS = 6000, MIN_AFTER_FIRST_MS = 12000;
// v1.3.3:送回時附上這個分頁查的日期(d)—— 工具端比對「目前行程」的日期,不同就不收
// (業主實測:改了行程後,舊行程還在跑的分頁把濟州的價格回填到大阪的矩陣上)。
function tripDates() {
var ds = String(location.search).match(/\d{4}-\d{2}-\d{2}/g) || [], out = [];
for (var i = 0; i < ds.length && out.length < 8; i++) if (out.indexOf(ds[i]) < 0) out.push(ds[i]);
return out;
}
function sendDates() { return (arm && arm.d && arm.d.length) ? arm.d : tripDates(); }
function clearReloads() { try { sessionStorage.removeItem("cj_agrab_reload_" + location.pathname); } catch (e) {} }
function send(r) { clearReloads(); disarm(); go(TOOL + "#px=" + b64url(JSON.stringify({ v: 1, host: location.hostname, price: r.min, t: Date.now(), d: sendDates() }))); }
function fail() { clearReloads(); disarm(); go(TOOL + "#pxfail=" + b64url(JSON.stringify({ v: 1, host: location.hostname, t: Date.now() }))); }
var advancing = 0, advFrom = 0;
// 「搜尋結果已逾期」偵測:畫面上固定位置(彈窗)的區塊含各語言的「逾期/過期」字樣
var EXPIRED_WORDS = ["逾期", "過期", "已失效", "过期", "expired", "abgelaufen", "expiré", "scadut", "caducad", "expirad", "verlopen",
"期限切れ", "有効期限", "만료", "หมดอายุ", "hết hạn", "kedaluwarsa", "tamat tempoh", "wygas", "süresi dol", "истек", "закінч",
"έληξ", "udløbet", "vanhentun", "utgått", "expirou"];
function expiredDialog() {
var els = document.body ? document.body.querySelectorAll("[role=dialog],[class*=modal],[class*=Modal],[class*=dialog],[class*=Dialog],[class*=popup],[class*=Popup]") : [];
for (var i = 0; i < els.length; i++) {
var e = els[i], t = (e.innerText || "").toLowerCase();
if (!t || t.length > 600) continue;
var rc = e.getBoundingClientRect(), cs = getComputedStyle(e);
if (rc.width < 50 || rc.height < 30 || cs.display === "none" || cs.visibility === "hidden" || Number(cs.opacity) === 0) continue; // 只認真的顯示在畫面上的彈窗
for (var j = 0; j < EXPIRED_WORDS.length; j++) if (t.indexOf(EXPIRED_WORDS[j].toLowerCase()) >= 0) return true;
}
return false;
}
function reloadOnce() {
var key = "cj_agrab_reload_" + location.pathname, n = 0;
try { n = parseInt(sessionStorage.getItem(key) || "0", 10) || 0; } catch (e) {}
if (n >= 2) return false;
try { sessionStorage.setItem(key, String(n + 1)); } catch (e) {}
done = true; clearInterval(iv);
location.reload();
return true;
}
function tick() {
if (done) return;
var now = Date.now();
if (!document.hidden) visibleMs += Math.min(now - lastTick, 3000); // 背景時間不計入
lastTick = now;
// v1.4.2:「搜尋結果已逾期」視窗(頁面放太久,價格可能已變)→ 自動重新整理拿最新價格(同一頁最多 2 次)
// 另外:分頁在背景等了 8 分鐘以上才輪到前景,畫面上的價格也是舊的 → 先重新整理再讀,不送舊價。
// 保險:就算沒認出彈窗,頁面在前景、開了 10 分鐘還沒完成,也重新整理一次(Trip.com 結果約 10 分鐘就會逾期)
if (expiredDialog() || (!document.hidden && now - START > 480000 && (!firstPriceAt || now - START > 600000))) {
if (reloadOnce()) return;
if (expiredDialog()) { clearInterval(iv); fail(); return; } // 已重整 2 次仍逾期:放棄這站(寧可空白)
}
// 剛按了「選取」:等頁面換到下一步(換頁會重跑本腳本;同頁更新則看網址的 currentseqno 或清單變化)
if (advancing) {
if (curStep() === advFrom && now - advancing < 20000) return;
advancing = 0; lastSig = ""; firstPriceAt = 0; stableAt = now;
}
var r = scan();
var sig = r.count + "|" + r.min + "|" + r.bar;
if (r.count > 0 && !firstPriceAt) firstPriceAt = now;
if (r.count > 0 && sig === lastSig) {
// 卡片數與最低價都 6 秒沒變,且第一次出現價格後至少等 12 秒 = 載完(即時價已換上)
if (now - stableAt >= STABLE_MS && now - firstPriceAt >= MIN_AFTER_FIRST_MS) {
// 有指定航司、還沒到最後一步:選最便宜那班、進下一步(去回程都要是該航司)
if (arm && arm.al && curStep() < arm.legs) {
if (clickSelect(r.cheapCard)) { advancing = now; advFrom = curStep(); return; }
clearInterval(iv); if (!reloadOnce()) fail(); return; // 按不到「選取」:先重整再試;仍不行寧可空白,不回報「只有去程是該航司」的錯價
}
clearInterval(iv); send(r); return;
}
} else { lastSig = sig; stableAt = now; }
// 逾時只看「可見時間」90 秒;背景分頁最多等 10 分鐘牆鐘,期間持續掃描
// v1.4.1:背景分頁的航班清單常常不會載入(瀏覽器暫停背景分頁的畫面更新);舊版 10 分鐘牆鐘一到就回報「無價」,
// 同時開好幾站時,最先開的幾個分頁(被後面的蓋到背景)幾乎都這樣失敗(業主實測 tw/hk/www 開了 9 分鐘才回報無價)。
// 改成:從沒被看見過的分頁不因牆鐘放棄(前面的分頁抓完關掉後,它就會輪到前景),最多等 30 分鐘。
if (visibleMs > 90000 || (visibleMs > 0 && now - START > 600000) || now - START > 1800000) {
clearInterval(iv);
if (r.count > 0 && !(arm && arm.al && curStep() < arm.legs)) send(r);
// v1.4.3:逾時還沒完成(清單沒出來、或卡在第 1 步選不到下一步)→ 先自動重新整理再試(同頁最多 2 次),仍不行才回報沒抓到
else if (!reloadOnce()) fail();
}
}
var iv = setInterval(tick, 800);
document.addEventListener("visibilitychange", function () { lastTick = Date.now(); if (!document.hidden) tick(); }); // 切回分頁立刻重掃
window.addEventListener("focus", function () { lastTick = Date.now(); tick(); });
})();
分享連結只帶行程與乘客/艙等設定(編在網址 # 後面,不經伺服器);你回填的參考價留在本機 localStorage,不會跟著連結走。免登入,清瀏覽器資料會清掉草稿。