@skrillex1224/playwright-toolkit 3.0.52 → 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/index.js CHANGED
@@ -6741,6 +6741,155 @@ async function solveCaptcha(page, options = {}, dependencies = {}) {
6741
6741
  }
6742
6742
  var sloveCaptcha = solveCaptcha;
6743
6743
 
6744
+ // src/internals/captcha/qbot_chaptcha.js
6745
+ var QBOT_CAPTCHA_TYPE = "30119";
6746
+ var QBOT_IMAGE_BASE_WIDTH = 310;
6747
+ var QBOT_IMAGE_BASE_HEIGHT = 155;
6748
+ var DEFAULT_QBOT_PAGE_OPTIONS = Object.freeze({
6749
+ formSelector: 'xpath=//*[@id="seccodeForm"]',
6750
+ imageSelector: 'xpath=//*[@id="seccodeForm"]//img',
6751
+ extraSelector: 'xpath=//*[@id="seccodeForm"]//*[@class="verify-bar-area"]/span',
6752
+ submitSelector: 'xpath=//*[@id="submit"]',
6753
+ refreshSelector: 'xpath=//*[@class="verify-refresh"]',
6754
+ formVisibleTimeoutMs: 1e4,
6755
+ imageVisibleTimeoutMs: 1e4,
6756
+ extraVisibleTimeoutMs: 5e3,
6757
+ vcSelector: "#vc",
6758
+ vcValueTimeoutMs: 8e3,
6759
+ submitLoadTimeoutMs: 3e4,
6760
+ coordinateBaseWidth: QBOT_IMAGE_BASE_WIDTH,
6761
+ coordinateBaseHeight: QBOT_IMAGE_BASE_HEIGHT,
6762
+ clickIntervalMs: 250,
6763
+ refreshVisibleTimeoutMs: 1e3,
6764
+ refreshWaitMs: 1e3,
6765
+ maxRetries: 3
6766
+ });
6767
+ var normalizeQbotCaptchaImage = (src = "") => String(src || "").split(",").pop().trim();
6768
+ var extractQbotCaptchaExtra = (text = "") => {
6769
+ const content = String(text || "").match(/【([^】]+)】/)?.[1] || "";
6770
+ return content.split(/[,,]/).map((item) => item.trim()).filter(Boolean);
6771
+ };
6772
+ var parseQbotCaptchaCoordinates = (value = "") => String(value || "").split("|").map((pair) => {
6773
+ const [x, y] = pair.split(",").map(Number);
6774
+ return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;
6775
+ }).filter(Boolean);
6776
+ async function solveQbotCaptcha(image, extra = [], token, options = {}, dependencies = {}) {
6777
+ const { callCaptchaRecognitionApi: callCaptchaRecognitionApi2 } = dependencies;
6778
+ if (!token) {
6779
+ throw new Error("[Captcha] \u7F3A\u5C11 qbot \u9A8C\u8BC1\u7801 token\u3002");
6780
+ }
6781
+ if (typeof callCaptchaRecognitionApi2 !== "function") {
6782
+ throw new Error("[Captcha] \u7F3A\u5C11\u901A\u7528\u8BC6\u522B\u8BF7\u6C42\u51FD\u6570 callCaptchaRecognitionApi\u3002");
6783
+ }
6784
+ const response = await callCaptchaRecognitionApi2({
6785
+ apiUrl: options.apiUrl,
6786
+ token,
6787
+ type: QBOT_CAPTCHA_TYPE,
6788
+ image,
6789
+ extra
6790
+ });
6791
+ return response?.data?.data ?? response?.data;
6792
+ }
6793
+ var readQbotCaptcha = async (page, config) => {
6794
+ const imageLocator = page.locator(config.imageSelector).first();
6795
+ await imageLocator.waitFor({ state: "visible", timeout: config.imageVisibleTimeoutMs });
6796
+ const image = normalizeQbotCaptchaImage(await imageLocator.getAttribute("src"));
6797
+ if (!image) {
6798
+ throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801\u56FE\u7247\u4E3A\u7A7A\u3002");
6799
+ }
6800
+ const extraLocator = page.locator(config.extraSelector).first();
6801
+ await extraLocator.waitFor({ state: "visible", timeout: config.extraVisibleTimeoutMs });
6802
+ const extra = extractQbotCaptchaExtra(await extraLocator.textContent());
6803
+ if (extra.length === 0) {
6804
+ throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801 extra \u4E3A\u7A7A\u3002");
6805
+ }
6806
+ return { imageLocator, image, extra };
6807
+ };
6808
+ var clickQbotPoints = async (page, imageLocator, coordinates, config, deviceInput) => {
6809
+ const box = await imageLocator.boundingBox();
6810
+ if (!box) {
6811
+ throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801\u56FE\u7247\u4F4D\u7F6E\u4E0D\u53EF\u7528\u3002");
6812
+ }
6813
+ const scaleX = box.width / config.coordinateBaseWidth;
6814
+ const scaleY = box.height / config.coordinateBaseHeight;
6815
+ for (const point of coordinates) {
6816
+ await deviceInput.clickPoint(page, {
6817
+ x: box.x + point.x * scaleX,
6818
+ y: box.y + point.y * scaleY
6819
+ }, config);
6820
+ if (config.clickIntervalMs > 0) {
6821
+ await page.waitForTimeout(config.clickIntervalMs);
6822
+ }
6823
+ }
6824
+ };
6825
+ var refreshQbotCaptcha = async (page, config, deviceInput, logger18) => {
6826
+ try {
6827
+ const refreshLocator = page.locator(config.refreshSelector).first();
6828
+ if (!await waitForVisible(refreshLocator, config.refreshVisibleTimeoutMs)) return;
6829
+ await deviceInput.click(page, refreshLocator, { ...config, fallbackDomClick: true });
6830
+ if (config.refreshWaitMs > 0) {
6831
+ await page.waitForTimeout(config.refreshWaitMs);
6832
+ }
6833
+ } catch (error) {
6834
+ logger18?.warn?.(`[Captcha] qbot \u9A8C\u8BC1\u7801\u5237\u65B0\u5931\u8D25\uFF0C\u7EE7\u7EED\u629B\u51FA\u539F\u9519\u8BEF\uFF1A${error?.message || error}`);
6835
+ }
6836
+ };
6837
+ var solveQbotCaptchaAttempt = async (page, config, dependencies) => {
6838
+ const { callCaptchaRecognitionApi: callCaptchaRecognitionApi2, deviceInput } = dependencies;
6839
+ const { imageLocator, image, extra } = await readQbotCaptcha(page, config);
6840
+ const coordinateText = await solveQbotCaptcha(image, extra, config.token, config, {
6841
+ callCaptchaRecognitionApi: callCaptchaRecognitionApi2
6842
+ });
6843
+ const coordinates = parseQbotCaptchaCoordinates(coordinateText);
6844
+ if (coordinates.length === 0) {
6845
+ throw new Error("[Captcha] qbot \u9A8C\u8BC1\u7801\u5750\u6807\u4E3A\u7A7A\u3002");
6846
+ }
6847
+ await clickQbotPoints(page, imageLocator, coordinates, config, deviceInput);
6848
+ await page.waitForFunction(
6849
+ (selector) => Boolean(document.querySelector(selector)?.value),
6850
+ config.vcSelector,
6851
+ { timeout: config.vcValueTimeoutMs }
6852
+ );
6853
+ await deviceInput.click(page, page.locator(config.submitSelector).first(), {
6854
+ ...config,
6855
+ fallbackDomClick: true
6856
+ });
6857
+ await page.waitForLoadState("domcontentloaded", { timeout: config.submitLoadTimeoutMs }).catch(() => {
6858
+ });
6859
+ return true;
6860
+ };
6861
+ async function solveCaptcha2(page, options = {}, dependencies = {}) {
6862
+ const config = { ...DEFAULT_QBOT_PAGE_OPTIONS, ...options };
6863
+ const logger18 = dependencies.logger || options.logger;
6864
+ const deviceInput = dependencies.deviceInput || DeviceInput;
6865
+ if (!config.token) {
6866
+ logger18?.warn?.("[Captcha] \u7F3A\u5C11 qbot \u9A8C\u8BC1\u7801 token\uFF0C\u8DF3\u8FC7\u81EA\u52A8\u8BC6\u522B\u3002");
6867
+ return false;
6868
+ }
6869
+ const formLocator = page.locator(config.formSelector).first();
6870
+ if (!await waitForVisible(formLocator, config.formVisibleTimeoutMs)) {
6871
+ return false;
6872
+ }
6873
+ const maxRetries = Math.max(1, Number(config.maxRetries) || 1);
6874
+ let lastError = null;
6875
+ for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
6876
+ try {
6877
+ return await solveQbotCaptchaAttempt(page, config, {
6878
+ ...dependencies,
6879
+ deviceInput
6880
+ });
6881
+ } catch (error) {
6882
+ lastError = error;
6883
+ logger18?.warn?.(`[Captcha] qbot \u9A8C\u8BC1\u7801\u8BC6\u522B\u7B2C ${attempt}/${maxRetries} \u6B21\u5931\u8D25\uFF1A${error?.message || error}`);
6884
+ if (attempt < maxRetries) {
6885
+ await refreshQbotCaptcha(page, config, deviceInput, logger18);
6886
+ }
6887
+ }
6888
+ }
6889
+ throw lastError;
6890
+ }
6891
+ var sloveCaptcha2 = solveCaptcha2;
6892
+
6744
6893
  // src/chaptcha.js
