@tocha688/browser 1.0.2 → 1.0.4
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.cjs +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/package.json +5 -2
- package/CHANGELOG.md +0 -12
- package/src/actions/auto/click.ts +0 -59
- package/src/actions/auto/index.ts +0 -236
- package/src/actions/auto/input.ts +0 -157
- package/src/actions/auto/poll.ts +0 -145
- package/src/actions/auto/scroll.ts +0 -81
- package/src/actions/auto/select.ts +0 -240
- package/src/actions/auto/types.ts +0 -63
- package/src/actions/auto/utils.ts +0 -36
- package/src/actions/auto/wait.ts +0 -105
- package/src/actions/index.ts +0 -1
- package/src/const/browser.ts +0 -215
- package/src/core/config.ts +0 -3
- package/src/core/launcher.ts +0 -45
- package/src/core/pool.ts +0 -70
- package/src/human/mouse.ts +0 -308
- package/src/index.ts +0 -13
- package/src/network/cache.ts +0 -130
- package/src/network/resource.ts +0 -62
- package/src/providers/ads_tool.ts +0 -38
- package/src/providers/adspower.ts +0 -245
- package/src/providers/base.ts +0 -80
- package/src/providers/local.ts +0 -40
- package/src/providers/ok.ts +0 -102
- package/src/types/index.ts +0 -24
- package/tsconfig.json +0 -29
- package/tsup.config.ts +0 -14
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { faker } from "@faker-js/faker";
|
|
4
|
-
import { adsEncodeBase64, adsDecodeBase64 } from "./ads_tool";
|
|
5
|
-
import { PcScreen, WindowsWebGL, Cpus, Memorys, rSysFonts } from "../const/browser";
|
|
6
|
-
import type { BrowserResult, BrowserStartOptions } from "../types";
|
|
7
|
-
import { checkAutoProxy, rArrItem, rInt, uuidV4, rAutoDigitInt, type ProxyServerResult, startProxyServer, getIpInfo } from "@tocha688/utils";
|
|
8
|
-
import { launchBrowserBase } from "./base";
|
|
9
|
-
|
|
10
|
-
export async function AdsBrowserStartMain(opts: BrowserStartOptions): Promise<BrowserResult> {
|
|
11
|
-
return launchBrowserBase(opts, {
|
|
12
|
-
prepare: async (userDataDir, devtoolsPort) => {
|
|
13
|
-
|
|
14
|
-
const webGLFP_path = path.join(userDataDir, "webgl.json")
|
|
15
|
-
const dynamicConfig_path = path.join(userDataDir, "dynamic.config")
|
|
16
|
-
const staticConfig_path = path.join(userDataDir, "static.config")
|
|
17
|
-
const params_path = path.join(userDataDir, "params.config")
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
let params: string;
|
|
21
|
-
let screenSize: string;
|
|
22
|
-
|
|
23
|
-
if (fs.existsSync(params_path)) {
|
|
24
|
-
params = fs.readFileSync(params_path, "utf-8");
|
|
25
|
-
const decoded = JSON.parse(adsDecodeBase64(params));
|
|
26
|
-
screenSize = decoded.ScreenSize;
|
|
27
|
-
} else {
|
|
28
|
-
let ipinfo: any = {};
|
|
29
|
-
let proxyInfo: URL | undefined;
|
|
30
|
-
|
|
31
|
-
if (opts.proxy) {
|
|
32
|
-
ipinfo = await checkAutoProxy(opts.proxy);
|
|
33
|
-
proxyInfo = new URL(ipinfo.proxy)
|
|
34
|
-
} else {
|
|
35
|
-
ipinfo = await getIpInfo(ipinfo.proxy);
|
|
36
|
-
}
|
|
37
|
-
// console.log(ipinfo)
|
|
38
|
-
// webgl指纹
|
|
39
|
-
const config = {
|
|
40
|
-
// 指纹随机数种子
|
|
41
|
-
fp: rInt(100000, 999999),
|
|
42
|
-
geop: ipinfo?.latitude ? ipinfo?.latitude + "," + ipinfo?.longitude : "",
|
|
43
|
-
// 加上随机字符串 MSBYH29R
|
|
44
|
-
device_name: "PC" + faker.string.alphanumeric(8).toUpperCase(),
|
|
45
|
-
timezone: ipinfo?.timezone || ipinfo?.timeZone || "America/Los_Angeles",
|
|
46
|
-
proxy: {
|
|
47
|
-
protocol: proxyInfo?.protocol.replace(":", "") || "http",
|
|
48
|
-
host: proxyInfo?.hostname || "127.0.0.1",
|
|
49
|
-
port: proxyInfo?.port || "8080",
|
|
50
|
-
username: proxyInfo?.username || "",
|
|
51
|
-
password: proxyInfo?.password || "",
|
|
52
|
-
},
|
|
53
|
-
mac: faker.internet.mac(),
|
|
54
|
-
scanPorts: "",
|
|
55
|
-
screenSize: rArrItem(PcScreen),
|
|
56
|
-
langs: ipinfo?.languages ?? "en-US,en",
|
|
57
|
-
}
|
|
58
|
-
// console.log(config)
|
|
59
|
-
const webGL = rArrItem(WindowsWebGL);
|
|
60
|
-
const webGLFP = {
|
|
61
|
-
"UNMASKED_VENDOR_WEBGL": webGL.name,
|
|
62
|
-
"UNMASKED_RENDERER_WEBGL": rArrItem(webGL.values),
|
|
63
|
-
"GPUAdapterInfo": {
|
|
64
|
-
"vendor": webGL.vendor,
|
|
65
|
-
"architecture": "pascal"
|
|
66
|
-
},
|
|
67
|
-
"SUPPORTED_EXTENSIONS": [
|
|
68
|
-
]
|
|
69
|
-
}
|
|
70
|
-
// 黑名单 在名单上的不会修改指纹
|
|
71
|
-
const dynamic = {
|
|
72
|
-
"BlockList": {
|
|
73
|
-
"Version": "1743148877",
|
|
74
|
-
// 白名单域名
|
|
75
|
-
"Domains": []
|
|
76
|
-
},
|
|
77
|
-
"StrongBlockList": {
|
|
78
|
-
"Version": "3",
|
|
79
|
-
"Domains": []
|
|
80
|
-
},
|
|
81
|
-
"TimeZone": config.timezone,
|
|
82
|
-
"Geoposition": config.geop
|
|
83
|
-
}
|
|
84
|
-
// 静态配置
|
|
85
|
-
const staticConfig = {
|
|
86
|
-
// "CookiesExportPath": "C:\\.ADSPOWER_GLOBAL\\cache\\k186hhvu_hwvl6k\\sf_cookie.txt",
|
|
87
|
-
"CookiesExportPath": "",
|
|
88
|
-
"SecurePreferenceSync": true,
|
|
89
|
-
// "PasswordExportPath": "C:\\.ADSPOWER_GLOBAL\\cache\\k186hhvu_hwvl6k\\e2776b7f6d0ee269e7a3d43987c7b103",
|
|
90
|
-
"PasswordExportPath": "",
|
|
91
|
-
// "PasswordImportPath": "C:\\.ADSPOWER_GLOBAL\\cache\\k186hhvu_hwvl6k\\6c13174a34c549425974d259f9589e45",
|
|
92
|
-
"PasswordImportPath": "",
|
|
93
|
-
"RestoreLastSession": true,
|
|
94
|
-
// 黑名单页面的html base64编码
|
|
95
|
-
"BlockPage": "NDA0",
|
|
96
|
-
"FoceSafeBrowsing": true,
|
|
97
|
-
"ExtensionSetting": [
|
|
98
|
-
// {
|
|
99
|
-
// "path": "C:\\Users\\Administrator\\AppData\\Roaming\\Electron\\cwd_global\\lib\\tab_assistant",
|
|
100
|
-
// "pinned": 0,
|
|
101
|
-
// "hide": true,
|
|
102
|
-
// "version": "0.0.1",
|
|
103
|
-
// "accessWeb": true
|
|
104
|
-
// }
|
|
105
|
-
],
|
|
106
|
-
// 不修改指纹的域名列表 net-a-porter.com,nike.com,fedex.com,thenorthface,bybit.com,adidas.com,mrporter.com,lululemon.com,sephora.com,biglietti.italotreno.it,target.com,tangerine.ca,ipdog.io,dhl.com,spotify.com,vinted.com,pingpongx.com,uber.com,wildberries.ru
|
|
107
|
-
"DisCanvasUrl": "",
|
|
108
|
-
"MaxTouchPoints": 0,
|
|
109
|
-
"MediaDevices": [
|
|
110
|
-
{
|
|
111
|
-
"kind": "audioinput",
|
|
112
|
-
"label": "Microphone Array (Realtek(R) Audio)"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
"kind": "videoinput",
|
|
116
|
-
"label": "Integrated Camera (98da:3959)"
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
"kind": "audiooutput",
|
|
120
|
-
"label": "Speakers (Realtek(R) Audio)"
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
"AudioFp": rAutoDigitInt(980, config.fp),
|
|
124
|
-
// "WebGLMark": rAutoDigitInt("5001", config.fp).toString(),
|
|
125
|
-
// "WebGLMark": config.fp.toString(),
|
|
126
|
-
"WebGLMark": "5001",
|
|
127
|
-
"StartTime": Math.floor(Date.now() / 1000),
|
|
128
|
-
"GeolocationSetting": "ask",
|
|
129
|
-
"FlashPluginSetting": "block",
|
|
130
|
-
"Platform": "Win32",
|
|
131
|
-
"ScreenSize": config.screenSize,
|
|
132
|
-
"DisableBackgroundMode": true,
|
|
133
|
-
"DisableWebRTC": true,
|
|
134
|
-
"HardwareConcurrency": rArrItem(Cpus),
|
|
135
|
-
// "DeviceMemory": rArrItem(Memorys),
|
|
136
|
-
"DeviceMemory": rArrItem([4, 8]),
|
|
137
|
-
"LoadExtensionErrorBox": false,
|
|
138
|
-
"ClientRectFp": rAutoDigitInt("5001", config.fp).toString(),
|
|
139
|
-
"ForceProcessExit": true,
|
|
140
|
-
"ProxyUser": config.proxy.username,
|
|
141
|
-
"ProxyPassword": config.proxy.password,
|
|
142
|
-
"Langs": config.langs,
|
|
143
|
-
"AcceptLang": config.langs ? config.langs + ",q=0.9" : "en-US,en;q=0.9",
|
|
144
|
-
// 禁用字体
|
|
145
|
-
"DisabledFonts": (await rSysFonts()).join(","),
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
fs.writeFileSync(webGLFP_path, JSON.stringify(webGLFP))
|
|
149
|
-
fs.writeFileSync(dynamicConfig_path, adsEncodeBase64(JSON.stringify(dynamic)))
|
|
150
|
-
fs.writeFileSync(staticConfig_path, adsEncodeBase64(JSON.stringify(staticConfig)))
|
|
151
|
-
|
|
152
|
-
params = adsEncodeBase64(JSON.stringify({
|
|
153
|
-
"UserId": "1",
|
|
154
|
-
"CanvasMark": rAutoDigitInt("7949", config.fp).toString(),
|
|
155
|
-
"DisableContainer": true,
|
|
156
|
-
"WebGLFP": webGLFP_path,
|
|
157
|
-
"AudioFp": staticConfig.AudioFp,
|
|
158
|
-
"WebGLMark": staticConfig.WebGLMark,
|
|
159
|
-
"StartTime": staticConfig.StartTime,
|
|
160
|
-
"AllowScanPorts": config.scanPorts,
|
|
161
|
-
"GeolocationSetting": staticConfig.GeolocationSetting,
|
|
162
|
-
"FlashPluginSetting": staticConfig.FlashPluginSetting,
|
|
163
|
-
"Platform": staticConfig.Platform,
|
|
164
|
-
"ScreenSize": staticConfig.ScreenSize,
|
|
165
|
-
"DisableBackgroundMode": staticConfig.DisableBackgroundMode,
|
|
166
|
-
"DisableWebRTC": staticConfig.DisableWebRTC,
|
|
167
|
-
"HardwareConcurrency": staticConfig.HardwareConcurrency,
|
|
168
|
-
"DeviceMemory": staticConfig.DeviceMemory,
|
|
169
|
-
"LoadExtensionErrorBox": staticConfig.LoadExtensionErrorBox,
|
|
170
|
-
"ClientRectFp": staticConfig.ClientRectFp,
|
|
171
|
-
"CanvasMarkEx": rAutoDigitInt("7949", config.fp).toString(),
|
|
172
|
-
"WebGLMarkEx": rAutoDigitInt("5001", config.fp).toString(),
|
|
173
|
-
"command_line": {
|
|
174
|
-
"do-not-de-elevate": ""
|
|
175
|
-
},
|
|
176
|
-
"ProxyChain": [
|
|
177
|
-
{
|
|
178
|
-
"scheme": config.proxy.protocol,
|
|
179
|
-
"host": config.proxy.host,
|
|
180
|
-
"port": config.proxy.port,
|
|
181
|
-
"account": config.proxy.username,
|
|
182
|
-
"password": config.proxy.password
|
|
183
|
-
}
|
|
184
|
-
],
|
|
185
|
-
"ForceProcessExit": staticConfig.ForceProcessExit,
|
|
186
|
-
"ProxyUser": staticConfig.ProxyUser,
|
|
187
|
-
"ProxyPassword": staticConfig.ProxyPassword,
|
|
188
|
-
"Langs": staticConfig.Langs,
|
|
189
|
-
"AcceptLang": staticConfig.AcceptLang,
|
|
190
|
-
"TimeZone": config.timezone,
|
|
191
|
-
"Geoposition": config.geop,
|
|
192
|
-
"DynamicConfig": dynamicConfig_path,
|
|
193
|
-
"StaticConfig": staticConfig_path
|
|
194
|
-
}));
|
|
195
|
-
|
|
196
|
-
fs.writeFileSync(params_path, params)
|
|
197
|
-
screenSize = staticConfig.ScreenSize;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const args = [
|
|
202
|
-
"--disable-background-networking",
|
|
203
|
-
"--disable-client-side-phishing-detection",
|
|
204
|
-
"--disable-default-apps",
|
|
205
|
-
"--disable-hang-monitor",
|
|
206
|
-
"--disable-popup-blocking",
|
|
207
|
-
"--disable-prompt-on-repost",
|
|
208
|
-
"--disable-sync",
|
|
209
|
-
"--metrics-recording-only",
|
|
210
|
-
"--no-first-run",
|
|
211
|
-
"--safebrowsing-disable-auto-update",
|
|
212
|
-
"--password-store=basic",
|
|
213
|
-
"--no-service-autorun",
|
|
214
|
-
"--disable-features=Translate,AcceptCHFrame,MediaRouter,OptimizationHints,ProcessPerSiteUpToMainFrameThreshold,IsolateSandboxedIframes",
|
|
215
|
-
"--force-color-profile=srgb",
|
|
216
|
-
"--use-mock-keychain",
|
|
217
|
-
"--export-tagged-pdf",
|
|
218
|
-
"--no-default-browser-check",
|
|
219
|
-
"--window-position=0,0",
|
|
220
|
-
"--disable-background-mode",
|
|
221
|
-
"--ash-host-window-bounds=" + screenSize,
|
|
222
|
-
"--window-size=" + screenSize,
|
|
223
|
-
"--disable-renderer-accessibility",
|
|
224
|
-
"--disable-legacy-window",
|
|
225
|
-
"--fake-variations-channel=stable",
|
|
226
|
-
"--variations-server-url=https://clientservices.googleapis.com/chrome-variations/seed",
|
|
227
|
-
"--component-updater=initial-delay=6e5",
|
|
228
|
-
"--lang=en-US",
|
|
229
|
-
"--enable-features=NetworkService,NetworkServiceInProcess,LoadCryptoTokenExtension,PermuteTLSExtensions",
|
|
230
|
-
"--enable-blink-features=IdleDetection,Fledge",
|
|
231
|
-
"--extended-parameters=" + params,
|
|
232
|
-
"--flag-switches-begin",
|
|
233
|
-
"--flag-switches-end",
|
|
234
|
-
"--load-extension=",
|
|
235
|
-
// "--timezone=" + (ipinfo?.timezone ?? "America/Los_Angeles"),
|
|
236
|
-
"--no-sandbox"
|
|
237
|
-
];
|
|
238
|
-
|
|
239
|
-
return {
|
|
240
|
-
args,
|
|
241
|
-
startingUrl: "https://ipapi.co/json/"
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
package/src/providers/base.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { makeUniqueBrowserConfig, getBrowserWebSocketUrl } from "../core/launcher";
|
|
2
|
-
import portfinder from 'portfinder';
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import * as cl from "chrome-launcher";
|
|
5
|
-
import { getIpInfo, startProxyServer, tryCatch, tryLoop, type ProxyServerResult } from "@tocha688/utils";
|
|
6
|
-
import type { BrowserResult, BrowserStartOptions } from "../types";
|
|
7
|
-
import { chromium } from "patchright-core";
|
|
8
|
-
|
|
9
|
-
export interface BrowserLaunchConfig {
|
|
10
|
-
prepare: (userDataDir: string, devtoolsPort: number) => Promise<{
|
|
11
|
-
args: string[];
|
|
12
|
-
startingUrl?: string;
|
|
13
|
-
cleanup?: () => Promise<void>;
|
|
14
|
-
}>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export async function launchBrowserBase(
|
|
21
|
-
opts: BrowserStartOptions,
|
|
22
|
-
config: BrowserLaunchConfig
|
|
23
|
-
): Promise<BrowserResult> {
|
|
24
|
-
const { userDataDir } = makeUniqueBrowserConfig();
|
|
25
|
-
// Ensure userDataDir exists
|
|
26
|
-
fs.mkdirSync(userDataDir, { recursive: true });
|
|
27
|
-
|
|
28
|
-
let hookResult: Awaited<ReturnType<BrowserLaunchConfig['prepare']>> | undefined;
|
|
29
|
-
try {
|
|
30
|
-
const devtoolsPort = await portfinder.getPortPromise({ port: 41000, stopPort: 49999 });
|
|
31
|
-
|
|
32
|
-
hookResult = await config.prepare(userDataDir, devtoolsPort);
|
|
33
|
-
|
|
34
|
-
const args = [
|
|
35
|
-
`--user-data-dir=${userDataDir}`,
|
|
36
|
-
`--remote-debugging-port=${devtoolsPort}`,
|
|
37
|
-
`--remote-debugging-address=0.0.0.0`,
|
|
38
|
-
...hookResult.args
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
// Handle headless option if not already handled by provider
|
|
42
|
-
if (opts.headless !== false && !args.some(a => a.startsWith("--headless"))) {
|
|
43
|
-
args.push("--headless");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const brw = await cl.launch({
|
|
47
|
-
userDataDir,
|
|
48
|
-
port: devtoolsPort,
|
|
49
|
-
chromePath: opts.chromePath,
|
|
50
|
-
chromeFlags: args,
|
|
51
|
-
startingUrl: hookResult.startingUrl || "about:blank"
|
|
52
|
-
});
|
|
53
|
-
const wsUrl = await getBrowserWebSocketUrl(brw.port)
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
userDataDir,
|
|
57
|
-
port: brw.port,
|
|
58
|
-
browser: brw,
|
|
59
|
-
wsUrl,
|
|
60
|
-
close: async () => {
|
|
61
|
-
await tryCatch(async () => await brw.kill());
|
|
62
|
-
if (hookResult?.cleanup) {
|
|
63
|
-
await tryCatch(hookResult.cleanup);
|
|
64
|
-
}
|
|
65
|
-
await tryLoop(async () => fs.rmSync(userDataDir, { recursive: true, force: true }));
|
|
66
|
-
},
|
|
67
|
-
async mainPage() {
|
|
68
|
-
const browser = await chromium.connectOverCDP(wsUrl)
|
|
69
|
-
const ctx = browser.contexts()?.[0] ?? await browser.newContext()
|
|
70
|
-
const page = ctx?.pages()?.[0] ?? await ctx.newPage()
|
|
71
|
-
return page;
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
} catch (e) {
|
|
75
|
-
// cleanup immediately if launch fails
|
|
76
|
-
await tryLoop(async () => fs.rmSync(userDataDir, { recursive: true, force: true }));
|
|
77
|
-
if (hookResult?.cleanup) await tryCatch(hookResult.cleanup);
|
|
78
|
-
throw e;
|
|
79
|
-
}
|
|
80
|
-
}
|
package/src/providers/local.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { BrowserStartOptions, BrowserResult } from "../types";
|
|
2
|
-
import * as cl from "chrome-launcher";
|
|
3
|
-
import { getBrowserWebSocketUrl } from "../core/launcher";
|
|
4
|
-
import { chromium } from "patchright-core";
|
|
5
|
-
|
|
6
|
-
export async function startLocalBrowser(opts: BrowserStartOptions): Promise<BrowserResult> {
|
|
7
|
-
const { chromePath, headless = false, userDataDir } = opts;
|
|
8
|
-
|
|
9
|
-
const chromeFlags = [
|
|
10
|
-
"--disable-blink-features=AutomationControlled",
|
|
11
|
-
"--no-sandbox",
|
|
12
|
-
"--disable-setuid-sandbox",
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
if (headless) {
|
|
16
|
-
chromeFlags.push("--headless");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const browser = await cl.launch({
|
|
20
|
-
chromePath,
|
|
21
|
-
chromeFlags,
|
|
22
|
-
userDataDir,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const wsUrl = await getBrowserWebSocketUrl(browser.port);
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
userDataDir: userDataDir || "",
|
|
29
|
-
port: browser.port,
|
|
30
|
-
browser: browser,
|
|
31
|
-
wsUrl,
|
|
32
|
-
close: async () => await browser.kill(),
|
|
33
|
-
async mainPage() {
|
|
34
|
-
const brw = await chromium.connectOverCDP(wsUrl)
|
|
35
|
-
const ctx = brw.contexts()?.[0] ?? await brw.newContext()
|
|
36
|
-
const page = ctx?.pages()?.[0] ?? await ctx.newPage()
|
|
37
|
-
return page;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
}
|
package/src/providers/ok.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { faker } from "@faker-js/faker";
|
|
2
|
-
import type { BrowserResult, BrowserStartOptions } from "../types";
|
|
3
|
-
import { getIpInfo, startProxyServer, type ProxyServerResult } from "@tocha688/utils";
|
|
4
|
-
import { launchBrowserBase } from "./base";
|
|
5
|
-
import fs from "node:fs";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
|
|
8
|
-
export async function OKBrowserStartMain(opts: BrowserStartOptions): Promise<BrowserResult> {
|
|
9
|
-
return launchBrowserBase(opts, {
|
|
10
|
-
prepare: async (userDataDir, devtoolsPort) => {
|
|
11
|
-
let proxy: ProxyServerResult | undefined;
|
|
12
|
-
if (opts.proxy) {
|
|
13
|
-
proxy = await startProxyServer(opts.proxy);
|
|
14
|
-
console.log(`Started proxy server on port ${proxy.port}`);
|
|
15
|
-
}
|
|
16
|
-
let ipinfo: any = proxy?.ipinfo;
|
|
17
|
-
if (ipinfo) {
|
|
18
|
-
//获取本地IP
|
|
19
|
-
ipinfo = await getIpInfo(ipinfo.proxy);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const fingerprintPath = path.join(userDataDir, "fingerprint.config");
|
|
24
|
-
let fingerprint: string;
|
|
25
|
-
|
|
26
|
-
if (fs.existsSync(fingerprintPath)) {
|
|
27
|
-
fingerprint = fs.readFileSync(fingerprintPath, "utf-8");
|
|
28
|
-
} else {
|
|
29
|
-
fingerprint = faker.number.int({ min: 10000000, max: 99999999 }).toString();
|
|
30
|
-
fs.writeFileSync(fingerprintPath, fingerprint);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const args = [
|
|
34
|
-
"--allow-pre-commit-input",
|
|
35
|
-
"--disable-background-networking",
|
|
36
|
-
"--disable-background-timer-throttling",
|
|
37
|
-
"--disable-backgrounding-occluded-windows",
|
|
38
|
-
"--disable-breakpad",
|
|
39
|
-
"--disable-client-side-phishing-detection",
|
|
40
|
-
"--disable-component-extensions-with-background-pages",
|
|
41
|
-
"--disable-crash-reporter",
|
|
42
|
-
"--disable-default-apps",
|
|
43
|
-
"--disable-dev-shm-usage",
|
|
44
|
-
"--disable-hang-monitor",
|
|
45
|
-
"--disable-infobars",
|
|
46
|
-
"--disable-ipc-flooding-protection",
|
|
47
|
-
"--disable-popup-blocking",
|
|
48
|
-
"--disable-prompt-on-repost",
|
|
49
|
-
"--disable-renderer-backgrounding",
|
|
50
|
-
"--disable-search-engine-choice-screen",
|
|
51
|
-
"--disable-sync",
|
|
52
|
-
"--export-tagged-pdf",
|
|
53
|
-
"--force-color-profile=srgb",
|
|
54
|
-
"--generate-pdf-document-outline",
|
|
55
|
-
"--metrics-recording-only",
|
|
56
|
-
"--no-first-run",
|
|
57
|
-
"--password-store=basic",
|
|
58
|
-
"--use-mock-keychain",
|
|
59
|
-
"--disable-features=Translate,AcceptCHFrame,MediaRouter,OptimizationHints,ProcessPerSiteUpToMainFrameThreshold,IsolateSandboxedIframes",
|
|
60
|
-
"--enable-features=PdfOopif",
|
|
61
|
-
// "--user-data-dir=" + userDataDir, // Handled by base
|
|
62
|
-
// "about:blank",
|
|
63
|
-
// "http://127.0.0.1:4252/index.html?id=1977283458602381314",
|
|
64
|
-
// "--fingerprints=37553310",
|
|
65
|
-
"--fingerprints=" + fingerprint,
|
|
66
|
-
"--window-size=1280,720",
|
|
67
|
-
"--window-position=0,0",
|
|
68
|
-
"--no-sandbox",
|
|
69
|
-
// "--disable-blink-features=AutomationControlled",
|
|
70
|
-
"--ignore-certificate-errors",
|
|
71
|
-
"--notice-number=1",
|
|
72
|
-
// "--notice-number=4",
|
|
73
|
-
// "--load-extension=",
|
|
74
|
-
// "--remote-debugging-port=" + devtoolsPort, // Handled by base
|
|
75
|
-
// "--remote-debugging-address=0.0.0.0", // Handled by base
|
|
76
|
-
// "--enable-password-manager",
|
|
77
|
-
"--ignores=tls",
|
|
78
|
-
"--enable-logging",
|
|
79
|
-
// "--proxy-server=http://127.0.0.1:" + proxy.port,
|
|
80
|
-
"--timezone=" + (ipinfo?.timezone ?? "America/Los_Angeles"),
|
|
81
|
-
"--lang=en-US",
|
|
82
|
-
// "--headless", // Handled by base
|
|
83
|
-
];
|
|
84
|
-
|
|
85
|
-
if (proxy && proxy.port) {
|
|
86
|
-
args.push(`--proxy-server=http://127.0.0.1:${proxy.port}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
args,
|
|
91
|
-
startingUrl: "https://ipapi.co/json/",
|
|
92
|
-
cleanup: async () => {
|
|
93
|
-
if (proxy) await proxy.server.close(true);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export async function OKBrowserCreate(opts: BrowserStartOptions) {
|
|
101
|
-
return OKBrowserStartMain(opts);
|
|
102
|
-
}
|
package/src/types/index.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { ProxyFormatInfo } from "@tocha688/utils/ip";
|
|
2
|
-
import * as cl from "chrome-launcher"
|
|
3
|
-
import type { Page } from "patchright-core";
|
|
4
|
-
import * as ProxyChain from "proxy-chain";
|
|
5
|
-
|
|
6
|
-
// 使用方式
|
|
7
|
-
export type BrowserStartOptions = {
|
|
8
|
-
proxy?: string,
|
|
9
|
-
headless?: boolean,
|
|
10
|
-
chromePath: string,
|
|
11
|
-
userDataDir?: string;
|
|
12
|
-
}
|
|
13
|
-
export type BrowserResult = {
|
|
14
|
-
userDataDir: string,
|
|
15
|
-
port: number,
|
|
16
|
-
browser: cl.LaunchedChrome,
|
|
17
|
-
close: Function,
|
|
18
|
-
wsUrl: string,
|
|
19
|
-
mainPage:()=>Promise<Page>
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type StartBrowserFn = (opts: BrowserStartOptions) => Promise<BrowserResult>;
|
|
23
|
-
|
|
24
|
-
export type ProxyServerResult = { port: number, server: ProxyChain.Server, ipinfo: any }
|
package/tsconfig.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// Environment setup & latest features
|
|
4
|
-
"lib": ["ESNext"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"module": "Preserve",
|
|
7
|
-
"moduleDetection": "force",
|
|
8
|
-
"jsx": "react-jsx",
|
|
9
|
-
"allowJs": true,
|
|
10
|
-
|
|
11
|
-
// Bundler mode
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"allowImportingTsExtensions": true,
|
|
14
|
-
"verbatimModuleSyntax": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
|
|
17
|
-
// Best practices
|
|
18
|
-
"strict": true,
|
|
19
|
-
"skipLibCheck": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"noUncheckedIndexedAccess": true,
|
|
22
|
-
"noImplicitOverride": true,
|
|
23
|
-
|
|
24
|
-
// Some stricter flags (disabled by default)
|
|
25
|
-
"noUnusedLocals": false,
|
|
26
|
-
"noUnusedParameters": false,
|
|
27
|
-
"noPropertyAccessFromIndexSignature": false
|
|
28
|
-
}
|
|
29
|
-
}
|
package/tsup.config.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'tsup';
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
entry: ['src/index.ts'],
|
|
5
|
-
format: ['cjs', 'esm'],
|
|
6
|
-
clean: true,
|
|
7
|
-
minify: true,
|
|
8
|
-
shims: true,
|
|
9
|
-
dts: true,
|
|
10
|
-
splitting: false,
|
|
11
|
-
sourcemap: false,
|
|
12
|
-
platform: 'node',
|
|
13
|
-
target: 'esnext',
|
|
14
|
-
});
|