feat: 飞猪自动化调试完成

This commit is contained in:
duanshuwen
2026-03-10 21:26:17 +08:00
parent 15a7d115cb
commit 8a6544ede2
7 changed files with 124 additions and 130 deletions

View File

@@ -0,0 +1,129 @@
import { chromium } from 'playwright';
import log from 'electron-log';
const checkLoginStatus = async (page) => {
try {
const currentUrl = await page.url();
log.info('current url==========>:', currentUrl);
const loginPagePatterns = ['/login', '/signin', '/auth'];
const isLoginPage = loginPagePatterns.some(pattern => currentUrl.includes(pattern));
if(!isLoginPage) {
return true;
}
// 检查页面内容中的关键字
const pageContent = await page.content();
const loginKeywords = ['退出', '房价房量管理'];
const hasLoginKeyword = loginKeywords.some(keyword =>
pageContent.includes(keyword)
);
if (hasLoginKeyword) {
return true;
}
return false;
} catch (error) {
return false;
}
}
(async () => {
const browser = await chromium.connectOverCDP(`http://localhost:9222`);
const context = browser.contexts()[0];
await context.addInitScript(() => {
Object.defineProperty(navigator, 'webdriver', { get: ()=> undefined });
});
const pages = await context.pages();
const page = pages.length ? pages[0] : await context.newPage();
await page.goto('https://hotel.fliggy.com/ebooking/hotelBaseInfoUv.htm#/ebk/homeV1');
const isLogin = await checkLoginStatus(page);
if(!isLogin) {
await page.getByRole('textbox', { name: '请输入账号' }).dblclick();
await page.getByRole('textbox', { name: '请输入账号' }).click();
await page.getByRole('textbox', { name: '请输入账号' }).fill('hoteltmwq123', { delay: 80 + Math.random() * 120 });
await page.waitForTimeout(1000 + Math.random() * 1000);
await page.getByRole('button', { name: '下一步' }).click();
const frame_1 = await page.frameLocator('#alibaba-login-box');
await page.locator('#alibaba-login-box').contentFrame().getByRole('textbox', { name: '请输入登录密码' }).dblclick();
await page.locator('#alibaba-login-box').contentFrame().getByRole('textbox', { name: '请输入登录密码' }).fill('Tmwq654321', { delay: 80 + Math.random() * 120 });
await page.waitForTimeout(1000 + Math.random() * 1000);
await page.locator('#alibaba-login-box').contentFrame().getByRole('button', { name: '登录' }).click();
// 等待滑块真正出现在 DOM 并可见
await page.waitForTimeout(4000 + Math.random() * 1000);
const frame_2 = await frame_1.frameLocator('#baxia-dialog-content');
const container = await frame_2.locator('#nc_1_nocaptcha');
const slider = await frame_2.locator('#nc_1_n1z');
const isVisible = await slider.isVisible();
if (isVisible) {
// 重新获取滑块按钮(可能嵌套在 iframe 里)
const containerBox = await container.boundingBox();
const sliderBox = await slider.boundingBox();
const startX = sliderBox.x + sliderBox.width / 2;
const startY = sliderBox.y + sliderBox.height / 2;
const distance = containerBox.width - sliderBox.width; // 适当拉长拖动距离
const steps = 20; // 分多步模拟人手拖动
await page.mouse.move(startX, startY);
// 等待随机时间再开始滑动(模拟人类反应)
await page.waitForTimeout(200 + Math.random() * 300);
await page.mouse.down();
await page.waitForTimeout(100 + Math.random() * 200);
// 按轨迹滑动
for (let i = 0; i < steps; i++) {
await page.mouse.move(
sliderBox.x + sliderBox.width / 2 + (distance * (i + 1) / steps),
sliderBox.y + sliderBox.height / 2 + (Math.random() * 5 - 2.5), // 模拟轻微Y轴抖动
{ steps: 5 }
);
}
await page.mouse.up();
}
}
await page.waitForTimeout(4000 + Math.random() * 300);
await page.getByRole('menuitem', { name: '房价房量管理' }).click();
await page.waitForTimeout(4000 + Math.random() * 1000);
await page.getByText('房价房量日历').click();
// await page.pause();
/*
* 1、我要知道日期
* 2、我要知道房型
* 3、我要知道是关闭或开启操作
*
* 存在以下影响自动化情况:
* 1、房型重新拖拽排序会影响后续操作
* 2、筛选日期下存在没有安排的房型
*/
// await page.getByRole('textbox', { name: '-02-27' }).click();
// await page.getByText('27').nth(3).click();
// 开启房型div:nth-child(动态变化的) > .boardRow___p2ZiO > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r
// await page.locator('div:nth-child(7) > div > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').first().click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(2) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(3) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(4) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(5) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// 关闭房型div:nth-child(动态变化的) > .boardRow___p2ZiO > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').first().click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(2) > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(3) > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(4) > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').click();
})();