@crawlee/playwright 4.0.0-beta.2 → 4.0.0-beta.21
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 +5 -1
- package/internals/adaptive-playwright-crawler.d.ts +38 -54
- package/internals/adaptive-playwright-crawler.d.ts.map +1 -1
- package/internals/adaptive-playwright-crawler.js +244 -169
- package/internals/adaptive-playwright-crawler.js.map +1 -1
- package/internals/enqueue-links/click-elements.d.ts +10 -0
- package/internals/enqueue-links/click-elements.d.ts.map +1 -1
- package/internals/enqueue-links/click-elements.js +14 -2
- package/internals/enqueue-links/click-elements.js.map +1 -1
- package/internals/playwright-crawler.d.ts +19 -42
- package/internals/playwright-crawler.d.ts.map +1 -1
- package/internals/playwright-crawler.js +47 -9
- package/internals/playwright-crawler.js.map +1 -1
- package/internals/utils/playwright-utils.d.ts +10 -3
- package/internals/utils/playwright-utils.d.ts.map +1 -1
- package/internals/utils/playwright-utils.js +36 -38
- package/internals/utils/playwright-utils.js.map +1 -1
- package/internals/utils/rendering-type-prediction.d.ts +8 -3
- package/internals/utils/rendering-type-prediction.d.ts.map +1 -1
- package/internals/utils/rendering-type-prediction.js +22 -10
- package/internals/utils/rendering-type-prediction.js.map +1 -1
- package/package.json +12 -8
- package/tsconfig.build.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
<small>A web scraping and browser automation library</small>
|
|
10
10
|
</h1>
|
|
11
11
|
|
|
12
|
+
<p align=center>
|
|
13
|
+
<a href="https://trendshift.io/repositories/5179" target="_blank"><img src="https://trendshift.io/api/badge/repositories/5179" alt="apify%2Fcrawlee | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
12
16
|
<p align=center>
|
|
13
17
|
<a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/v/@crawlee/core.svg" alt="NPM latest version" data-canonical-src="https://img.shields.io/npm/v/@crawlee/core/next.svg" style="max-width: 100%;"></a>
|
|
14
18
|
<a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/dm/@crawlee/core.svg" alt="Downloads" data-canonical-src="https://img.shields.io/npm/dm/@crawlee/core.svg" style="max-width: 100%;"></a>
|
|
@@ -24,7 +28,7 @@ Crawlee is available as the [`crawlee`](https://www.npmjs.com/package/crawlee) N
|
|
|
24
28
|
|
|
25
29
|
> 👉 **View full documentation, guides and examples on the [Crawlee project website](https://crawlee.dev)** 👈
|
|
26
30
|
|
|
27
|
-
>
|
|
31
|
+
> Do you prefer 🐍 Python instead of JavaScript? [👉 Checkout Crawlee for Python 👈](https://github.com/apify/crawlee-python).
|
|
28
32
|
|
|
29
33
|
## Installation
|
|
30
34
|
|
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
1
|
+
import { BasicCrawler } from '@crawlee/basic';
|
|
2
|
+
import type { BasicCrawlerOptions, BrowserHook, LoadedRequest, Request } from '@crawlee/browser';
|
|
3
|
+
import type { CrawlingContext, EnqueueLinksOptions, GetUserDataFromRequest, RestrictedCrawlingContext, RouterRoutes, StatisticsOptions, StatisticState } from '@crawlee/core';
|
|
3
4
|
import { Configuration, RequestHandlerResult, Statistics } from '@crawlee/core';
|
|
4
|
-
import type {
|
|
5
|
+
import type { BatchAddRequestsResult, Dictionary } from '@crawlee/types';
|
|
5
6
|
import { type CheerioRoot } from '@crawlee/utils';
|
|
6
7
|
import { type Cheerio } from 'cheerio';
|
|
8
|
+
import type { AnyNode } from 'domhandler';
|
|
7
9
|
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
8
10
|
import type { Page } from 'playwright';
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
11
|
-
import { PlaywrightCrawler } from './playwright-crawler.js';
|
|
11
|
+
import type { SetRequired } from 'type-fest';
|
|
12
|
+
import type { PlaywrightGotoOptions } from './playwright-crawler.js';
|
|
12
13
|
import { RenderingTypePredictor } from './utils/rendering-type-prediction.js';
|
|
13
|
-
type Result<TResult> = {
|
|
14
|
-
result: TResult;
|
|
15
|
-
ok: true;
|
|
16
|
-
logs?: LogProxyCall[];
|
|
17
|
-
} | {
|
|
18
|
-
error: unknown;
|
|
19
|
-
ok: false;
|
|
20
|
-
logs?: LogProxyCall[];
|
|
21
|
-
};
|
|
22
14
|
interface AdaptivePlaywrightCrawlerStatisticState extends StatisticState {
|
|
23
15
|
httpOnlyRequestHandlerRuns?: number;
|
|
24
16
|
browserRequestHandlerRuns?: number;
|
|
@@ -33,11 +25,12 @@ declare class AdaptivePlaywrightCrawlerStatistics extends Statistics {
|
|
|
33
25
|
trackBrowserRequestHandlerRun(): void;
|
|
34
26
|
trackRenderingTypeMisprediction(): void;
|
|
35
27
|
}
|
|
36
|
-
export interface AdaptivePlaywrightCrawlerContext<UserData extends Dictionary = Dictionary> extends
|
|
28
|
+
export interface AdaptivePlaywrightCrawlerContext<UserData extends Dictionary = Dictionary> extends CrawlingContext<UserData> {
|
|
29
|
+
request: LoadedRequest<Request<UserData>>;
|
|
37
30
|
/**
|
|
38
31
|
* The HTTP response, either from the HTTP client or from the initial request from playwright's navigation.
|
|
39
32
|
*/
|
|
40
|
-
response:
|
|
33
|
+
response: Response;
|
|
41
34
|
/**
|
|
42
35
|
* Playwright Page object. If accessed in HTTP-only rendering, this will throw an error and make the AdaptivePlaywrightCrawlerContext retry the request in a browser.
|
|
43
36
|
*/
|
|
@@ -46,7 +39,7 @@ export interface AdaptivePlaywrightCrawlerContext<UserData extends Dictionary =
|
|
|
46
39
|
* Wait for an element matching the selector to appear and return a Cheerio object of matched elements.
|
|
47
40
|
* Timeout defaults to 5s.
|
|
48
41
|
*/
|
|
49
|
-
querySelector
|
|
42
|
+
querySelector(selector: string, timeoutMs?: number): Promise<Cheerio<AnyNode>>;
|
|
50
43
|
/**
|
|
51
44
|
* Wait for an element matching the selector to appear.
|
|
52
45
|
* Timeout defaults to 5s.
|
|
@@ -74,24 +67,14 @@ export interface AdaptivePlaywrightCrawlerContext<UserData extends Dictionary =
|
|
|
74
67
|
* ```
|
|
75
68
|
*/
|
|
76
69
|
parseWithCheerio(selector?: string, timeoutMs?: number): Promise<CheerioRoot>;
|
|
70
|
+
enqueueLinks(options?: EnqueueLinksOptions): Promise<void>;
|
|
77
71
|
}
|
|
78
|
-
interface AdaptiveHook extends BrowserHook<Pick<AdaptivePlaywrightCrawlerContext, 'id' | '
|
|
72
|
+
interface AdaptiveHook extends BrowserHook<Pick<AdaptivePlaywrightCrawlerContext, 'id' | 'session' | 'proxyInfo' | 'log'> & {
|
|
79
73
|
page?: Page;
|
|
74
|
+
request: Request;
|
|
80
75
|
}, PlaywrightGotoOptions> {
|
|
81
76
|
}
|
|
82
|
-
export interface AdaptivePlaywrightCrawlerOptions extends Omit<
|
|
83
|
-
/**
|
|
84
|
-
* Function that is called to process each request.
|
|
85
|
-
*
|
|
86
|
-
* The function receives the {@link AdaptivePlaywrightCrawlingContext} as an argument, and it must refrain from calling code with side effects,
|
|
87
|
-
* other than the methods of the crawling context. Any other side effects may be invoked repeatedly by the crawler, which can lead to inconsistent results.
|
|
88
|
-
*
|
|
89
|
-
* The function must return a promise, which is then awaited by the crawler.
|
|
90
|
-
*
|
|
91
|
-
* If the function throws an exception, the crawler will try to re-crawl the
|
|
92
|
-
* request later, up to `option.maxRequestRetries` times.
|
|
93
|
-
*/
|
|
94
|
-
requestHandler?: (crawlingContext: LoadedContext<AdaptivePlaywrightCrawlerContext>) => Awaitable<void>;
|
|
77
|
+
export interface AdaptivePlaywrightCrawlerOptions<ExtendedContext extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext> extends Omit<BasicCrawlerOptions<AdaptivePlaywrightCrawlerContext, ExtendedContext>, 'preNavigationHooks' | 'postNavigationHooks'> {
|
|
95
78
|
/**
|
|
96
79
|
* Async functions that are sequentially evaluated before the navigation. Good for setting additional cookies.
|
|
97
80
|
* The function accepts a subset of the crawling context. If you attempt to access the `page` property during HTTP-only crawling,
|
|
@@ -117,23 +100,24 @@ export interface AdaptivePlaywrightCrawlerOptions extends Omit<PlaywrightCrawler
|
|
|
117
100
|
resultChecker?: (result: RequestHandlerResult) => boolean;
|
|
118
101
|
/**
|
|
119
102
|
* An optional callback used in rendering type detection. On each detection, the result of the plain HTTP run is compared to that of the browser one.
|
|
120
|
-
* If
|
|
103
|
+
* If a callback is provided, the contract is as follows:
|
|
104
|
+
* It the callback returns true or 'equal', the results are considered equal and the target site is considered static.
|
|
105
|
+
* If it returns false or 'different', the target site is considered client-rendered.
|
|
106
|
+
* If it returns 'inconclusive', the detection result won't be used.
|
|
121
107
|
* If no result comparator is specified, but there is a `resultChecker`, any site where the `resultChecker` returns true is considered static.
|
|
122
108
|
* If neither `resultComparator` nor `resultChecker` are specified, a deep comparison of returned dataset items is used as a default.
|
|
123
109
|
*/
|
|
124
|
-
resultComparator?: (resultA: RequestHandlerResult, resultB: RequestHandlerResult) => boolean;
|
|
110
|
+
resultComparator?: (resultA: RequestHandlerResult, resultB: RequestHandlerResult) => boolean | 'equal' | 'different' | 'inconclusive';
|
|
125
111
|
/**
|
|
126
112
|
* A custom rendering type predictor
|
|
127
113
|
*/
|
|
128
|
-
renderingTypePredictor?: Pick<RenderingTypePredictor, 'predict' | 'storeResult'>;
|
|
114
|
+
renderingTypePredictor?: Pick<RenderingTypePredictor, 'predict' | 'storeResult' | 'initialize'>;
|
|
129
115
|
/**
|
|
130
116
|
* Prevent direct access to storage in request handlers (only allow using context helpers).
|
|
131
117
|
* Defaults to `true`
|
|
132
118
|
*/
|
|
133
119
|
preventDirectStorageAccess?: boolean;
|
|
134
120
|
}
|
|
135
|
-
declare const proxyLogMethods: readonly ["error", "exception", "softFail", "info", "debug", "perf", "warningOnce", "deprecated"];
|
|
136
|
-
type LogProxyCall = [log: Log, method: (typeof proxyLogMethods)[number], ...args: unknown[]];
|
|
137
121
|
/**
|
|
138
122
|
* An extension of {@link PlaywrightCrawler} that uses a more limited request handler interface so that it is able to switch to HTTP-only crawling when it detects it may be possible.
|
|
139
123
|
*
|
|
@@ -163,31 +147,31 @@ type LogProxyCall = [log: Log, method: (typeof proxyLogMethods)[number], ...args
|
|
|
163
147
|
*
|
|
164
148
|
* @experimental
|
|
165
149
|
*/
|
|
166
|
-
export declare class AdaptivePlaywrightCrawler extends
|
|
150
|
+
export declare class AdaptivePlaywrightCrawler<ExtendedContext extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext> extends BasicCrawler<AdaptivePlaywrightCrawlerContext, ExtendedContext> {
|
|
167
151
|
readonly config: Configuration;
|
|
168
|
-
private adaptiveRequestHandler;
|
|
169
152
|
private renderingTypePredictor;
|
|
170
153
|
private resultChecker;
|
|
171
154
|
private resultComparator;
|
|
172
155
|
private preventDirectStorageAccess;
|
|
156
|
+
private staticContextPipeline;
|
|
157
|
+
private browserContextPipeline;
|
|
158
|
+
private individualRequestHandlerTimeoutMillis;
|
|
173
159
|
readonly stats: AdaptivePlaywrightCrawlerStatistics;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
protected
|
|
182
|
-
protected commitResult(crawlingContext:
|
|
160
|
+
private resultObjects;
|
|
161
|
+
private teardownHooks;
|
|
162
|
+
constructor(options?: AdaptivePlaywrightCrawlerOptions<ExtendedContext>, config?: Configuration);
|
|
163
|
+
protected _init(): Promise<void>;
|
|
164
|
+
private adaptCheerioContext;
|
|
165
|
+
private adaptPlaywrightContext;
|
|
166
|
+
private crawlOne;
|
|
167
|
+
protected runRequestHandler(crawlingContext: CrawlingContext): Promise<void>;
|
|
168
|
+
protected commitResult(crawlingContext: CrawlingContext, { calls, keyValueStoreChanges }: RequestHandlerResult): Promise<void>;
|
|
183
169
|
protected allowStorageAccess<R, TArgs extends any[]>(func: (...args: TArgs) => Promise<R>): (...args: TArgs) => Promise<R>;
|
|
184
|
-
protected
|
|
185
|
-
result: Result<RequestHandlerResult>;
|
|
186
|
-
initialStateCopy?: Record<string, unknown>;
|
|
187
|
-
}>;
|
|
188
|
-
protected runRequestHandlerWithPlainHTTP(crawlingContext: PlaywrightCrawlingContext, oldStateCopy?: Dictionary): Promise<Result<RequestHandlerResult>>;
|
|
170
|
+
protected enqueueLinks(options: SetRequired<EnqueueLinksOptions, 'urls'>, request: RestrictedCrawlingContext['request'], result: RequestHandlerResult): Promise<BatchAddRequestsResult>;
|
|
189
171
|
private createLogProxy;
|
|
172
|
+
teardown(): Promise<void>;
|
|
190
173
|
}
|
|
191
|
-
|
|
174
|
+
// @ts-ignore optional peer dependency or compatibility with es2022
|
|
175
|
+
export declare function createAdaptivePlaywrightRouter<Context extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext, UserData extends Dictionary = GetUserDataFromRequest<Context['request']>>(routes?: RouterRoutes<Context, UserData>): import("@crawlee/basic").RouterHandler<Context>;
|
|
192
176
|
export {};
|
|
193
177
|
//# sourceMappingURL=adaptive-playwright-crawler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adaptive-playwright-crawler.d.ts","sourceRoot":"","sources":["../../src/internals/adaptive-playwright-crawler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"adaptive-playwright-crawler.d.ts","sourceRoot":"","sources":["../../src/internals/adaptive-playwright-crawler.ts"],"names":[],"mappings":"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"}
|