6745
6894
  var logger13 = createInternalLogger("Captcha");
6746
6895
  var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
@@ -6753,6 +6902,9 @@ var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
6753
6902
  var CAPTCHA_STRATEGIES = Object.freeze({
6754
6903
  bytedance: {
6755
6904
  sloveCaptcha
6905
+ },
6906
+ qbot: {
6907
+ sloveCaptcha: sloveCaptcha2
6756
6908
  }
6757
6909
  });
6758
6910
  var mergeDefinedOptions = (...sources) => {
@@ -6897,9 +7049,15 @@ async function solveCaptchaWithStrategy(strategyName, page, options = {}) {
6897
7049
  logger: logger13
6898
7050
  });
6899
7051
  }
7052
+ async function solveQbotCaptcha2(image, extra = [], token, options = {}) {
7053
+ return solveQbotCaptcha(image, extra, token, options, {
7054
+ callCaptchaRecognitionApi
7055
+ });
7056
+ }
6900
7057
  var Captcha = {
6901
7058
  useCaptchaMonitor,
6902
- solveCaptchaWithStrategy
7059
+ solveCaptchaWithStrategy,
7060
+ solveQbotCaptcha: solveQbotCaptcha2
6903
7061
  };
6904
7062
 
6905
7063
  // src/mutation.js