@purepageio/fetch-engines 0.1.0
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/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/FetchEngine.d.ts +46 -0
- package/dist/FetchEngine.d.ts.map +1 -0
- package/dist/FetchEngine.js +137 -0
- package/dist/FetchEngine.js.map +1 -0
- package/dist/FetchEngine.test.d.ts +2 -0
- package/dist/FetchEngine.test.d.ts.map +1 -0
- package/dist/FetchEngine.test.js +44 -0
- package/dist/FetchEngine.test.js.map +1 -0
- package/dist/HybridEngine.d.ts +15 -0
- package/dist/HybridEngine.d.ts.map +1 -0
- package/dist/HybridEngine.js +45 -0
- package/dist/HybridEngine.js.map +1 -0
- package/dist/IEngine.d.ts +22 -0
- package/dist/IEngine.d.ts.map +1 -0
- package/dist/IEngine.js +2 -0
- package/dist/IEngine.js.map +1 -0
- package/dist/PlaywrightEngine.d.ts +88 -0
- package/dist/PlaywrightEngine.d.ts.map +1 -0
- package/dist/PlaywrightEngine.js +484 -0
- package/dist/PlaywrightEngine.js.map +1 -0
- package/dist/PlaywrightEngine.test.d.ts +2 -0
- package/dist/PlaywrightEngine.test.d.ts.map +1 -0
- package/dist/PlaywrightEngine.test.js +299 -0
- package/dist/PlaywrightEngine.test.js.map +1 -0
- package/dist/PuppeteerEngine.d.ts +21 -0
- package/dist/PuppeteerEngine.d.ts.map +1 -0
- package/dist/PuppeteerEngine.js +412 -0
- package/dist/PuppeteerEngine.js.map +1 -0
- package/dist/browser/BrowserPool.d.ts +29 -0
- package/dist/browser/BrowserPool.d.ts.map +1 -0
- package/dist/browser/BrowserPool.js +378 -0
- package/dist/browser/BrowserPool.js.map +1 -0
- package/dist/browser/PlaywrightBrowserPool.d.ts +78 -0
- package/dist/browser/PlaywrightBrowserPool.d.ts.map +1 -0
- package/dist/browser/PlaywrightBrowserPool.js +429 -0
- package/dist/browser/PlaywrightBrowserPool.js.map +1 -0
- package/dist/browser/PlaywrightBrowserPool.test.d.ts +2 -0
- package/dist/browser/PlaywrightBrowserPool.test.d.ts.map +1 -0
- package/dist/browser/PlaywrightBrowserPool.test.js +422 -0
- package/dist/browser/PlaywrightBrowserPool.test.js.map +1 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +151 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { HTMLFetchResult, BrowserMetrics, PlaywrightEngineConfig, FetchOptions } from "./types.js";
|
|
2
|
+
import type { IEngine } from "./IEngine.js";
|
|
3
|
+
/**
|
|
4
|
+
* PlaywrightEngine - Fetches HTML using a managed pool of headless Playwright browser instances.
|
|
5
|
+
*
|
|
6
|
+
* This engine is suitable for dynamic websites that require JavaScript execution.
|
|
7
|
+
* It incorporates `playwright-extra` with the stealth plugin for enhanced anti-detection capabilities.
|
|
8
|
+
* Features include caching, retries, HTTP fallback, and configurable browser pooling.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PlaywrightEngine implements IEngine {
|
|
11
|
+
private browserPool;
|
|
12
|
+
private readonly queue;
|
|
13
|
+
private readonly cache;
|
|
14
|
+
private readonly config;
|
|
15
|
+
private initializingBrowserPool;
|
|
16
|
+
private isUsingHeadedMode;
|
|
17
|
+
private headedFallbackSites;
|
|
18
|
+
private static readonly DEFAULT_CONFIG;
|
|
19
|
+
/**
|
|
20
|
+
* Creates an instance of PlaywrightEngine.
|
|
21
|
+
*
|
|
22
|
+
* @param config Configuration options for the engine and its browser pool.
|
|
23
|
+
* See `PlaywrightEngineConfig` for details.
|
|
24
|
+
*/
|
|
25
|
+
constructor(config?: PlaywrightEngineConfig);
|
|
26
|
+
/**
|
|
27
|
+
* Initialize the browser pool with improved error handling and mode switching.
|
|
28
|
+
*/
|
|
29
|
+
private initializeBrowserPool;
|
|
30
|
+
/**
|
|
31
|
+
* Fallback method using simple HTTP requests via Axios.
|
|
32
|
+
* Ensures return type matches HTMLFetchResult.
|
|
33
|
+
*/
|
|
34
|
+
private fetchHTMLWithHttpFallback;
|
|
35
|
+
private checkCache;
|
|
36
|
+
/**
|
|
37
|
+
* Safely check if a page is still usable and connected.
|
|
38
|
+
*/
|
|
39
|
+
private isPageValid;
|
|
40
|
+
/**
|
|
41
|
+
* Simulate human-like interactions on the page.
|
|
42
|
+
*/
|
|
43
|
+
private simulateHumanBehavior;
|
|
44
|
+
/**
|
|
45
|
+
* Adds a result to the in-memory cache.
|
|
46
|
+
*/
|
|
47
|
+
private addToCache;
|
|
48
|
+
/**
|
|
49
|
+
* Public method to fetch HTML. Delegates to the internal recursive fetch method.
|
|
50
|
+
*
|
|
51
|
+
* @param url The URL to fetch.
|
|
52
|
+
* @param options Optional settings for this specific fetch operation.
|
|
53
|
+
* @param options.fastMode Overrides the engine's `defaultFastMode` configuration for this request.
|
|
54
|
+
* @returns A Promise resolving to an HTMLFetchResult object.
|
|
55
|
+
* @throws {FetchError} If the fetch fails after all retries or encounters critical errors.
|
|
56
|
+
*/
|
|
57
|
+
fetchHTML(url: string, options?: FetchOptions): Promise<HTMLFetchResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Internal recursive method to handle fetching with retries.
|
|
60
|
+
*
|
|
61
|
+
* @param url URL to fetch
|
|
62
|
+
* @param options Original fetch options (e.g., fastMode override)
|
|
63
|
+
* @param retryAttempt Current retry attempt number (starts at 0)
|
|
64
|
+
* @param parentRetryCount Tracks retries related to pool initialization errors (starts at 0)
|
|
65
|
+
* @returns Promise resolving to HTMLFetchResult
|
|
66
|
+
*/
|
|
67
|
+
private _fetchRecursive;
|
|
68
|
+
/**
|
|
69
|
+
* Performs the actual page fetch using a Playwright page from the pool.
|
|
70
|
+
* Ensures return type matches HTMLFetchResult.
|
|
71
|
+
*/
|
|
72
|
+
private fetchWithPlaywright;
|
|
73
|
+
private applyBlockingRules;
|
|
74
|
+
/**
|
|
75
|
+
* Cleans up resources used by the engine, primarily closing browser instances in the pool.
|
|
76
|
+
*
|
|
77
|
+
* It is crucial to call this method when finished with the engine instance to release resources.
|
|
78
|
+
* @returns A Promise that resolves when cleanup is complete.
|
|
79
|
+
*/
|
|
80
|
+
cleanup(): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Retrieves metrics from the underlying browser pool.
|
|
83
|
+
* @returns An array of BrowserMetrics objects, one for each active browser instance, or an empty array if the pool is not initialized.
|
|
84
|
+
*/
|
|
85
|
+
getMetrics(): BrowserMetrics[];
|
|
86
|
+
private shouldUseHeadedMode;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=PlaywrightEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightEngine.d.ts","sourceRoot":"","sources":["../src/PlaywrightEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,YAAY,EACb,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAsB5C;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAIE;IAGzB,OAAO,CAAC,uBAAuB,CAAkB;IACjD,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,mBAAmB,CAA0B;IAGrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAoBpC;IAEF;;;;;OAKG;gBACS,MAAM,GAAE,sBAA2B;IAmB/C;;OAEG;YACW,qBAAqB;IAoDnC;;;OAGG;YACW,yBAAyB;IAyEvC,OAAO,CAAC,UAAU;IAWlB;;OAEG;YACW,WAAW;IAazB;;OAEG;YACW,qBAAqB;IAyCnC;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB;;;;;;;;OAQG;IACG,SAAS,CACb,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,eAAe,CAAC;IAK3B;;;;;;;;OAQG;YACW,eAAe;IAgJ7B;;;OAGG;YACW,mBAAmB;YA0EnB,kBAAkB;IA6ChC;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B;;;OAGG;IACH,UAAU,IAAI,cAAc,EAAE;IAQ9B,OAAO,CAAC,mBAAmB;CAS5B"}
|
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import { PlaywrightBrowserPool } from "./browser/PlaywrightBrowserPool.js";
|
|
2
|
+
import PQueue from "p-queue";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import { FetchError } from "./errors.js"; // Import FetchError
|
|
5
|
+
function delay(time) {
|
|
6
|
+
// Added return type
|
|
7
|
+
return new Promise((resolve) => setTimeout(resolve, time));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* PlaywrightEngine - Fetches HTML using a managed pool of headless Playwright browser instances.
|
|
11
|
+
*
|
|
12
|
+
* This engine is suitable for dynamic websites that require JavaScript execution.
|
|
13
|
+
* It incorporates `playwright-extra` with the stealth plugin for enhanced anti-detection capabilities.
|
|
14
|
+
* Features include caching, retries, HTTP fallback, and configurable browser pooling.
|
|
15
|
+
*/
|
|
16
|
+
export class PlaywrightEngine {
|
|
17
|
+
browserPool = null;
|
|
18
|
+
queue;
|
|
19
|
+
cache = new Map();
|
|
20
|
+
config;
|
|
21
|
+
// Browser pooling safety flags
|
|
22
|
+
initializingBrowserPool = false;
|
|
23
|
+
isUsingHeadedMode = false; // Tracks current pool mode
|
|
24
|
+
headedFallbackSites = new Set(); // Stores domains marked for headed mode
|
|
25
|
+
// Default configuration - Ensure all required fields are present
|
|
26
|
+
static DEFAULT_CONFIG = {
|
|
27
|
+
concurrentPages: 3,
|
|
28
|
+
maxRetries: 3,
|
|
29
|
+
retryDelay: 5000,
|
|
30
|
+
cacheTTL: 15 * 60 * 1000,
|
|
31
|
+
useHttpFallback: true,
|
|
32
|
+
useHeadedModeFallback: false,
|
|
33
|
+
defaultFastMode: true,
|
|
34
|
+
simulateHumanBehavior: true,
|
|
35
|
+
maxBrowsers: 2,
|
|
36
|
+
maxPagesPerContext: 6,
|
|
37
|
+
maxBrowserAge: 20 * 60 * 1000,
|
|
38
|
+
healthCheckInterval: 60 * 1000,
|
|
39
|
+
poolBlockedDomains: [],
|
|
40
|
+
poolBlockedResourceTypes: [],
|
|
41
|
+
proxy: undefined,
|
|
42
|
+
useHeadedMode: false, // ADDED default
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Creates an instance of PlaywrightEngine.
|
|
46
|
+
*
|
|
47
|
+
* @param config Configuration options for the engine and its browser pool.
|
|
48
|
+
* See `PlaywrightEngineConfig` for details.
|
|
49
|
+
*/
|
|
50
|
+
constructor(config = {}) {
|
|
51
|
+
// Merge provided config with defaults
|
|
52
|
+
const mergedConfig = { ...PlaywrightEngine.DEFAULT_CONFIG, ...config };
|
|
53
|
+
// Remove the obsolete stealth keys if they were passed in config
|
|
54
|
+
delete mergedConfig.useStealthMode;
|
|
55
|
+
delete mergedConfig.randomizeFingerprint;
|
|
56
|
+
delete mergedConfig.evasionLevel;
|
|
57
|
+
// Assign cleaned config - type should now match
|
|
58
|
+
this.config = mergedConfig;
|
|
59
|
+
this.queue = new PQueue({ concurrency: this.config.concurrentPages });
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Initialize the browser pool with improved error handling and mode switching.
|
|
63
|
+
*/
|
|
64
|
+
async initializeBrowserPool(useHeadedMode = false) {
|
|
65
|
+
// Check if pool exists and is in the correct mode
|
|
66
|
+
if (this.browserPool && this.isUsingHeadedMode === useHeadedMode) {
|
|
67
|
+
return; // Already initialized in the correct mode
|
|
68
|
+
}
|
|
69
|
+
// Prevent concurrent initialization attempts
|
|
70
|
+
if (this.initializingBrowserPool) {
|
|
71
|
+
while (this.initializingBrowserPool) {
|
|
72
|
+
await delay(100);
|
|
73
|
+
}
|
|
74
|
+
// Re-check if the pool is now in the correct state after waiting
|
|
75
|
+
if (this.browserPool && this.isUsingHeadedMode === useHeadedMode) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// If still not correct, proceed with initialization (the other process might have failed)
|
|
79
|
+
}
|
|
80
|
+
this.initializingBrowserPool = true;
|
|
81
|
+
try {
|
|
82
|
+
// If pool exists but is in the wrong mode, clean it up first
|
|
83
|
+
if (this.browserPool && this.isUsingHeadedMode !== useHeadedMode) {
|
|
84
|
+
await this.browserPool.cleanup();
|
|
85
|
+
this.browserPool = null;
|
|
86
|
+
}
|
|
87
|
+
this.isUsingHeadedMode = useHeadedMode; // Set the mode *before* creating the pool
|
|
88
|
+
this.browserPool = new PlaywrightBrowserPool({
|
|
89
|
+
maxBrowsers: this.config.maxBrowsers,
|
|
90
|
+
maxPagesPerContext: this.config.maxPagesPerContext,
|
|
91
|
+
maxBrowserAge: this.config.maxBrowserAge,
|
|
92
|
+
healthCheckInterval: this.config.healthCheckInterval,
|
|
93
|
+
useHeadedMode: useHeadedMode,
|
|
94
|
+
// Pass through blocking config
|
|
95
|
+
blockedDomains: this.config.poolBlockedDomains, // Pass from engine config
|
|
96
|
+
blockedResourceTypes: this.config.poolBlockedResourceTypes, // Pass from engine config
|
|
97
|
+
});
|
|
98
|
+
await this.browserPool.initialize();
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.browserPool = null; // Ensure pool is null on failure
|
|
102
|
+
this.isUsingHeadedMode = false; // Reset mode state on failure
|
|
103
|
+
throw error; // Re-throw error
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
this.initializingBrowserPool = false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Fallback method using simple HTTP requests via Axios.
|
|
111
|
+
* Ensures return type matches HTMLFetchResult.
|
|
112
|
+
*/
|
|
113
|
+
async fetchHTMLWithHttpFallback(url) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await axios.get(url, {
|
|
116
|
+
headers: {
|
|
117
|
+
// Use more standard browser-like headers
|
|
118
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
|
|
119
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
|
120
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
121
|
+
"Accept-Encoding": "gzip, deflate, br", // Allow compression
|
|
122
|
+
Referer: "https://www.google.com/", // Common referer
|
|
123
|
+
"Upgrade-Insecure-Requests": "1",
|
|
124
|
+
"Sec-Ch-Ua": '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"',
|
|
125
|
+
"Sec-Ch-Ua-Mobile": "?0",
|
|
126
|
+
"Sec-Ch-Ua-Platform": '"Windows"',
|
|
127
|
+
"Sec-Fetch-Dest": "document",
|
|
128
|
+
"Sec-Fetch-Mode": "navigate",
|
|
129
|
+
"Sec-Fetch-Site": "cross-site",
|
|
130
|
+
"Sec-Fetch-User": "?1",
|
|
131
|
+
Connection: "keep-alive", // Keep connection open
|
|
132
|
+
// Avoid Cache-Control/Pragma unless specifically needed
|
|
133
|
+
},
|
|
134
|
+
maxRedirects: 5,
|
|
135
|
+
timeout: 30000,
|
|
136
|
+
responseType: "text",
|
|
137
|
+
// Decompress response automatically
|
|
138
|
+
decompress: true,
|
|
139
|
+
});
|
|
140
|
+
// Extract title using regex (less robust than DOM parsing)
|
|
141
|
+
const titleMatch = response.data.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
142
|
+
const title = titleMatch ? titleMatch[1].trim() : "";
|
|
143
|
+
// Basic check for challenge pages
|
|
144
|
+
const lowerHtml = response.data.toLowerCase();
|
|
145
|
+
const isChallengeOrBot = /cloudflare|checking your browser|please wait|verification|captcha|attention required/i.test(lowerHtml);
|
|
146
|
+
if (isChallengeOrBot) {
|
|
147
|
+
// Throw specific error code for easier handling upstream
|
|
148
|
+
throw new FetchError("Received challenge page via HTTP fallback", "ERR_CHALLENGE_PAGE");
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
html: response.data,
|
|
152
|
+
title: title,
|
|
153
|
+
url: response.request?.res?.responseUrl || response.config.url || url,
|
|
154
|
+
isFromCache: false, // ADDED
|
|
155
|
+
statusCode: response.status, // ADDED
|
|
156
|
+
error: undefined, // ADDED
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
// Wrap non-FetchErrors
|
|
161
|
+
if (!(error instanceof FetchError)) {
|
|
162
|
+
throw new FetchError(`HTTP fallback failed: ${error.message}`, "ERR_HTTP_FALLBACK_FAILED", error);
|
|
163
|
+
}
|
|
164
|
+
throw error; // Re-throw FetchError or other wrapped errors
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
checkCache(url) {
|
|
168
|
+
const cached = this.cache.get(url);
|
|
169
|
+
if (cached && Date.now() - cached.timestamp < this.config.cacheTTL) {
|
|
170
|
+
return cached.result;
|
|
171
|
+
}
|
|
172
|
+
if (cached) {
|
|
173
|
+
this.cache.delete(url); // Explicitly delete expired entry
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Safely check if a page is still usable and connected.
|
|
179
|
+
*/
|
|
180
|
+
async isPageValid(page) {
|
|
181
|
+
if (!page || page.isClosed())
|
|
182
|
+
return false;
|
|
183
|
+
try {
|
|
184
|
+
// Check connection status
|
|
185
|
+
if (!page.context().browser()?.isConnected())
|
|
186
|
+
return false;
|
|
187
|
+
// Try a simple operation that throws if the page is crashed/detached
|
|
188
|
+
await page.evaluate("1 + 1", { timeout: 1000 });
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Simulate human-like interactions on the page.
|
|
197
|
+
*/
|
|
198
|
+
async simulateHumanBehavior(page) {
|
|
199
|
+
if (!(await this.isPageValid(page)))
|
|
200
|
+
return;
|
|
201
|
+
try {
|
|
202
|
+
const viewport = page.viewportSize();
|
|
203
|
+
if (!viewport)
|
|
204
|
+
return;
|
|
205
|
+
// Gentle mouse movements
|
|
206
|
+
await page.mouse.move(Math.random() * viewport.width, (Math.random() * viewport.height) / 3, { steps: 5 });
|
|
207
|
+
await delay(150 + Math.random() * 200);
|
|
208
|
+
await page.mouse.move(Math.random() * viewport.width, viewport.height / 2 + (Math.random() * viewport.height) / 2, { steps: 10 });
|
|
209
|
+
await delay(200 + Math.random() * 300);
|
|
210
|
+
// Gentle scrolling
|
|
211
|
+
await page.evaluate(() => {
|
|
212
|
+
window.scrollBy({
|
|
213
|
+
top: window.innerHeight * (0.3 + Math.random() * 0.4),
|
|
214
|
+
behavior: "smooth",
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
await delay(400 + Math.random() * 600);
|
|
218
|
+
await page.evaluate(() => {
|
|
219
|
+
window.scrollBy({
|
|
220
|
+
top: window.innerHeight * (0.2 + Math.random() * 0.3),
|
|
221
|
+
behavior: "smooth",
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
await delay(300 + Math.random() * 400);
|
|
225
|
+
}
|
|
226
|
+
catch (_error) {
|
|
227
|
+
/* Ignore errors during simulation */
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Adds a result to the in-memory cache.
|
|
232
|
+
*/
|
|
233
|
+
addToCache(url, result) {
|
|
234
|
+
if (this.config.cacheTTL <= 0)
|
|
235
|
+
return; // Don't cache if TTL is zero or negative
|
|
236
|
+
const entry = {
|
|
237
|
+
result: { ...result, isFromCache: true }, // Mark as cached
|
|
238
|
+
timestamp: Date.now(),
|
|
239
|
+
};
|
|
240
|
+
this.cache.set(url, entry);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Public method to fetch HTML. Delegates to the internal recursive fetch method.
|
|
244
|
+
*
|
|
245
|
+
* @param url The URL to fetch.
|
|
246
|
+
* @param options Optional settings for this specific fetch operation.
|
|
247
|
+
* @param options.fastMode Overrides the engine's `defaultFastMode` configuration for this request.
|
|
248
|
+
* @returns A Promise resolving to an HTMLFetchResult object.
|
|
249
|
+
* @throws {FetchError} If the fetch fails after all retries or encounters critical errors.
|
|
250
|
+
*/
|
|
251
|
+
async fetchHTML(url, options = {}) {
|
|
252
|
+
// Start the recursive fetch process with initial retry counts
|
|
253
|
+
return this._fetchRecursive(url, options, 0, 0);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Internal recursive method to handle fetching with retries.
|
|
257
|
+
*
|
|
258
|
+
* @param url URL to fetch
|
|
259
|
+
* @param options Original fetch options (e.g., fastMode override)
|
|
260
|
+
* @param retryAttempt Current retry attempt number (starts at 0)
|
|
261
|
+
* @param parentRetryCount Tracks retries related to pool initialization errors (starts at 0)
|
|
262
|
+
* @returns Promise resolving to HTMLFetchResult
|
|
263
|
+
*/
|
|
264
|
+
async _fetchRecursive(url, options, retryAttempt, parentRetryCount) {
|
|
265
|
+
const useFastMode = options.fastMode === undefined
|
|
266
|
+
? this.config.defaultFastMode
|
|
267
|
+
: options.fastMode;
|
|
268
|
+
// Check cache first
|
|
269
|
+
if (retryAttempt === 0 && parentRetryCount === 0) {
|
|
270
|
+
// Only check cache on the very first try
|
|
271
|
+
const cachedResult = this.checkCache(url);
|
|
272
|
+
if (cachedResult) {
|
|
273
|
+
return cachedResult;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
// Try HTTP fallback first if enabled and it's the first attempt
|
|
278
|
+
if (this.config.useHttpFallback &&
|
|
279
|
+
retryAttempt === 0 &&
|
|
280
|
+
parentRetryCount === 0) {
|
|
281
|
+
try {
|
|
282
|
+
const httpResult = await this.fetchHTMLWithHttpFallback(url);
|
|
283
|
+
// Cache successful HTTP fallback result if caching is enabled
|
|
284
|
+
if (this.config.cacheTTL > 0) {
|
|
285
|
+
this.addToCache(url, httpResult);
|
|
286
|
+
}
|
|
287
|
+
return httpResult;
|
|
288
|
+
}
|
|
289
|
+
catch (_httpError) {
|
|
290
|
+
if (_httpError instanceof FetchError &&
|
|
291
|
+
_httpError.code === "ERR_CHALLENGE_PAGE") {
|
|
292
|
+
// Challenge page detected, proceed to Playwright
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
// Other HTTP error, re-throw (will be caught below)
|
|
296
|
+
throw _httpError;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Determine if headed mode should be used for this attempt
|
|
301
|
+
const useHeadedMode = (this.config.useHeadedModeFallback &&
|
|
302
|
+
(retryAttempt >= 2 || this.shouldUseHeadedMode(url))) ||
|
|
303
|
+
this.config.useHeadedMode;
|
|
304
|
+
// Ensure pool is initialized in the correct mode (headed/headless)
|
|
305
|
+
try {
|
|
306
|
+
if (!this.browserPool || this.isUsingHeadedMode !== useHeadedMode) {
|
|
307
|
+
await this.initializeBrowserPool(useHeadedMode);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
catch (initError) {
|
|
311
|
+
// If pool init fails, retry the entire fetchHTML call (limited times)
|
|
312
|
+
if (parentRetryCount < 1) {
|
|
313
|
+
await delay(this.config.retryDelay);
|
|
314
|
+
// Retry the recursive call, incrementing parentRetryCount
|
|
315
|
+
return this._fetchRecursive(url, options, retryAttempt, parentRetryCount + 1);
|
|
316
|
+
}
|
|
317
|
+
throw new FetchError(`Browser pool initialization failed: ${initError.message}`, "ERR_POOL_INIT_FAILED", initError);
|
|
318
|
+
}
|
|
319
|
+
// If pool still isn't available after potential init, throw.
|
|
320
|
+
if (!this.browserPool) {
|
|
321
|
+
throw new FetchError("Browser pool is not available.", "ERR_POOL_UNAVAILABLE");
|
|
322
|
+
}
|
|
323
|
+
// Execute the actual Playwright fetch within the queue
|
|
324
|
+
const result = await this.queue.add(() => this.fetchWithPlaywright(url, this.browserPool, useFastMode));
|
|
325
|
+
// Cache successful Playwright result if caching is enabled
|
|
326
|
+
if (result && this.config.cacheTTL > 0) {
|
|
327
|
+
this.addToCache(url, result);
|
|
328
|
+
}
|
|
329
|
+
// Need to ensure we return HTMLFetchResult or throw
|
|
330
|
+
if (!result) {
|
|
331
|
+
throw new FetchError("Playwright fetch did not return a result from the queue.", "ERR_QUEUE_NO_RESULT");
|
|
332
|
+
}
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
// Handle retry logic based on the error
|
|
337
|
+
// 1. If in fast mode and this was the first *Playwright* attempt, retry in thorough mode immediately.
|
|
338
|
+
// (Check parentRetryCount ensures this wasn't a pool init retry)
|
|
339
|
+
if (useFastMode && retryAttempt === 0 && parentRetryCount === 0) {
|
|
340
|
+
return this._fetchRecursive(url, { ...options, fastMode: false }, 0, parentRetryCount);
|
|
341
|
+
}
|
|
342
|
+
// 2. If retries are left, delay and retry with the *same* mode settings.
|
|
343
|
+
if (retryAttempt < this.config.maxRetries) {
|
|
344
|
+
await delay(this.config.retryDelay);
|
|
345
|
+
// Pass the original options and increment retryAttempt
|
|
346
|
+
return this._fetchRecursive(url, options, retryAttempt + 1, parentRetryCount);
|
|
347
|
+
}
|
|
348
|
+
// 3. Max retries exhausted, throw final error
|
|
349
|
+
const fetchError = error instanceof FetchError
|
|
350
|
+
? error
|
|
351
|
+
: new FetchError(`Fetch failed after ${this.config.maxRetries} retries: ${error.message}`, "ERR_FETCH_FAILED", error);
|
|
352
|
+
// Optionally include the error in the result object if needed for specific use cases,
|
|
353
|
+
// but typically throwing is preferred for signaling failure.
|
|
354
|
+
// return { ... an error result structure ... };
|
|
355
|
+
throw fetchError;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Performs the actual page fetch using a Playwright page from the pool.
|
|
360
|
+
* Ensures return type matches HTMLFetchResult.
|
|
361
|
+
*/
|
|
362
|
+
async fetchWithPlaywright(url, pool, fastMode) {
|
|
363
|
+
let page = null;
|
|
364
|
+
try {
|
|
365
|
+
page = await pool.acquirePage();
|
|
366
|
+
await this.applyBlockingRules(page, fastMode);
|
|
367
|
+
let response = null;
|
|
368
|
+
try {
|
|
369
|
+
response = await page.goto(url, {
|
|
370
|
+
waitUntil: "domcontentloaded",
|
|
371
|
+
timeout: 60000,
|
|
372
|
+
}); // Use domcontentloaded, adjust timeout
|
|
373
|
+
}
|
|
374
|
+
catch (navigationError) {
|
|
375
|
+
throw new FetchError(`Playwright navigation failed: ${navigationError.message}`, "ERR_NAVIGATION", navigationError);
|
|
376
|
+
}
|
|
377
|
+
// Optional: Add a small delay or check for specific elements if needed after load
|
|
378
|
+
// await delay(500);
|
|
379
|
+
if (!response) {
|
|
380
|
+
throw new FetchError("Playwright navigation did not return a response.", "ERR_NO_RESPONSE");
|
|
381
|
+
}
|
|
382
|
+
if (!response.ok()) {
|
|
383
|
+
throw new FetchError(`HTTP error status received: ${response.status()}`, "ERR_HTTP_ERROR", undefined, response.status());
|
|
384
|
+
}
|
|
385
|
+
const contentType = response.headers()["content-type"] || "";
|
|
386
|
+
if (!contentType.includes("html")) {
|
|
387
|
+
throw new FetchError(`Invalid content type received: ${contentType}`, "ERR_NON_HTML_CONTENT");
|
|
388
|
+
}
|
|
389
|
+
if (!fastMode && this.config.simulateHumanBehavior) {
|
|
390
|
+
await this.simulateHumanBehavior(page);
|
|
391
|
+
}
|
|
392
|
+
const html = await page.content();
|
|
393
|
+
const title = await page.title();
|
|
394
|
+
return {
|
|
395
|
+
html,
|
|
396
|
+
title,
|
|
397
|
+
url: page.url(), // Get final URL from page
|
|
398
|
+
isFromCache: false, // ADDED
|
|
399
|
+
statusCode: response.status(), // ADDED
|
|
400
|
+
error: undefined, // ADDED
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
finally {
|
|
404
|
+
if (page) {
|
|
405
|
+
await pool.releasePage(page);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
async applyBlockingRules(page, fastMode) {
|
|
410
|
+
const blockedResources = fastMode
|
|
411
|
+
? this.config.poolBlockedResourceTypes.concat([
|
|
412
|
+
"image",
|
|
413
|
+
"font",
|
|
414
|
+
"stylesheet",
|
|
415
|
+
"media",
|
|
416
|
+
])
|
|
417
|
+
: this.config.poolBlockedResourceTypes;
|
|
418
|
+
const blockedDomains = this.config.poolBlockedDomains;
|
|
419
|
+
if (blockedResources.length > 0 || blockedDomains.length > 0) {
|
|
420
|
+
try {
|
|
421
|
+
await page.route("**/*", (route) => {
|
|
422
|
+
// Route type added
|
|
423
|
+
const resourceType = route.request().resourceType();
|
|
424
|
+
const requestUrl = route.request().url();
|
|
425
|
+
// Block by resource type
|
|
426
|
+
if (blockedResources.includes(resourceType)) {
|
|
427
|
+
return route.abort();
|
|
428
|
+
}
|
|
429
|
+
// Block by domain pattern
|
|
430
|
+
if (blockedDomains.some((pattern) => new RegExp(pattern.replace(/\./g, "\\.").replace(/\*/g, ".*")).test(requestUrl))) {
|
|
431
|
+
return route.abort();
|
|
432
|
+
}
|
|
433
|
+
return route.continue();
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
catch (_error) {
|
|
437
|
+
/* Ignore errors setting up routing */
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Cleans up resources used by the engine, primarily closing browser instances in the pool.
|
|
443
|
+
*
|
|
444
|
+
* It is crucial to call this method when finished with the engine instance to release resources.
|
|
445
|
+
* @returns A Promise that resolves when cleanup is complete.
|
|
446
|
+
*/
|
|
447
|
+
async cleanup() {
|
|
448
|
+
try {
|
|
449
|
+
await this.queue.onIdle(); // Wait for active tasks
|
|
450
|
+
this.queue.clear(); // Clear pending tasks
|
|
451
|
+
if (this.browserPool) {
|
|
452
|
+
await this.browserPool.cleanup();
|
|
453
|
+
this.browserPool = null;
|
|
454
|
+
}
|
|
455
|
+
this.isUsingHeadedMode = false; // Reset mode flag
|
|
456
|
+
}
|
|
457
|
+
catch (_error) {
|
|
458
|
+
/* Ignore errors during cleanup */
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Retrieves metrics from the underlying browser pool.
|
|
463
|
+
* @returns An array of BrowserMetrics objects, one for each active browser instance, or an empty array if the pool is not initialized.
|
|
464
|
+
*/
|
|
465
|
+
getMetrics() {
|
|
466
|
+
if (this.browserPool) {
|
|
467
|
+
return this.browserPool.getMetrics();
|
|
468
|
+
}
|
|
469
|
+
return [];
|
|
470
|
+
}
|
|
471
|
+
// Helper to check if a specific domain is marked for headed mode
|
|
472
|
+
shouldUseHeadedMode(url) {
|
|
473
|
+
if (!this.config.useHeadedModeFallback)
|
|
474
|
+
return false;
|
|
475
|
+
try {
|
|
476
|
+
const domain = new URL(url).hostname;
|
|
477
|
+
return this.headedFallbackSites.has(domain);
|
|
478
|
+
}
|
|
479
|
+
catch {
|
|
480
|
+
return false; // Invalid URL
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
//# sourceMappingURL=PlaywrightEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightEngine.js","sourceRoot":"","sources":["../src/PlaywrightEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightEngine.test.d.ts","sourceRoot":"","sources":["../src/PlaywrightEngine.test.ts"],"names":[],"mappings":""}
|