feat: 一键打开渠道|渠道开关房脚本问题修复
This commit is contained in:
@@ -1,4 +1,49 @@
|
|||||||
const preparePage = async (chromium, { tabIndex = Number(process.env.TAB_INDEX), endpoint = process.env.CDP_ENDPOINT || 'http://127.0.0.1:9222' } = {}) => {
|
const normalizeUrl = (value) => {
|
||||||
|
const raw = String(value || '').trim();
|
||||||
|
if (!raw) return null;
|
||||||
|
try {
|
||||||
|
return new URL(raw);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSameTarget = (currentUrl, targetUrl) => {
|
||||||
|
if (!currentUrl || !targetUrl) return false;
|
||||||
|
if (currentUrl.startsWith(targetUrl)) return true;
|
||||||
|
|
||||||
|
const current = normalizeUrl(currentUrl);
|
||||||
|
const target = normalizeUrl(targetUrl);
|
||||||
|
if (!current || !target) return false;
|
||||||
|
if (current.origin !== target.origin) return false;
|
||||||
|
if (!current.pathname.startsWith(target.pathname)) return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSameOrigin = (currentUrl, targetUrl) => {
|
||||||
|
const current = normalizeUrl(currentUrl);
|
||||||
|
const target = normalizeUrl(targetUrl);
|
||||||
|
if (!current || !target) return false;
|
||||||
|
return current.origin === target.origin;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isBlankLikePage = (url) => {
|
||||||
|
const u = String(url || '').trim().toLowerCase();
|
||||||
|
if (!u) return true;
|
||||||
|
if (u === 'about:blank' || u.startsWith('about:blank#') || u.startsWith('about:blank?')) return true;
|
||||||
|
if (u === 'chrome://newtab/' || u.startsWith('chrome://newtab')) return true;
|
||||||
|
if (u.startsWith('chrome://new-tab-page')) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const preparePage = async (
|
||||||
|
chromium,
|
||||||
|
{
|
||||||
|
tabIndex = Number(process.env.TAB_INDEX),
|
||||||
|
endpoint = process.env.CDP_ENDPOINT || 'http://127.0.0.1:9222',
|
||||||
|
targetUrl,
|
||||||
|
} = {},
|
||||||
|
) => {
|
||||||
const browser = await chromium.connectOverCDP(endpoint);
|
const browser = await chromium.connectOverCDP(endpoint);
|
||||||
const context = browser.contexts()[0];
|
const context = browser.contexts()[0];
|
||||||
|
|
||||||
@@ -10,17 +55,67 @@ const preparePage = async (chromium, { tabIndex = Number(process.env.TAB_INDEX),
|
|||||||
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
||||||
});
|
});
|
||||||
|
|
||||||
const idx = Number.isFinite(tabIndex) && tabIndex >= 0 ? Math.floor(tabIndex) : 0;
|
|
||||||
let pages = await context.pages();
|
let pages = await context.pages();
|
||||||
|
let page = null;
|
||||||
|
|
||||||
while (pages.length <= idx) {
|
if (targetUrl) {
|
||||||
await context.newPage();
|
// 1. Try exact/path match
|
||||||
pages = await context.pages();
|
for (let i = 0; i < pages.length; i++) {
|
||||||
|
const p = pages[i];
|
||||||
|
if (isSameTarget(p.url(), targetUrl)) {
|
||||||
|
page = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Try origin match
|
||||||
|
if (!page) {
|
||||||
|
for (let i = 0; i < pages.length; i++) {
|
||||||
|
const p = pages[i];
|
||||||
|
if (isSameOrigin(p.url(), targetUrl)) {
|
||||||
|
page = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
const isTabIndexSet = Number.isFinite(tabIndex) && tabIndex >= 0;
|
||||||
|
|
||||||
|
// If targetUrl provided and NO specific tabIndex requested, avoid hijacking tab 0
|
||||||
|
if (targetUrl && !isTabIndexSet) {
|
||||||
|
// Try blank page
|
||||||
|
for (let i = 0; i < pages.length; i++) {
|
||||||
|
if (isBlankLikePage(pages[i].url())) {
|
||||||
|
page = pages[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Else new page
|
||||||
|
if (!page) {
|
||||||
|
page = await context.newPage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Legacy/Default behavior: use tabIndex (default 0)
|
||||||
|
const idx = isTabIndexSet ? Math.floor(tabIndex) : 0;
|
||||||
|
while (pages.length <= idx) {
|
||||||
|
await context.newPage();
|
||||||
|
pages = await context.pages();
|
||||||
|
}
|
||||||
|
page = pages[idx];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = pages[idx];
|
|
||||||
await page.bringToFront();
|
await page.bringToFront();
|
||||||
|
|
||||||
|
if (targetUrl) {
|
||||||
|
const currentUrl = page.url();
|
||||||
|
if (!currentUrl || !isSameTarget(currentUrl, targetUrl)) {
|
||||||
|
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { browser, context, page };
|
return { browser, context, page };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,22 @@
|
|||||||
|
import { chromium } from 'playwright';
|
||||||
import log from 'electron-log';
|
import log from 'electron-log';
|
||||||
|
import tabsPkg from './common/tabs.js';
|
||||||
|
|
||||||
log.info('dy_trace.mjs placeholder: not implemented');
|
const { preparePage, safeDisconnectBrowser } = tabsPkg;
|
||||||
process.exit(0);
|
|
||||||
|
(async () => {
|
||||||
|
let browser;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const targetUrl = process.env.TARGET_URL || 'https://life.douyin.com/';
|
||||||
|
const prepared = await preparePage(chromium, { targetUrl });
|
||||||
|
browser = prepared.browser;
|
||||||
|
|
||||||
|
log.info('dy_hotel_trace.mjs placeholder: not implemented');
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
process.exitCode = 1;
|
||||||
|
} finally {
|
||||||
|
await safeDisconnectBrowser(browser);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { chromium } from 'playwright';
|
import { chromium } from 'playwright';
|
||||||
import log from 'electron-log';
|
import log from 'electron-log';
|
||||||
import tabsPkg from './common/tabs';
|
import tabsPkg from './common/tabs.js';
|
||||||
|
|
||||||
const { preparePage, safeDisconnectBrowser } = tabsPkg;
|
const { preparePage, safeDisconnectBrowser } = tabsPkg;
|
||||||
|
|
||||||
@@ -94,16 +94,11 @@ const toggleRoomByDateIndex = async (container, { roomType, dateIndex, operation
|
|||||||
let browser;
|
let browser;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const prepared = await preparePage(chromium);
|
const targetUrl = 'https://hotel.fliggy.com/ebooking/hotelBaseInfoUv.htm#/ebk/homeV1';
|
||||||
|
const prepared = await preparePage(chromium, { targetUrl });
|
||||||
browser = prepared.browser;
|
browser = prepared.browser;
|
||||||
const page = prepared.page;
|
const page = prepared.page;
|
||||||
|
|
||||||
const targetUrl = 'https://hotel.fliggy.com/ebooking/hotelBaseInfoUv.htm#/ebk/homeV1';
|
|
||||||
const currentUrl = page.url();
|
|
||||||
if (!currentUrl || !currentUrl.startsWith(targetUrl)) {
|
|
||||||
await page.goto(targetUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
await page.waitForTimeout(4000 + Math.random() * 300);
|
await page.waitForTimeout(4000 + Math.random() * 300);
|
||||||
|
|
||||||
await page.getByRole('menuitem', { name: '房价房量管理' }).click();
|
await page.getByRole('menuitem', { name: '房价房量管理' }).click();
|
||||||
|
|||||||
@@ -7,14 +7,10 @@ const { preparePage, safeDisconnectBrowser } = tabsPkg;
|
|||||||
let browser;
|
let browser;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const prepared = await preparePage(chromium);
|
const targetUrl = 'https://me.meituan.com/ebooking/merchant/product#/index';
|
||||||
|
const prepared = await preparePage(chromium, { targetUrl });
|
||||||
browser = prepared.browser;
|
browser = prepared.browser;
|
||||||
const page = prepared.page;
|
const page = prepared.page;
|
||||||
const targetUrl = 'https://me.meituan.com/ebooking/merchant/product#/index';
|
|
||||||
const currentUrl = page.url();
|
|
||||||
if (!currentUrl || !currentUrl.startsWith(targetUrl)) {
|
|
||||||
await page.goto(targetUrl);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
|
|||||||
@@ -12,6 +12,37 @@ const parseChannels = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const normalizeUrl = (value) => {
|
||||||
|
const raw = String(value || '').trim();
|
||||||
|
if (!raw) return null;
|
||||||
|
try {
|
||||||
|
return new URL(raw);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSameTarget = (currentUrl, targetUrl) => {
|
||||||
|
if (!currentUrl || !targetUrl) return false;
|
||||||
|
if (currentUrl.startsWith(targetUrl)) return true;
|
||||||
|
|
||||||
|
const current = normalizeUrl(currentUrl);
|
||||||
|
const target = normalizeUrl(targetUrl);
|
||||||
|
if (!current || !target) return false;
|
||||||
|
if (current.origin !== target.origin) return false;
|
||||||
|
if (!current.pathname.startsWith(target.pathname)) return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isBlankLikePage = (url) => {
|
||||||
|
const u = String(url || '').trim().toLowerCase();
|
||||||
|
if (!u) return true;
|
||||||
|
if (u === 'about:blank' || u.startsWith('about:blank#') || u.startsWith('about:blank?')) return true;
|
||||||
|
if (u === 'chrome://newtab/' || u.startsWith('chrome://newtab')) return true;
|
||||||
|
if (u.startsWith('chrome://new-tab-page')) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
let browser;
|
let browser;
|
||||||
|
|
||||||
@@ -34,27 +65,56 @@ const parseChannels = () => {
|
|||||||
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const usedPages = new Set();
|
||||||
|
|
||||||
for (let i = 0; i < channels.length; i++) {
|
for (let i = 0; i < channels.length; i++) {
|
||||||
const targetUrl = channels[i]?.channelUrl;
|
const targetUrl = channels[i]?.channelUrl;
|
||||||
|
|
||||||
if (!targetUrl) continue;
|
if (!targetUrl) continue;
|
||||||
|
|
||||||
let pages = await context.pages();
|
let pages = await context.pages();
|
||||||
|
let page = null;
|
||||||
while (pages.length <= i) {
|
for (let j = 0; j < pages.length; j++) {
|
||||||
await context.newPage();
|
const p = pages[j];
|
||||||
pages = await context.pages();
|
const current = p.url();
|
||||||
|
if (isSameTarget(current, targetUrl)) {
|
||||||
|
page = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = pages[i];
|
if (!page) {
|
||||||
|
for (let j = 0; j < pages.length; j++) {
|
||||||
|
const p = pages[j];
|
||||||
|
if (usedPages.has(p)) continue;
|
||||||
|
if (isBlankLikePage(p.url())) {
|
||||||
|
page = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
page = await context.newPage();
|
||||||
|
}
|
||||||
await page.bringToFront();
|
await page.bringToFront();
|
||||||
|
usedPages.add(page);
|
||||||
|
|
||||||
const current = page.url();
|
const current = page.url();
|
||||||
|
|
||||||
if (!current || !current.startsWith(targetUrl)) {
|
if (!current || !isSameTarget(current, targetUrl)) {
|
||||||
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
|
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pagesAfter = await context.pages();
|
||||||
|
for (const p of pagesAfter) {
|
||||||
|
if (!usedPages.has(p) && isBlankLikePage(p.url())) {
|
||||||
|
try {
|
||||||
|
await p.close();
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user