@crawlee/browser 4.0.0-beta.110 → 4.0.0-beta.112

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.
@@ -7,6 +7,8 @@ import type { ReadonlyDeep } from 'type-fest';
7
7
  import type { BrowserLaunchContext } from './browser-launcher.js';
8
8
  interface BaseResponse {
9
9
  status(): number;
10
+ /** Optional because only Playwright and Puppeteer responses are guaranteed to carry it. */
11
+ headers?(): Record<string, string>;
10
12
  }
11
13
  export interface BrowserCrawlingContext<Page extends CommonPage = CommonPage, Response extends BaseResponse = BaseResponse, UserData extends Dictionary = any, // with default to Dictionary we cant use a typed router in untyped crawler
12
14
  GoToOptions extends Dictionary = Dictionary> extends CrawlingContext<UserData> {
@@ -265,6 +267,8 @@ export declare abstract class BrowserCrawler<Page extends CommonPage = CommonPag
265
267
  requestList: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
266
268
  // @ts-ignore optional peer dependency or compatibility with es2022
267
269
  requestQueue: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
270
+ // @ts-ignore optional peer dependency or compatibility with es2022
271
+ requestManager: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
268
272
  // @ts-ignore optional peer dependency or compatibility with es2022
269
273
  requestHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
270
274
  // @ts-ignore optional peer dependency or compatibility with es2022
@@ -1,6 +1,7 @@
1
- import { BasicCrawler, browserPoolCookieToToughCookie, ContextPipeline, cookieStringToToughCookie, enqueueLinks, NavigationSkippedError, OwnedOrInjected, remainingNavigationWindowMillis, RequestState, resolveBaseUrlForEnqueueLinksFiltering, SessionError, toughCookieToBrowserPoolCookie, tryAbsoluteURL, validators, } from '@crawlee/basic';
1
+ import { BasicCrawler, browserPoolCookieToToughCookie, ContextPipeline, cookieStringToToughCookie, enqueueLinks, NavigationSkippedError, OwnedOrInjected, remainingNavigationWindowMillis, RequestState, RequestThrottledError, resolveBaseUrlForEnqueueLinksFiltering, SessionError, toughCookieToBrowserPoolCookie, tryAbsoluteURL, validators, } from '@crawlee/basic';
2
2
  import { BrowserPool, RemoteBrowserPool } from '@crawlee/browser-pool';
3
- import { CLOUDFLARE_RETRY_CSS_SELECTORS, RETRY_CSS_SELECTORS, sleep } from '@crawlee/utils';
3
+ import { CLOUDFLARE_RETRY_CSS_SELECTORS, RETRY_CSS_SELECTORS } from '@crawlee/utils/internal';
4
+ import { sleep } from '@crawlee/utils';
4
5
  import ow from 'ow';
5
6
  import { addTimeoutToPromise, TimeoutError, tryCancel } from '@apify/timeout';
6
7
  const COOKIES_BEFORE_HOOKS = Symbol('cookiesBeforeHooks');
@@ -408,6 +409,15 @@ export class BrowserCrawler extends BasicCrawler {
408
409
  if (typeof response === 'object' && typeof response.status === 'function') {
409
410
  const status = response.status();
410
411
  this.stats.registerStatusCode(status);
412
+ // Ahead of the error-status throw below: a 429 the user opted into treating as an error is still a
413
+ // rate limit the domain should back off from.
414
+ if (status === 429) {
415
+ // Both drivers lower-case header names and join duplicates, so a plain lookup is enough.
416
+ const retryAfter = response.headers?.()['retry-after'];
417
+ if (this.recordDomainRateLimit(crawlingContext.request.url, retryAfter)) {
418
+ throw new RequestThrottledError(`${crawlingContext.request.url} responded with 429.`);
419
+ }
420
+ }
411
421
  if (this.isErrorStatusCode(status)) {
412
422
  if (this.additionalHttpErrorStatusCodes.has(status)) {
413
423
  throw new Error(`${status} - Error status code was set by user.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/browser",
3
- "version": "4.0.0-beta.110",
3
+ "version": "4.0.0-beta.112",
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.0.0"
@@ -48,10 +48,10 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@apify/timeout": "^0.4.4",
51
- "@crawlee/basic": "4.0.0-beta.110",
52
- "@crawlee/browser-pool": "4.0.0-beta.110",
53
- "@crawlee/types": "4.0.0-beta.110",
54
- "@crawlee/utils": "4.0.0-beta.110",
51
+ "@crawlee/basic": "4.0.0-beta.112",
52
+ "@crawlee/browser-pool": "4.0.0-beta.112",
53
+ "@crawlee/types": "4.0.0-beta.112",
54
+ "@crawlee/utils": "4.0.0-beta.112",
55
55
  "ow": "^2.0.0",
56
56
  "tslib": "^2.8.1",
57
57
  "type-fest": "^4.41.0"
@@ -75,5 +75,5 @@
75
75
  }
76
76
  }
77
77
  },
78
- "gitHead": "71f42c48f431ca46b04491eca65b191691e75033"
78
+ "gitHead": "5d1e107d4dc4ffd21f1c6cc5b1a1c10b59ca2b47"
79
79
  }