@crawlee/playwright 4.0.0-beta.251 → 4.0.0-beta.253
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.
|
@@ -186,8 +186,26 @@ export class AdaptivePlaywrightCrawler extends BasicCrawler {
|
|
|
186
186
|
});
|
|
187
187
|
this.#staticCrawler = staticCrawler;
|
|
188
188
|
this.#browserCrawler = browserCrawler;
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
// Each attempt needs its own deferred cleanups, and they must share the attempt's cleanup stack: resources the
|
|
190
|
+
// pipeline defers releasing (the page) have to outlive the user's cleanups, which may still use them.
|
|
191
|
+
const deferredCleanup = ContextPipeline.create().compose((_context, onCleanup) => ({
|
|
192
|
+
registerDeferredCleanup: (cleanup) => {
|
|
193
|
+
onCleanup(async () => {
|
|
194
|
+
try {
|
|
195
|
+
await cleanup();
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
this.log.debug('Error in deferred cleanup', { error });
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
},
|
|
202
|
+
}));
|
|
203
|
+
this.#staticContextPipeline = deferredCleanup
|
|
204
|
+
.chain(staticCrawler.contextPipeline)
|
|
205
|
+
.compose(this.#adaptCheerioContext.bind(this));
|
|
206
|
+
this.#browserContextPipeline = deferredCleanup
|
|
207
|
+
.chain(browserCrawler.contextPipeline)
|
|
208
|
+
.compose(this.#adaptPlaywrightContext.bind(this));
|
|
191
209
|
}
|
|
192
210
|
async init() {
|
|
193
211
|
// A crawler can be run again after a teardown.
|
|
@@ -243,9 +261,14 @@ export class AdaptivePlaywrightCrawler extends BasicCrawler {
|
|
|
243
261
|
async #adaptPlaywrightContext(playwrightContext) {
|
|
244
262
|
// Capture the original response to avoid infinite recursion when the getter is copied to the context
|
|
245
263
|
const originalResponse = playwrightContext.response;
|
|
264
|
+
// `headers()` can return repeated headers (e.g. `set-cookie`) joined with `\n`, which `Headers` rejects
|
|
265
|
+
const headers = new Headers();
|
|
266
|
+
for (const { name, value } of await originalResponse.headersArray()) {
|
|
267
|
+
headers.append(name, value);
|
|
268
|
+
}
|
|
246
269
|
return {
|
|
247
270
|
response: new ResponseWithUrl(Uint8Array.from(await originalResponse.body()), {
|
|
248
|
-
headers
|
|
271
|
+
headers,
|
|
249
272
|
status: originalResponse.status(),
|
|
250
273
|
statusText: originalResponse.statusText(),
|
|
251
274
|
url: originalResponse.url(),
|
|
@@ -280,7 +303,6 @@ export class AdaptivePlaywrightCrawler extends BasicCrawler {
|
|
|
280
303
|
});
|
|
281
304
|
transactions.push(transaction);
|
|
282
305
|
const logs = [];
|
|
283
|
-
const deferredCleanup = [];
|
|
284
306
|
const contextModifications = {
|
|
285
307
|
request: new MutationJournal(),
|
|
286
308
|
state: new MutationJournal(),
|
|
@@ -290,7 +312,6 @@ export class AdaptivePlaywrightCrawler extends BasicCrawler {
|
|
|
290
312
|
request: contextModifications.request.track(request),
|
|
291
313
|
useState: async (defaultValue) => contextModifications.state.track(await useStateFunction(defaultValue)),
|
|
292
314
|
log: this.#createLogProxy(context.log, logs),
|
|
293
|
-
registerDeferredCleanup: (cleanup) => deferredCleanup.push(cleanup),
|
|
294
315
|
// The sub-crawler pipeline keeps this attempt's navigation deadline on `subCrawlerContext`, but the
|
|
295
316
|
// outer `extendTimeout` only pushes the deadline it finds on `context`, so push this one as well.
|
|
296
317
|
extendTimeout: (secs) => {
|
|
@@ -328,9 +349,6 @@ export class AdaptivePlaywrightCrawler extends BasicCrawler {
|
|
|
328
349
|
catch (error) {
|
|
329
350
|
return { ok: false, error, transaction, contextModifications, logs };
|
|
330
351
|
}
|
|
331
|
-
finally {
|
|
332
|
-
await Promise.all(deferredCleanup.map((cleanup) => cleanup()));
|
|
333
|
-
}
|
|
334
352
|
}
|
|
335
353
|
async runRequestHandler(crawlingContext) {
|
|
336
354
|
const renderingTypePrediction = await this.#renderingTypePredictor.value.predict(crawlingContext.request);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crawlee/playwright",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.253",
|
|
4
4
|
"description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.13.0"
|
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@apify/datastructures": "^3.0.1",
|
|
51
51
|
"@apify/timeout": "^1.0.1",
|
|
52
|
-
"@crawlee/basic": "4.0.0-beta.
|
|
53
|
-
"@crawlee/browser": "4.0.0-beta.
|
|
54
|
-
"@crawlee/browser-pool": "4.0.0-beta.
|
|
55
|
-
"@crawlee/cheerio": "4.0.0-beta.
|
|
56
|
-
"@crawlee/core": "4.0.0-beta.
|
|
57
|
-
"@crawlee/http-client": "4.0.0-beta.
|
|
58
|
-
"@crawlee/types": "4.0.0-beta.
|
|
59
|
-
"@crawlee/utils": "4.0.0-beta.
|
|
52
|
+
"@crawlee/basic": "4.0.0-beta.253",
|
|
53
|
+
"@crawlee/browser": "4.0.0-beta.253",
|
|
54
|
+
"@crawlee/browser-pool": "4.0.0-beta.253",
|
|
55
|
+
"@crawlee/cheerio": "4.0.0-beta.253",
|
|
56
|
+
"@crawlee/core": "4.0.0-beta.253",
|
|
57
|
+
"@crawlee/http-client": "4.0.0-beta.253",
|
|
58
|
+
"@crawlee/types": "4.0.0-beta.253",
|
|
59
|
+
"@crawlee/utils": "4.0.0-beta.253",
|
|
60
60
|
"cheerio": "^1.2.0",
|
|
61
61
|
"domhandler": "^6.0.1",
|
|
62
62
|
"jquery": "^3.7.1",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "f93aa3970468c422d9626db0d21175e8a39fdfed"
|
|
85
85
|
}
|