@webcrawlerapi/stealth 1.0.0 → 1.0.1
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/README.md +1 -0
- package/package.json +1 -1
- package/stealth.d.ts +5 -0
- package/stealth.js +35 -1
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ The two functions you normally need are:
|
|
|
30
30
|
| `matchMedia` pointer / hover | normalized |
|
|
31
31
|
| `window.outerWidth` / `outerHeight` | corrected to inner + chrome |
|
|
32
32
|
| `Error.prepareStackTrace` | installed if absent |
|
|
33
|
+
| `User-Agent` header + `navigator.userAgent` (`HeadlessChrome` token) | read from `browser.userAgent()` and `HeadlessChrome` → `Chrome` via `page.setUserAgent`; never hardcoded, so the version always matches the real engine. Skip with `fixUserAgent: false`, or pass `userAgent` |
|
|
33
34
|
|
|
34
35
|
---
|
|
35
36
|
|
package/package.json
CHANGED
package/stealth.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export interface StealthOptions {
|
|
|
19
19
|
userDataDir?: string;
|
|
20
20
|
/** Launch only: extra chrome args. */
|
|
21
21
|
args?: string[];
|
|
22
|
+
/** Explicit User-Agent for the page. Default: browser UA with "HeadlessChrome" replaced by "Chrome". */
|
|
23
|
+
userAgent?: string;
|
|
24
|
+
/** Set to false to skip the User-Agent fix. Default true. */
|
|
25
|
+
fixUserAgent?: boolean;
|
|
22
26
|
/** newPage only: origin for overridePermissions. */
|
|
23
27
|
origin?: string;
|
|
24
28
|
/** newPage only: permissions to grant. */
|
|
@@ -47,6 +51,7 @@ export declare const UA: string;
|
|
|
47
51
|
export declare function buildInitScript(cfg?: StealthOptions): void;
|
|
48
52
|
export declare function buildSource(opts?: StealthOptions): string;
|
|
49
53
|
export declare function installStealth(page: PageLike, opts?: StealthOptions): Promise<PageLike>;
|
|
54
|
+
export declare function fixUserAgent(page: PageLike, opts?: StealthOptions): Promise<PageLike>;
|
|
50
55
|
export declare function injectNow(page: PageLike, opts?: StealthOptions): Promise<PageLike>;
|
|
51
56
|
export declare function installOopifHook(browser: BrowserLike, opts?: StealthOptions): BrowserLike;
|
|
52
57
|
export declare function newPage(browser: BrowserLike, opts?: StealthOptions): Promise<PageLike>;
|
package/stealth.js
CHANGED
|
@@ -21,7 +21,7 @@ const UA =
|
|
|
21
21
|
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ' +
|
|
22
22
|
'(KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36';
|
|
23
23
|
|
|
24
|
-
const VERSION = '1.0.
|
|
24
|
+
const VERSION = '1.0.1';
|
|
25
25
|
|
|
26
26
|
const DEFAULT_RENDERER =
|
|
27
27
|
'ANGLE (Intel, Intel(R) UHD Graphics 630 (0x00003E9B) Direct3D11 vs_5_0 ps_5_0, D3D11)';
|
|
@@ -352,10 +352,43 @@ async function installStealth(page, opts) {
|
|
|
352
352
|
opts = opts || {};
|
|
353
353
|
const cfg = resolveConfig(opts);
|
|
354
354
|
await page.evaluateOnNewDocument(buildInitScript, cfg);
|
|
355
|
+
await fixUserAgent(page, opts);
|
|
355
356
|
try { page[INSTALLED] = true; } catch (_) {}
|
|
356
357
|
return page;
|
|
357
358
|
}
|
|
358
359
|
|
|
360
|
+
/**
|
|
361
|
+
* Headless Chrome announces itself as "HeadlessChrome/<ver>" in both the
|
|
362
|
+
* `User-Agent` request header and navigator.userAgent. The header is set by the
|
|
363
|
+
* network stack, so the in-page patches can't touch it; it has to go through
|
|
364
|
+
* the CDP UA override (page.setUserAgent).
|
|
365
|
+
*
|
|
366
|
+
* The UA is read from the running browser (browser.userAgent()) instead of
|
|
367
|
+
* being hardcoded, so the Chrome version always matches the real engine and
|
|
368
|
+
* never goes stale when the bundled Chrome is upgraded.
|
|
369
|
+
*
|
|
370
|
+
* opts.userAgent explicit UA, used as is
|
|
371
|
+
* opts.fixUserAgent set to false to skip
|
|
372
|
+
*
|
|
373
|
+
* No-op when the browser UA has no "HeadlessChrome" token (headful, connect()).
|
|
374
|
+
*/
|
|
375
|
+
async function fixUserAgent(page, opts) {
|
|
376
|
+
opts = opts || {};
|
|
377
|
+
if (opts.fixUserAgent === false || typeof page.setUserAgent !== 'function') return page;
|
|
378
|
+
try {
|
|
379
|
+
let ua = opts.userAgent;
|
|
380
|
+
if (!ua) {
|
|
381
|
+
const browser = typeof page.browser === 'function' ? page.browser() : null;
|
|
382
|
+
if (!browser || typeof browser.userAgent !== 'function') return page;
|
|
383
|
+
const current = await browser.userAgent();
|
|
384
|
+
if (!/HeadlessChrome/.test(current)) return page;
|
|
385
|
+
ua = current.replace('HeadlessChrome', 'Chrome');
|
|
386
|
+
}
|
|
387
|
+
await page.setUserAgent(ua);
|
|
388
|
+
} catch (_) {}
|
|
389
|
+
return page;
|
|
390
|
+
}
|
|
391
|
+
|
|
359
392
|
/**
|
|
360
393
|
* Also inject the bootstrap into documents that are ALREADY loaded (useful when
|
|
361
394
|
* you attach with connect() to a page that is already on the target URL).
|
|
@@ -468,6 +501,7 @@ module.exports = {
|
|
|
468
501
|
buildInitScript,
|
|
469
502
|
buildSource,
|
|
470
503
|
installStealth,
|
|
504
|
+
fixUserAgent,
|
|
471
505
|
injectNow,
|
|
472
506
|
installOopifHook,
|
|
473
507
|
newPage,
|