From 9afc5407a99b68c8a506808515c83e61014346b7 Mon Sep 17 00:00:00 2001 From: NobyDa <53217160+NobyDa@users.noreply.github.com> Date: Mon, 16 Jan 2023 00:43:43 +0800 Subject: [PATCH] Add bypass Google CAPTCHA script. --- Surge/JS/Google_CAPTCHA.js | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Surge/JS/Google_CAPTCHA.js diff --git a/Surge/JS/Google_CAPTCHA.js b/Surge/JS/Google_CAPTCHA.js new file mode 100644 index 0000000..0b33470 --- /dev/null +++ b/Surge/JS/Google_CAPTCHA.js @@ -0,0 +1,63 @@ +/* +Google搜索内容时并发使用多个策略(组),以避免可能出现的人机验证 + +注:该脚本仅兼容Surge(4.9.3+),使用时需要在脚本配置内的argument参数中填写筛选策略(组)的正则表达式,留空则表示同时使用所有策略(组) + +Surge脚本配置: + +[Script] +Google CAPTCHA = type=http-response,pattern=^https:\/\/www\.google\.com(\.[a-z]+|)\/search\?q=,requires-body=1,debug=0,script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Google_CAPTCHA.js,max-size=0,timeout=10,ability=http-client-policy,argument=^(🇸🇬|🇭🇰)\s.*\d+$ + +[MITM] +hostname = www.google.com* + +*/ + +let ret = {}; + +(async () => { + if ($response.status !== 200) { + const allPolicy = await new Promise((r) => { + $httpAPI("GET", "v1/policies", null, (v) => r( + [...v.proxies, ...v['policy-groups']] + )) + }); + const selected = allPolicy.filter((n) => { + return n && new RegExp(typeof $argument == 'string' ? $argument : "").test(n) + }); + console.log(`[INFO]: Use policy ${JSON.stringify(selected, null, 2)}`); + const http = [ + new Promise((r, e) => setTimeout(() => e('Timeout'), 5000)), + ...selected.map( + (v) => new Promise((r, e) => { + $httpClient[$request.method.toLowerCase()]({ + url: $request.url, + headers: $request.headers, + policy: v + }, (error, response, body) => { + if (response && response.status == 200) { + r({ + policy: v, + body: { + headers: response.headers, + status: response.status, + body: body + } + }) + } else if (response && response.status == 429) { + console.log(`[ERROR]: Policy "${v}" need to CAPTCHA`); + } else if (error) { + console.log(`[ERROR]: Policy "${v}" ${error}`); + } + }) + }) + ) + ]; + await Promise.race(http).then((data) => { + ret = data.body; + console.log(`[INFO]: Use data from "${data.policy}"`); + }); + } +})() + .catch((err) => console.log(`[ERROR]: ${(err && err.message) || err}`)) + .finally(() => $done(ret)); \ No newline at end of file