|
|
import type { Page } from "playwright";
|
|
|
|
|
|
/** 官网匿名报价次数上限(cookie / 邮箱 / IP 维度) */
|
|
|
export async function isFlockQuoteLimitReached(page: Page): Promise<boolean> {
|
|
|
const body = ((await page.locator("body").innerText().catch(() => "")) || "")
|
|
|
.slice(0, 8_000);
|
|
|
return isFlockQuoteLimitText(body);
|
|
|
}
|
|
|
|
|
|
export function isFlockQuoteLimitText(body: string): boolean {
|
|
|
return (
|
|
|
/quote\s*limit|reached\s*(your\s*)?limit|too\s*many\s*quotes/i.test(body) ||
|
|
|
/获取报价.*上限|报价.*达到.*上限|已达.*上限|次数.*上限|达到.*获取报价.*上限/i.test(
|
|
|
body,
|
|
|
) ||
|
|
|
/Thank you for your interest/i.test(body)
|
|
|
);
|
|
|
}
|
|
|
|
|
|
export function describeFlockPagePhase(body: string): string {
|
|
|
if (isFlockQuoteLimitText(body)) {
|
|
|
return "quote_limit";
|
|
|
}
|
|
|
if (/Create your free account/i.test(body) && /Work email/i.test(body)) {
|
|
|
return "registration";
|
|
|
}
|
|
|
if (
|
|
|
/Explore your custom quote options|fulfillment-option|Prices from \$/i.test(
|
|
|
body,
|
|
|
)
|
|
|
) {
|
|
|
return "quote_results";
|
|
|
}
|
|
|
if (/Pickup ZIP Code|Number of pallets|Total shipment weight|Shipment Pickup|Freight Class|Generate my quote|Let'?s build a quote/i.test(body)) {
|
|
|
return "quote_form";
|
|
|
}
|
|
|
if (/Thank you for your interest/i.test(body)) {
|
|
|
return "quote_limit_thank_you";
|
|
|
}
|
|
|
return "unknown";
|
|
|
}
|
|
|
|
|
|
export async function flockQuoteLimitMessage(page: Page): Promise<string | null> {
|
|
|
if (!(await isFlockQuoteLimitReached(page))) {
|
|
|
return null;
|
|
|
}
|
|
|
const body = ((await page.locator("body").innerText().catch(() => "")) || "").slice(
|
|
|
0,
|
|
|
500,
|
|
|
);
|
|
|
if (/Thank you for your interest/i.test(body)) {
|
|
|
return "FLOCK_QUOTE_LIMIT:官网提示 Thank you for your interest(获取报价已达上限)";
|
|
|
}
|
|
|
return "FLOCK_QUOTE_LIMIT:官网报价次数已达上限(请 npm run record:flock -- --fresh 或换无痕会话)";
|
|
|
}
|
|
|
|
|
|
/** 注册失败提示(含虚构邮箱被拒、账号已存在) */
|
|
|
export async function flockRegistrationErrorMessage(
|
|
|
page: Page,
|
|
|
): Promise<string | null> {
|
|
|
const body = await page.locator("body").innerText().catch(() => "");
|
|
|
if (/We had an issue creating your account/i.test(body)) {
|
|
|
return "FLOCK_ACCOUNT_REJECTED:官网拒绝创建账号(邮箱已排除时多为:自动化指纹/同电话复用/IP 频控/姓名公司像机器人)";
|
|
|
}
|
|
|
if (/already (have|registered)|email.*(taken|exists|in use)/i.test(body)) {
|
|
|
return "FLOCK_ACCOUNT_EXISTS:该邮箱已注册,请加载录制会话或换邮箱";
|
|
|
}
|
|
|
return null;
|
|
|
}
|