mirror of
https://github.com/foxhui/WebAI2API.git
synced 2026-06-16 21:03:59 +08:00
fix: 再次修复 Gemini 懒加载的问题
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
import {
|
||||
sleep,
|
||||
safeClick,
|
||||
safeScroll,
|
||||
uploadFilesViaChooser
|
||||
} from '../engine/utils.js';
|
||||
import {
|
||||
@@ -173,9 +174,8 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) {
|
||||
meta
|
||||
});
|
||||
|
||||
// 等待图片元素出现并滚动到可视范围,触发懒加载
|
||||
await scrollToElement(page, 'model-response', { timeout: 20000 });
|
||||
|
||||
// 将图片滚动到可视范围,触发懒加载
|
||||
await scrollToElement(page, 'generated-image', { timeout: 120000 });
|
||||
imageResponse = await imageResponsePromise;
|
||||
} catch (e) {
|
||||
const pageError = normalizePageError(e, meta);
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
uploadFilesViaChooser
|
||||
} from '../engine/utils.js';
|
||||
import {
|
||||
fillPrompt,
|
||||
normalizePageError,
|
||||
moveMouseAway,
|
||||
waitForInput,
|
||||
@@ -123,7 +124,7 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) {
|
||||
if (await modelCombobox.count() > 0) {
|
||||
await safeClick(page, modelCombobox.first(), { bias: 'button' });
|
||||
await sleep(300, 500);
|
||||
await safeClick(page, page.getByRole('option', { name: codeName }), { bias: 'button' });
|
||||
await safeClick(page, page.getByRole('option', { name: codeName, exact: true }), { bias: 'button' });
|
||||
await sleep(300, 500);
|
||||
logger.debug('适配器', `模型已设置为 ${codeName}`, meta);
|
||||
}
|
||||
@@ -185,7 +186,7 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) {
|
||||
logger.info('适配器', '输入提示词...', meta);
|
||||
const textarea = page.locator('textarea[placeholder]');
|
||||
await waitForInput(page, textarea, { click: true });
|
||||
await textarea.fill(prompt);
|
||||
await fillPrompt(page, textarea, prompt, meta);
|
||||
await sleep(500, 1000);
|
||||
|
||||
// 7. 先启动 API 监听,再点击发送
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* 职责边界:
|
||||
* - 浏览器原子操作(点击、输入、上传等)
|
||||
* - 页面状态检测(isPageValid、createPageCloseWatcher)
|
||||
* - 拟人化交互(humanType、safeClick)
|
||||
* - 拟人化交互(humanType、safeClick、safeScroll)
|
||||
* - 工具函数(random、sleep、getMimeType)
|
||||
*
|
||||
* 注意:业务逻辑应放在 backend/utils.js
|
||||
@@ -200,6 +200,62 @@ export async function safeClick(page, target, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全滚动 (包含拟人化移动和滚轮滚动)
|
||||
* 支持 CSS selector、ElementHandle 和 Locator 三种输入
|
||||
* @param {import('playwright-core').Page} page - Playwright 页面对象
|
||||
* @param {string|import('playwright-core').ElementHandle|import('playwright-core').Locator} target - CSS 选择器、元素句柄或 Locator
|
||||
* @param {object} [options] - 滚动选项
|
||||
* @param {number} [options.deltaX=0] - 水平滚动距离 (正值向右)
|
||||
* @param {number} [options.deltaY=0] - 垂直滚动距离 (正值向下)
|
||||
* @param {string} [options.bias='random'] - 偏移偏好: 'input' 或 'random'
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function safeScroll(page, target, options = {}) {
|
||||
try {
|
||||
let el;
|
||||
|
||||
// 判断输入类型
|
||||
if (typeof target === 'string') {
|
||||
// CSS selector
|
||||
el = await page.$(target);
|
||||
if (!el) throw new Error(`未找到: ${target}`);
|
||||
} else if (typeof target.elementHandle === 'function') {
|
||||
// Locator (来自 page.getByRole, page.getByText 等)
|
||||
el = await target.elementHandle();
|
||||
if (!el) throw new Error(`Locator 未匹配到元素`);
|
||||
} else {
|
||||
// ElementHandle
|
||||
el = target;
|
||||
if (!el || !el.asElement()) throw new Error(`Element handle invalid`);
|
||||
}
|
||||
|
||||
const deltaX = options.deltaX || 0;
|
||||
const deltaY = options.deltaY || 0;
|
||||
|
||||
// 使用 ghost-cursor hover 后滚动
|
||||
if (page.cursor) {
|
||||
const box = await el.boundingBox();
|
||||
if (box) {
|
||||
const { x, y } = getHumanClickPoint(box, options.bias || 'random');
|
||||
await page.cursor.moveTo({ x, y });
|
||||
await page.mouse.wheel(deltaX, deltaY);
|
||||
return;
|
||||
}
|
||||
// 如果无法获取 box,降级到元素中心点滚动
|
||||
await page.cursor.move(el);
|
||||
await page.mouse.wheel(deltaX, deltaY);
|
||||
return;
|
||||
}
|
||||
|
||||
// 降级逻辑: 直接在元素上 hover 并滚动
|
||||
await el.hover();
|
||||
await page.mouse.wheel(deltaX, deltaY);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟人类键盘输入
|
||||
* 支持 CSS selector 和 ElementHandle 两种输入
|
||||
|
||||
Reference in New Issue
Block a user