@skrillex1224/playwright-toolkit 3.0.51 → 3.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +2 -1
- package/dist/browser.js.map +2 -2
- package/dist/index.cjs +161 -2
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +161 -2
- package/dist/index.js.map +4 -4
- package/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -54,7 +54,8 @@ var Code = {
|
|
|
54
54
|
Chaptcha: 30000002,
|
|
55
55
|
Timeout: 30000003,
|
|
56
56
|
InitialTimeout: 30000004,
|
|
57
|
-
OverallTimeout: 30000005
|
|
57
|
+
OverallTimeout: 30000005,
|
|
58
|
+
AccountFreeze: 30000006
|
|
58
59
|
};
|
|
59
60
|
var Status = {
|
|
60
61
|
Success: "SUCCESS",
|
|
@@ -6768,6 +6769,155 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
|
|
|
6768
6769
|
}
|
|
6769
6770
|
var sloveCaptcha = solveCaptcha;
|
|
6770
6771
|
|
|
6772
|
+
// src/internals/captcha/qbot_chaptcha.js
|
|
6773
|
+
var QBOT_CAPTCHA_TYPE = "30119";
|
|
6774
|
+
var QBOT_IMAGE_BASE_WIDTH = 310;
|
|
6775
|
+
var QBOT_IMAGE_BASE_HEIGHT = 155;
|
|
6776
|
+
var DEFAULT_QBOT_PAGE_OPTIONS = Object.freeze({
|
|
6777
|
+
formSelector: 'xpath=//*[@id="seccodeForm"]',
|
|
6778
|
+
imageSelector: 'xpath=//*[@id="seccodeForm"]//img',
|
|
6779
|
+
extraSelector: 'xpath=//*[@id="seccodeForm"]//*[@class="verify-bar-area"]/span',
|
|
6780
|
+
submitSelector: 'xpath=//*[@id="submit"]',
|
|
6781
|
+
refreshSelector: 'xpath=//*[@class="verify-refresh"]',
|
|
6782
|
+
formVisibleTimeoutMs: 1e4,
|
|
6783
|
+
imageVisibleTimeoutMs: 1e4,
|
|
6784
|
+
extraVisibleTimeoutMs: 5e3,
|
|
6785
|
+
vcSelector: "#vc",
|
|
6786
|
+
vcValueTimeoutMs: 8e3,
|
|
6787
|
+
submitLoadTimeoutMs: 3e4,
|
|
6788
|
+
coordinateBaseWidth: QBOT_IMAGE_BASE_WIDTH,
|
|
6789
|
+
coordinateBaseHeight: QBOT_IMAGE_BASE_HEIGHT,
|
|
6790
|
+
clickIntervalMs: 250,
|
|
6791
|
+
refreshVisibleTimeoutMs: 1e3,
|
|
6792
|
+
refreshWaitMs: 1e3,
|
|
6793
|
+
maxRetries: 3
|
|
6794
|
+
});
|
|
6795
|
+
var normalizeQbotCaptchaImage = (src = "") => String(src || "").split(",").pop().trim();
|
|
6796
|
+
var extractQbotCaptchaExtra = (text = "") => {
|
|
6797
|
+
const content = String(text || "").match(/【([^】]+)】/)?.[1] || "";
|
|
6798
|
+
return content.split(/[,,]/).map((item) => item.trim()).filter(Boolean);
|
|
6799
|
+
};
|
|
6800
|
+
var parseQbotCaptchaCoordinates = (value = "") => String(value || "").split("|").map((pair) => {
|
|
6801
|
+
const [x, y] = pair.split(",").map(Number);
|
|
6802
|
+
return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;
|
|
6803
|
+
}).filter(Boolean);
|
|
6804
|
+
async function solveQbotCaptcha(image, extra = [], token, options = {}, dependencies = {}) {
|
|
6805
|
+
const { callCaptchaRecognitionApi: callCaptchaRecognitionApi2 } = dependencies;
|
|
6806
|
+
if (!token) {
|
|
6807
|
+
throw new Error("[Captcha] \u7F3A\u5C11 qbot \u9A8C\u8BC1\u7801 token\u3002");
|
|
6808
|
+
}
|
|
6809
|
+
if (typeof callCaptchaRecognitionApi2 !== "function") {
|
|
6810
|
+
throw new Error("[Captcha] \u7F3A\u5C11\u901A\u7528\u8BC6\u522B\u8BF7\u6C42\u51FD\u6570 callCaptchaRecognitionApi\u3002");
|
|
6811
|
+
}
|
|
6812
|
+
const response = await callCaptchaRecognitionApi2({
|
|
6813
|
+
apiUrl: options.apiUrl,
|
|
6814
|
+
token,
|
|
6815
|
+
type: QBOT_CAPTCHA_TYPE,
|
|
6816
|
+
image,
|
|
6817
|
+
extra
|
|
6818
|
+
});
|
|
6819
|
+
return response?.data?.data ?? response?.data;
|
|
6820
|
+
}
|
|
6821
|
+
var readQbotCaptcha = async (page, config) => {
|
|
6822
|
+
const imageLocator = page.locator(config.imageSelector).first();
|
|
6823
|
+
await imageLocator.waitFor({ state: "visible", timeout: config.imageVisibleTimeoutMs });
|
|
6824
|
+
const image = normalizeQbotCaptchaImage(await imageLocator.getAttribute("src"));
|
|
6825
|
+
if (!image) {
|
|
6826
|
+
throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801\u56FE\u7247\u4E3A\u7A7A\u3002");
|
|
6827
|
+
}
|
|
6828
|
+
const extraLocator = page.locator(config.extraSelector).first();
|
|
6829
|
+
await extraLocator.waitFor({ state: "visible", timeout: config.extraVisibleTimeoutMs });
|
|
6830
|
+
const extra = extractQbotCaptchaExtra(await extraLocator.textContent());
|
|
6831
|
+
if (extra.length === 0) {
|
|
6832
|
+
throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801 extra \u4E3A\u7A7A\u3002");
|
|
6833
|
+
}
|
|
6834
|
+
return { imageLocator, image, extra };
|
|
6835
|
+
};
|
|
6836
|
+
var clickQbotPoints = async (page, imageLocator, coordinates, config, deviceInput) => {
|
|
6837
|
+
const box = await imageLocator.boundingBox();
|
|
6838
|
+
if (!box) {
|
|
6839
|
+
throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801\u56FE\u7247\u4F4D\u7F6E\u4E0D\u53EF\u7528\u3002");
|
|
6840
|
+
}
|
|
6841
|
+
const scaleX = box.width / config.coordinateBaseWidth;
|
|
6842
|
+
const scaleY = box.height / config.coordinateBaseHeight;
|
|
6843
|
+
for (const point of coordinates) {
|
|
6844
|
+
await deviceInput.clickPoint(page, {
|
|
6845
|
+
x: box.x + point.x * scaleX,
|
|
6846
|
+
y: box.y + point.y * scaleY
|
|
6847
|
+
}, config);
|
|
6848
|
+
if (config.clickIntervalMs > 0) {
|
|
6849
|
+
await page.waitForTimeout(config.clickIntervalMs);
|
|
6850
|
+
}
|
|
6851
|
+
}
|
|
6852
|
+
};
|
|
6853
|
+
var refreshQbotCaptcha = async (page, config, deviceInput, logger18) => {
|
|
6854
|
+
try {
|
|
6855
|
+
const refreshLocator = page.locator(config.refreshSelector).first();
|
|
6856
|
+
if (!await waitForVisible(refreshLocator, config.refreshVisibleTimeoutMs)) return;
|
|
6857
|
+
await deviceInput.click(page, refreshLocator, { ...config, fallbackDomClick: true });
|
|
6858
|
+
if (config.refreshWaitMs > 0) {
|
|
6859
|
+
await page.waitForTimeout(config.refreshWaitMs);
|
|
6860
|
+
}
|
|
6861
|
+
} catch (error) {
|
|
6862
|
+
logger18?.warn?.(`[Captcha] qbot \u9A8C\u8BC1\u7801\u5237\u65B0\u5931\u8D25\uFF0C\u7EE7\u7EED\u629B\u51FA\u539F\u9519\u8BEF\uFF1A${error?.message || error}`);
|
|
6863
|
+
}
|
|
6864
|
+
};
|
|
6865
|
+
var solveQbotCaptchaAttempt = async (page, config, dependencies) => {
|
|
6866
|
+
const { callCaptchaRecognitionApi: callCaptchaRecognitionApi2, deviceInput } = dependencies;
|
|
6867
|
+
const { imageLocator, image, extra } = await readQbotCaptcha(page, config);
|
|
6868
|
+
const coordinateText = await solveQbotCaptcha(image, extra, config.token, config, {
|
|
6869
|
+
callCaptchaRecognitionApi: callCaptchaRecognitionApi2
|
|
6870
|
+
});
|
|
6871
|
+
const coordinates = parseQbotCaptchaCoordinates(coordinateText);
|
|
6872
|
+
if (coordinates.length === 0) {
|
|
6873
|
+
throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801\u5750\u6807\u4E3A\u7A7A\u3002");
|
|
6874
|
+
}
|
|
6875
|
+
await clickQbotPoints(page, imageLocator, coordinates, config, deviceInput);
|
|
6876
|
+
await page.waitForFunction(
|
|
6877
|
+
(selector) => Boolean(document.querySelector(selector)?.value),
|
|
6878
|
+
config.vcSelector,
|
|
6879
|
+
{ timeout: config.vcValueTimeoutMs }
|
|
6880
|
+
);
|
|
6881
|
+
await deviceInput.click(page, page.locator(config.submitSelector).first(), {
|
|
6882
|
+
...config,
|
|
6883
|
+
fallbackDomClick: true
|
|
6884
|
+
});
|
|
6885
|
+
await page.waitForLoadState("domcontentloaded", { timeout: config.submitLoadTimeoutMs }).catch(() => {
|
|
6886
|
+
});
|
|
6887
|
+
return true;
|
|
6888
|
+
};
|
|
6889
|
+
async function solveCaptcha2(page, options = {}, dependencies = {}) {
|
|
6890
|
+
const config = { ...DEFAULT_QBOT_PAGE_OPTIONS, ...options };
|
|
6891
|
+
const logger18 = dependencies.logger || options.logger;
|
|
6892
|
+
const deviceInput = dependencies.deviceInput || DeviceInput;
|
|
6893
|
+
if (!config.token) {
|
|
6894
|
+
logger18?.warn?.("[Captcha] \u7F3A\u5C11 qbot \u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
|
|
6895
|
+
return false;
|
|
6896
|
+
}
|
|
6897
|
+
const formLocator = page.locator(config.formSelector).first();
|
|
6898
|
+
if (!await waitForVisible(formLocator, config.formVisibleTimeoutMs)) {
|
|
6899
|
+
return false;
|
|
6900
|
+
}
|
|
6901
|
+
const maxRetries = Math.max(1, Number(config.maxRetries) || 1);
|
|
6902
|
+
let lastError = null;
|
|
6903
|
+
for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
|
|
6904
|
+
try {
|
|
6905
|
+
return await solveQbotCaptchaAttempt(page, config, {
|
|
6906
|
+
...dependencies,
|
|
6907
|
+
deviceInput
|
|
6908
|
+
});
|
|
6909
|
+
} catch (error) {
|
|
6910
|
+
lastError = error;
|
|
6911
|
+
logger18?.warn?.(`[Captcha] qbot \u9A8C\u8BC1\u7801\u8BC6\u522B\u7B2C ${attempt}/${maxRetries} \u6B21\u5931\u8D25\uFF1A${error?.message || error}`);
|
|
6912
|
+
if (attempt < maxRetries) {
|
|
6913
|
+
await refreshQbotCaptcha(page, config, deviceInput, logger18);
|
|
6914
|
+
}
|
|
6915
|
+
}
|
|
6916
|
+
}
|
|
6917
|
+
throw lastError;
|
|
6918
|
+
}
|
|
6919
|
+
var sloveCaptcha2 = solveCaptcha2;
|
|
6920
|
+
|
|
6771
6921
|
// src/chaptcha.js
|
|
6772
6922
|
var logger13 = createInternalLogger("Captcha");
|
|
6773
6923
|
var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
|
|
@@ -6780,6 +6930,9 @@ var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
|
6780
6930
|
var CAPTCHA_STRATEGIES = Object.freeze({
|
|
6781
6931
|
bytedance: {
|
|
6782
6932
|
sloveCaptcha
|
|
6933
|
+
},
|
|
6934
|
+
qbot: {
|
|
6935
|
+
sloveCaptcha: sloveCaptcha2
|
|
6783
6936
|
}
|
|
6784
6937
|
});
|
|
6785
6938
|
var mergeDefinedOptions = (...sources) => {
|
|
@@ -6924,9 +7077,15 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
|
|
|
6924
7077
|
logger: logger13
|
|
6925
7078
|
});
|
|
6926
7079
|
}
|
|
7080
|
+
async function solveQbotCaptcha2(image, extra = [], token, options = {}) {
|
|
7081
|
+
return solveQbotCaptcha(image, extra, token, options, {
|
|
7082
|
+
callCaptchaRecognitionApi
|
|
7083
|
+
});
|
|
7084
|
+
}
|
|
6927
7085
|
var Captcha = {
|
|
6928
7086
|
useCaptchaMonitor,
|
|
6929
|
-
solveCaptchaWithStrategy
|
|
7087
|
+
solveCaptchaWithStrategy,
|
|
7088
|
+
solveQbotCaptcha: solveQbotCaptcha2
|
|
6930
7089
|
};
|
|
6931
7090
|
|
|
6932
7091
|
// src/mutation.js
|