@crawlee/puppeteer 3.0.0-alpha.2 → 3.0.0-alpha.5
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/index.d.ts +12 -0
- package/index.d.ts.map +1 -0
- package/index.js +12 -0
- package/index.js.map +1 -0
- package/index.mjs +76 -0
- package/internals/enqueue-links/click-elements.d.ts +188 -0
- package/internals/enqueue-links/click-elements.d.ts.map +1 -0
- package/internals/enqueue-links/click-elements.js +336 -0
- package/internals/enqueue-links/click-elements.js.map +1 -0
- package/internals/puppeteer-crawler.d.ts +149 -0
- package/internals/puppeteer-crawler.d.ts.map +1 -0
- package/internals/puppeteer-crawler.js +117 -0
- package/internals/puppeteer-crawler.js.map +1 -0
- package/internals/puppeteer-launcher.d.ts +142 -0
- package/internals/puppeteer-launcher.d.ts.map +1 -0
- package/internals/puppeteer-launcher.js +150 -0
- package/internals/puppeteer-launcher.js.map +1 -0
- package/internals/stealth/hiding_tricks.d.ts +10 -0
- package/internals/stealth/hiding_tricks.d.ts.map +1 -0
- package/internals/stealth/hiding_tricks.js +334 -0
- package/internals/stealth/hiding_tricks.js.map +1 -0
- package/internals/stealth/index.d.ts +40 -0
- package/internals/stealth/index.d.ts.map +1 -0
- package/internals/stealth/index.js +108 -0
- package/internals/stealth/index.js.map +1 -0
- package/internals/utils/puppeteer_request_interception.d.ts +60 -0
- package/internals/utils/puppeteer_request_interception.d.ts.map +1 -0
- package/internals/utils/puppeteer_request_interception.js +225 -0
- package/internals/utils/puppeteer_request_interception.js.map +1 -0
- package/internals/utils/puppeteer_utils.d.ts +298 -0
- package/internals/utils/puppeteer_utils.d.ts.map +1 -0
- package/internals/utils/puppeteer_utils.js +468 -0
- package/internals/utils/puppeteer_utils.js.map +1 -0
- package/package.json +2 -5
- package/tsconfig.build.tsbuildinfo +1 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { BrowserCrawler, BrowserCrawlerHandleRequest, BrowserCrawlerOptions, BrowserCrawlingContext, BrowserHook } from '@crawlee/browser';
|
|
2
|
+
import { PuppeteerPlugin } from '@crawlee/browser-pool';
|
|
3
|
+
import { HTTPResponse, LaunchOptions, Page } from 'puppeteer';
|
|
4
|
+
import { PuppeteerLaunchContext } from './puppeteer-launcher';
|
|
5
|
+
import { DirectNavigationOptions } from './utils/puppeteer_utils';
|
|
6
|
+
export declare type PuppeteerController = ReturnType<PuppeteerPlugin['_createController']>;
|
|
7
|
+
export declare type PuppeteerCrawlContext = BrowserCrawlingContext<Page, HTTPResponse, PuppeteerController>;
|
|
8
|
+
export declare type PuppeteerHook = BrowserHook<PuppeteerCrawlContext, PuppeteerGoToOptions>;
|
|
9
|
+
export declare type PuppeteerRequestHandlerParam = BrowserCrawlingContext<Page, HTTPResponse, PuppeteerController>;
|
|
10
|
+
export declare type PuppeteerRequestHandler = BrowserCrawlerHandleRequest<PuppeteerRequestHandlerParam>;
|
|
11
|
+
export declare type PuppeteerGoToOptions = Parameters<Page['goto']>[1];
|
|
12
|
+
export interface PuppeteerCrawlerOptions extends BrowserCrawlerOptions<PuppeteerCrawlContext, PuppeteerGoToOptions, {
|
|
13
|
+
browserPlugins: [PuppeteerPlugin];
|
|
14
|
+
}> {
|
|
15
|
+
/**
|
|
16
|
+
* Options used by {@link launchPuppeteer} to start new Puppeteer instances.
|
|
17
|
+
*/
|
|
18
|
+
launchContext?: PuppeteerLaunchContext;
|
|
19
|
+
/**
|
|
20
|
+
* Async functions that are sequentially evaluated before the navigation. Good for setting additional cookies
|
|
21
|
+
* or browser properties before navigation. The function accepts two parameters, `crawlingContext` and `gotoOptions`,
|
|
22
|
+
* which are passed to the `page.goto()` function the crawler calls to navigate.
|
|
23
|
+
* Example:
|
|
24
|
+
* ```
|
|
25
|
+
* preNavigationHooks: [
|
|
26
|
+
* async (crawlingContext, gotoOptions) => {
|
|
27
|
+
* const { page } = crawlingContext;
|
|
28
|
+
* await page.evaluate((attr) => { window.foo = attr; }, 'bar');
|
|
29
|
+
* },
|
|
30
|
+
* ]
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
preNavigationHooks?: PuppeteerHook[];
|
|
34
|
+
/**
|
|
35
|
+
* Async functions that are sequentially evaluated after the navigation. Good for checking if the navigation was successful.
|
|
36
|
+
* The function accepts `crawlingContext` as the only parameter.
|
|
37
|
+
* Example:
|
|
38
|
+
* ```
|
|
39
|
+
* postNavigationHooks: [
|
|
40
|
+
* async (crawlingContext) => {
|
|
41
|
+
* const { page } = crawlingContext;
|
|
42
|
+
* if (hasCaptcha(page)) {
|
|
43
|
+
* await solveCaptcha (page);
|
|
44
|
+
* }
|
|
45
|
+
* },
|
|
46
|
+
* ]
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
postNavigationHooks?: PuppeteerHook[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Provides a simple framework for parallel crawling of web pages
|
|
53
|
+
* using headless Chrome with [Puppeteer](https://github.com/puppeteer/puppeteer).
|
|
54
|
+
* The URLs to crawl are fed either from a static list of URLs
|
|
55
|
+
* or from a dynamic queue of URLs enabling recursive crawling of websites.
|
|
56
|
+
*
|
|
57
|
+
* Since `PuppeteerCrawler` uses headless Chrome to download web pages and extract data,
|
|
58
|
+
* it is useful for crawling of websites that require to execute JavaScript.
|
|
59
|
+
* If the target website doesn't need JavaScript, consider using {@link CheerioCrawler},
|
|
60
|
+
* which downloads the pages using raw HTTP requests and is about 10x faster.
|
|
61
|
+
*
|
|
62
|
+
* The source URLs are represented using {@link Request} objects that are fed from
|
|
63
|
+
* {@link RequestList} or {@link RequestQueue} instances provided by the {@link PuppeteerCrawlerOptions.requestList}
|
|
64
|
+
* or {@link PuppeteerCrawlerOptions.requestQueue} constructor options, respectively.
|
|
65
|
+
*
|
|
66
|
+
* If both {@link PuppeteerCrawlerOptions.requestList} and {@link PuppeteerCrawlerOptions.requestQueue} are used,
|
|
67
|
+
* the instance first processes URLs from the {@link RequestList} and automatically enqueues all of them
|
|
68
|
+
* to {@link RequestQueue} before it starts their processing. This ensures that a single URL is not crawled multiple times.
|
|
69
|
+
*
|
|
70
|
+
* The crawler finishes when there are no more {@link Request} objects to crawl.
|
|
71
|
+
*
|
|
72
|
+
* `PuppeteerCrawler` opens a new Chrome page (i.e. tab) for each {@link Request} object to crawl
|
|
73
|
+
* and then calls the function provided by user as the {@link PuppeteerCrawlerOptions.handlePageFunction} option.
|
|
74
|
+
*
|
|
75
|
+
* New pages are only opened when there is enough free CPU and memory available,
|
|
76
|
+
* using the functionality provided by the {@link AutoscaledPool} class.
|
|
77
|
+
* All {@link AutoscaledPool} configuration options can be passed to the {@link PuppeteerCrawlerOptions.autoscaledPoolOptions}
|
|
78
|
+
* parameter of the `PuppeteerCrawler` constructor. For user convenience, the `minConcurrency` and `maxConcurrency`
|
|
79
|
+
* {@link AutoscaledPoolOptions} are available directly in the `PuppeteerCrawler` constructor.
|
|
80
|
+
*
|
|
81
|
+
* Note that the pool of Puppeteer instances is internally managed by the [BrowserPool](https://github.com/apify/browser-pool) class.
|
|
82
|
+
*
|
|
83
|
+
* **Example usage:**
|
|
84
|
+
*
|
|
85
|
+
* ```javascript
|
|
86
|
+
* const crawler = new PuppeteerCrawler({
|
|
87
|
+
* requestList,
|
|
88
|
+
* handlePageFunction: async ({ page, request }) => {
|
|
89
|
+
* // This function is called to extract data from a single web page
|
|
90
|
+
* // 'page' is an instance of Puppeteer.Page with page.goto(request.url) already called
|
|
91
|
+
* // 'request' is an instance of Request class with information about the page to load
|
|
92
|
+
* await Actor.pushData({
|
|
93
|
+
* title: await page.title(),
|
|
94
|
+
* url: request.url,
|
|
95
|
+
* succeeded: true,
|
|
96
|
+
* })
|
|
97
|
+
* },
|
|
98
|
+
* handleFailedRequestFunction: async ({ request }) => {
|
|
99
|
+
* // This function is called when the crawling of a request failed too many times
|
|
100
|
+
* await Actor.pushData({
|
|
101
|
+
* url: request.url,
|
|
102
|
+
* succeeded: false,
|
|
103
|
+
* errors: request.errorMessages,
|
|
104
|
+
* })
|
|
105
|
+
* },
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* await crawler.run();
|
|
109
|
+
* ```
|
|
110
|
+
* @category Crawlers
|
|
111
|
+
*/
|
|
112
|
+
export declare class PuppeteerCrawler extends BrowserCrawler<{
|
|
113
|
+
browserPlugins: [PuppeteerPlugin];
|
|
114
|
+
}, LaunchOptions, PuppeteerCrawlContext> {
|
|
115
|
+
protected static optionsShape: {
|
|
116
|
+
browserPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
117
|
+
launchContext: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
118
|
+
handlePageFunction: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
119
|
+
gotoFunction: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
120
|
+
gotoTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
121
|
+
navigationTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
122
|
+
preNavigationHooks: import("ow").ArrayPredicate<unknown> & import("ow").BasePredicate<unknown[] | undefined>;
|
|
123
|
+
postNavigationHooks: import("ow").ArrayPredicate<unknown> & import("ow").BasePredicate<unknown[] | undefined>;
|
|
124
|
+
sessionPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
125
|
+
persistCookiesPerSession: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
126
|
+
useSessionPool: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
127
|
+
proxyConfiguration: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
128
|
+
requestList: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
129
|
+
requestQueue: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
130
|
+
requestHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
131
|
+
handleRequestFunction: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
132
|
+
requestHandlerTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
133
|
+
handleRequestTimeoutSecs: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
134
|
+
failedRequestHandler: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
135
|
+
handleFailedRequestFunction: import("ow").Predicate<Function> & import("ow").BasePredicate<Function | undefined>;
|
|
136
|
+
maxRequestRetries: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
137
|
+
maxRequestsPerCrawl: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
138
|
+
autoscaledPoolOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
139
|
+
minConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
140
|
+
maxConcurrency: import("ow").NumberPredicate & import("ow").BasePredicate<number | undefined>;
|
|
141
|
+
log: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* All `PuppeteerCrawler` parameters are passed via an options object.
|
|
145
|
+
*/
|
|
146
|
+
constructor(options: PuppeteerCrawlerOptions);
|
|
147
|
+
protected _navigationHandler(crawlingContext: PuppeteerCrawlContext, gotoOptions: DirectNavigationOptions): Promise<any>;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=puppeteer-crawler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puppeteer-crawler.d.ts","sourceRoot":"","sources":["../../src/internals/puppeteer-crawler.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACd,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAsB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAqB,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAAgB,MAAM,yBAAyB,CAAC;AAEhF,oBAAY,mBAAmB,GAAG,UAAU,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAEnF,oBAAY,qBAAqB,GAAG,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAA;AAEnG,oBAAY,aAAa,GAAG,WAAW,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;AAErF,oBAAY,4BAA4B,GAAG,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAA;AAE1G,oBAAY,uBAAuB,GAAG,2BAA2B,CAAC,4BAA4B,CAAC,CAAC;AAEhG,oBAAY,oBAAoB,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/D,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB,CAClE,qBAAqB,EACrB,oBAAoB,EACpB;IAAE,cAAc,EAAE,CAAC,eAAe,CAAC,CAAA;CAAE,CACxC;IACG;;OAEG;IACH,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAEvC;;;;;;;;;;;;;OAaG;IACH,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC;IAErC;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,CAAC,EAAE,aAAa,EAAE,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,qBAAa,gBAAiB,SAAQ,cAAc,CAAC;IAAE,cAAc,EAAE,CAAC,eAAe,CAAC,CAAA;CAAE,EAAE,aAAa,EAAE,qBAAqB,CAAC;IAC7H,iBAA0B,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;MAIpC;IAEF;;OAEG;gBACS,OAAO,EAAE,uBAAuB;cAqCnB,kBAAkB,CAAC,eAAe,EAAE,qBAAqB,EAAE,WAAW,EAAE,uBAAuB;CAQ3H"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PuppeteerCrawler = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const browser_1 = require("@crawlee/browser");
|
|
6
|
+
const ow_1 = tslib_1.__importDefault(require("ow"));
|
|
7
|
+
const puppeteer_launcher_1 = require("./puppeteer-launcher");
|
|
8
|
+
const stealth_1 = require("./stealth");
|
|
9
|
+
const puppeteer_utils_1 = require("./utils/puppeteer_utils");
|
|
10
|
+
/**
|
|
11
|
+
* Provides a simple framework for parallel crawling of web pages
|
|
12
|
+
* using headless Chrome with [Puppeteer](https://github.com/puppeteer/puppeteer).
|
|
13
|
+
* The URLs to crawl are fed either from a static list of URLs
|
|
14
|
+
* or from a dynamic queue of URLs enabling recursive crawling of websites.
|
|
15
|
+
*
|
|
16
|
+
* Since `PuppeteerCrawler` uses headless Chrome to download web pages and extract data,
|
|
17
|
+
* it is useful for crawling of websites that require to execute JavaScript.
|
|
18
|
+
* If the target website doesn't need JavaScript, consider using {@link CheerioCrawler},
|
|
19
|
+
* which downloads the pages using raw HTTP requests and is about 10x faster.
|
|
20
|
+
*
|
|
21
|
+
* The source URLs are represented using {@link Request} objects that are fed from
|
|
22
|
+
* {@link RequestList} or {@link RequestQueue} instances provided by the {@link PuppeteerCrawlerOptions.requestList}
|
|
23
|
+
* or {@link PuppeteerCrawlerOptions.requestQueue} constructor options, respectively.
|
|
24
|
+
*
|
|
25
|
+
* If both {@link PuppeteerCrawlerOptions.requestList} and {@link PuppeteerCrawlerOptions.requestQueue} are used,
|
|
26
|
+
* the instance first processes URLs from the {@link RequestList} and automatically enqueues all of them
|
|
27
|
+
* to {@link RequestQueue} before it starts their processing. This ensures that a single URL is not crawled multiple times.
|
|
28
|
+
*
|
|
29
|
+
* The crawler finishes when there are no more {@link Request} objects to crawl.
|
|
30
|
+
*
|
|
31
|
+
* `PuppeteerCrawler` opens a new Chrome page (i.e. tab) for each {@link Request} object to crawl
|
|
32
|
+
* and then calls the function provided by user as the {@link PuppeteerCrawlerOptions.handlePageFunction} option.
|
|
33
|
+
*
|
|
34
|
+
* New pages are only opened when there is enough free CPU and memory available,
|
|
35
|
+
* using the functionality provided by the {@link AutoscaledPool} class.
|
|
36
|
+
* All {@link AutoscaledPool} configuration options can be passed to the {@link PuppeteerCrawlerOptions.autoscaledPoolOptions}
|
|
37
|
+
* parameter of the `PuppeteerCrawler` constructor. For user convenience, the `minConcurrency` and `maxConcurrency`
|
|
38
|
+
* {@link AutoscaledPoolOptions} are available directly in the `PuppeteerCrawler` constructor.
|
|
39
|
+
*
|
|
40
|
+
* Note that the pool of Puppeteer instances is internally managed by the [BrowserPool](https://github.com/apify/browser-pool) class.
|
|
41
|
+
*
|
|
42
|
+
* **Example usage:**
|
|
43
|
+
*
|
|
44
|
+
* ```javascript
|
|
45
|
+
* const crawler = new PuppeteerCrawler({
|
|
46
|
+
* requestList,
|
|
47
|
+
* handlePageFunction: async ({ page, request }) => {
|
|
48
|
+
* // This function is called to extract data from a single web page
|
|
49
|
+
* // 'page' is an instance of Puppeteer.Page with page.goto(request.url) already called
|
|
50
|
+
* // 'request' is an instance of Request class with information about the page to load
|
|
51
|
+
* await Actor.pushData({
|
|
52
|
+
* title: await page.title(),
|
|
53
|
+
* url: request.url,
|
|
54
|
+
* succeeded: true,
|
|
55
|
+
* })
|
|
56
|
+
* },
|
|
57
|
+
* handleFailedRequestFunction: async ({ request }) => {
|
|
58
|
+
* // This function is called when the crawling of a request failed too many times
|
|
59
|
+
* await Actor.pushData({
|
|
60
|
+
* url: request.url,
|
|
61
|
+
* succeeded: false,
|
|
62
|
+
* errors: request.errorMessages,
|
|
63
|
+
* })
|
|
64
|
+
* },
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* await crawler.run();
|
|
68
|
+
* ```
|
|
69
|
+
* @category Crawlers
|
|
70
|
+
*/
|
|
71
|
+
class PuppeteerCrawler extends browser_1.BrowserCrawler {
|
|
72
|
+
/**
|
|
73
|
+
* All `PuppeteerCrawler` parameters are passed via an options object.
|
|
74
|
+
*/
|
|
75
|
+
constructor(options) {
|
|
76
|
+
(0, ow_1.default)(options, 'PuppeteerCrawlerOptions', ow_1.default.object.exactShape(PuppeteerCrawler.optionsShape));
|
|
77
|
+
const { launchContext = {}, browserPoolOptions = {}, proxyConfiguration, ...browserCrawlerOptions } = options;
|
|
78
|
+
const { stealth = false } = launchContext;
|
|
79
|
+
if (launchContext.proxyUrl) {
|
|
80
|
+
throw new Error('PuppeteerCrawlerOptions.launchContext.proxyUrl is not allowed in PuppeteerCrawler.'
|
|
81
|
+
+ 'Use PuppeteerCrawlerOptions.proxyConfiguration');
|
|
82
|
+
}
|
|
83
|
+
const puppeteerLauncher = new puppeteer_launcher_1.PuppeteerLauncher(launchContext);
|
|
84
|
+
browserPoolOptions.browserPlugins = [
|
|
85
|
+
puppeteerLauncher.createBrowserPlugin(),
|
|
86
|
+
];
|
|
87
|
+
super({ ...browserCrawlerOptions, proxyConfiguration, browserPoolOptions });
|
|
88
|
+
if (stealth) {
|
|
89
|
+
this.browserPool.postLaunchHooks.push(async (_pageId, browserController) => {
|
|
90
|
+
// TODO: We can do this better now. It is not necessary to override the page.
|
|
91
|
+
// we can modify the page in the postPageCreateHook
|
|
92
|
+
const { hideWebDriver, ...newStealthOptions } = puppeteerLauncher.stealthOptions;
|
|
93
|
+
(0, stealth_1.applyStealthToBrowser)(browserController.browser, newStealthOptions);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
this.launchContext = launchContext;
|
|
97
|
+
}
|
|
98
|
+
async _navigationHandler(crawlingContext, gotoOptions) {
|
|
99
|
+
if (this.gotoFunction) {
|
|
100
|
+
this.log.deprecated('PuppeteerCrawlerOptions.gotoFunction is deprecated. Use "preNavigationHooks" and "postNavigationHooks" instead.');
|
|
101
|
+
return this.gotoFunction(crawlingContext, gotoOptions);
|
|
102
|
+
}
|
|
103
|
+
return (0, puppeteer_utils_1.gotoExtended)(crawlingContext.page, crawlingContext.request, gotoOptions);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.PuppeteerCrawler = PuppeteerCrawler;
|
|
107
|
+
Object.defineProperty(PuppeteerCrawler, "optionsShape", {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
configurable: true,
|
|
110
|
+
writable: true,
|
|
111
|
+
value: {
|
|
112
|
+
...browser_1.BrowserCrawler.optionsShape,
|
|
113
|
+
browserPoolOptions: ow_1.default.optional.object,
|
|
114
|
+
launchContext: ow_1.default.optional.object,
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
//# sourceMappingURL=puppeteer-crawler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puppeteer-crawler.js","sourceRoot":"","sources":["../../src/internals/puppeteer-crawler.ts"],"names":[],"mappings":";;;;AAAA,8CAM0B;AAK1B,oDAAoB;AAEpB,6DAAiF;AACjF,uCAAkD;AAClD,6DAAgF;AA0DhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,MAAa,gBAAiB,SAAQ,wBAA2F;IAO7H;;OAEG;IACH,YAAY,OAAgC;QACxC,IAAA,YAAE,EAAC,OAAO,EAAE,yBAAyB,EAAE,YAAE,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC;QAE5F,MAAM,EACF,aAAa,GAAG,EAAE,EAClB,kBAAkB,GAAG,EAAwB,EAC7C,kBAAkB,EAClB,GAAG,qBAAqB,EAC3B,GAAG,OAAO,CAAC;QAEZ,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,aAAa,CAAC;QAE1C,IAAI,aAAa,CAAC,QAAQ,EAAE;YACxB,MAAM,IAAI,KAAK,CAAC,oFAAoF;kBAC9F,gDAAgD,CAAC,CAAC;SAC3D;QAED,MAAM,iBAAiB,GAAG,IAAI,sCAAiB,CAAC,aAAa,CAAC,CAAC;QAE/D,kBAAkB,CAAC,cAAc,GAAG;YAChC,iBAAiB,CAAC,mBAAmB,EAAE;SAC1C,CAAC;QAEF,KAAK,CAAC,EAAE,GAAG,qBAAqB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAE5E,IAAI,OAAO,EAAE;YACT,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE;gBACvE,6EAA6E;gBAC7E,oDAAoD;gBACpD,MAAM,EAAE,aAAa,EAAE,GAAG,iBAAiB,EAAE,GAAG,iBAAiB,CAAC,cAAe,CAAC;gBAClF,IAAA,+BAAqB,EAAC,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;SACN;QAED,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,CAAC;IAEkB,KAAK,CAAC,kBAAkB,CAAC,eAAsC,EAAE,WAAoC;QACpH,IAAI,IAAI,CAAC,YAAY,EAAE;YACnB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,iHAAiH,CAAC,CAAC;YAEvI,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,WAAyB,CAAC,CAAC;SACxE;QACD,OAAO,IAAA,8BAAY,EAAC,eAAe,CAAC,IAAI,EAAE,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACpF,CAAC;;AAtDL,4CAuDC;AAtDG;;;;WAAyC;QACrC,GAAG,wBAAc,CAAC,YAAY;QAC9B,kBAAkB,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;QACtC,aAAa,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;KACpC;GAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Browser } from 'puppeteer';
|
|
2
|
+
import { PuppeteerPlugin } from '@crawlee/browser-pool';
|
|
3
|
+
import { BrowserLaunchContext, BrowserLauncher } from '@crawlee/browser';
|
|
4
|
+
import { StealthOptions } from './stealth';
|
|
5
|
+
/**
|
|
6
|
+
* Apify extends the launch options of Puppeteer.
|
|
7
|
+
* You can use any of the Puppeteer compatible
|
|
8
|
+
* [`LaunchOptions`](https://pptr.dev/#?product=Puppeteer&show=api-puppeteerlaunchoptions)
|
|
9
|
+
* options by providing the `launchOptions` property.
|
|
10
|
+
*
|
|
11
|
+
* **Example:**
|
|
12
|
+
* ```js
|
|
13
|
+
* // launch a headless Chrome (not Chromium)
|
|
14
|
+
* const launchContext = {
|
|
15
|
+
* // Apify helpers
|
|
16
|
+
* useChrome: true,
|
|
17
|
+
* proxyUrl: 'http://user:password@some.proxy.com'
|
|
18
|
+
* // Native Puppeteer options
|
|
19
|
+
* launchOptions: {
|
|
20
|
+
* headless: true,
|
|
21
|
+
* args: ['--some-flag'],
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export interface PuppeteerLaunchContext extends BrowserLaunchContext<PuppeteerPlugin['launchOptions'], unknown> {
|
|
27
|
+
/**
|
|
28
|
+
* `puppeteer.launch` [options](https://pptr.dev/#?product=Puppeteer&version=v13.5.1&show=api-puppeteerlaunchoptions)
|
|
29
|
+
*/
|
|
30
|
+
launchOptions?: PuppeteerPlugin['launchOptions'];
|
|
31
|
+
/**
|
|
32
|
+
* URL to a HTTP proxy server. It must define the port number,
|
|
33
|
+
* and it may also contain proxy username and password.
|
|
34
|
+
*
|
|
35
|
+
* Example: `http://bob:pass123@proxy.example.com:1234`.
|
|
36
|
+
*/
|
|
37
|
+
proxyUrl?: string;
|
|
38
|
+
/**
|
|
39
|
+
* The `User-Agent` HTTP header used by the browser.
|
|
40
|
+
* If not provided, the function sets `User-Agent` to a reasonable default
|
|
41
|
+
* to reduce the chance of detection of the crawler.
|
|
42
|
+
*/
|
|
43
|
+
userAgent?: string;
|
|
44
|
+
/**
|
|
45
|
+
* If `true` and `executablePath` is not set,
|
|
46
|
+
* Puppeteer will launch full Google Chrome browser available on the machine
|
|
47
|
+
* rather than the bundled Chromium. The path to Chrome executable
|
|
48
|
+
* is taken from the `APIFY_CHROME_EXECUTABLE_PATH` environment variable if provided,
|
|
49
|
+
* or defaults to the typical Google Chrome executable location specific for the operating system.
|
|
50
|
+
* By default, this option is `false`.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
useChrome?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Already required module (`Object`). This enables usage of various Puppeteer
|
|
56
|
+
* wrappers such as `puppeteer-extra`.
|
|
57
|
+
*
|
|
58
|
+
* Take caution, because it can cause all kinds of unexpected errors and weird behavior.
|
|
59
|
+
* Apify SDK is not tested with any other library besides `puppeteer` itself.
|
|
60
|
+
*/
|
|
61
|
+
launcher?: unknown;
|
|
62
|
+
/**
|
|
63
|
+
* With this option selected, all pages will be opened in a new incognito browser context.
|
|
64
|
+
* This means they will not share cookies nor cache and their resources will not be throttled by one another.
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
useIncognitoPages?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* This setting hides most of the known properties that identify headless Chrome and makes it nearly undetectable.
|
|
70
|
+
* It is recommended to use it together with the `useChrome` set to `true`.
|
|
71
|
+
* @deprecated
|
|
72
|
+
*/
|
|
73
|
+
stealth?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Using this configuration, you can disable some of the hiding tricks.
|
|
76
|
+
* For these settings to take effect `stealth` must be set to true
|
|
77
|
+
* @deprecated
|
|
78
|
+
*/
|
|
79
|
+
stealthOptions?: StealthOptions;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* `PuppeteerLauncher` is based on the `BrowserLauncher`. It launches `puppeteer` browser instance.
|
|
83
|
+
* @ignore
|
|
84
|
+
*/
|
|
85
|
+
export declare class PuppeteerLauncher extends BrowserLauncher<PuppeteerPlugin, unknown> {
|
|
86
|
+
protected static optionsShape: {
|
|
87
|
+
launcher: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
88
|
+
userAgent: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
89
|
+
stealth: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
90
|
+
stealthOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
91
|
+
proxyUrl: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
92
|
+
useChrome: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
93
|
+
useIncognitoPages: import("ow").BooleanPredicate & import("ow").BasePredicate<boolean | undefined>;
|
|
94
|
+
userDataDir: import("ow").StringPredicate & import("ow").BasePredicate<string | undefined>;
|
|
95
|
+
launchOptions: import("ow").ObjectPredicate<object> & import("ow").BasePredicate<object | undefined>;
|
|
96
|
+
};
|
|
97
|
+
stealth?: boolean;
|
|
98
|
+
stealthOptions: StealthOptions;
|
|
99
|
+
/**
|
|
100
|
+
* All `PuppeteerLauncher` parameters are passed via an launchContext object.
|
|
101
|
+
*/
|
|
102
|
+
constructor(launchContext?: PuppeteerLaunchContext);
|
|
103
|
+
launch(): Promise<import("packages/browser-pool/dist/puppeteer/puppeteer-proxy-per-page").Browser>;
|
|
104
|
+
createLaunchOptions(): {
|
|
105
|
+
args?: string[] | undefined;
|
|
106
|
+
} & import("packages/utils/dist").Dictionary<unknown>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Launches headless Chrome using Puppeteer pre-configured to work within the Apify platform.
|
|
110
|
+
* The function has the same argument and the return value as `puppeteer.launch()`.
|
|
111
|
+
* See [Puppeteer documentation](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions) for more details.
|
|
112
|
+
*
|
|
113
|
+
* The `launchPuppeteer()` function alters the following Puppeteer options:
|
|
114
|
+
*
|
|
115
|
+
* - Passes the setting from the `APIFY_HEADLESS` environment variable to the `headless` option,
|
|
116
|
+
* unless it was already defined by the caller or `APIFY_XVFB` environment variable is set to `1`.
|
|
117
|
+
* Note that Apify Actor cloud platform automatically sets `APIFY_HEADLESS=1` to all running actors.
|
|
118
|
+
* - Takes the `proxyUrl` option, validates it and adds it to `args` as `--proxy-server=XXX`.
|
|
119
|
+
* The proxy URL must define a port number and have one of the following schemes: `http://`,
|
|
120
|
+
* `https://`, `socks4://` or `socks5://`.
|
|
121
|
+
* If the proxy is HTTP (i.e. has the `http://` scheme) and contains username or password,
|
|
122
|
+
* the `launchPuppeteer` functions sets up an anonymous proxy HTTP
|
|
123
|
+
* to make the proxy work with headless Chrome. For more information, read the
|
|
124
|
+
* [blog post about proxy-chain library](https://blog.apify.com/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212).
|
|
125
|
+
*
|
|
126
|
+
* To use this function, you need to have the [puppeteer](https://www.npmjs.com/package/puppeteer)
|
|
127
|
+
* NPM package installed in your project.
|
|
128
|
+
* When running on the Apify cloud, you can achieve that simply
|
|
129
|
+
* by using the `apify/actor-node-chrome` base Docker image for your actor - see
|
|
130
|
+
* [Apify Actor documentation](https://docs.apify.com/actor/build#base-images)
|
|
131
|
+
* for details.
|
|
132
|
+
*
|
|
133
|
+
* For an example of usage, see the [Puppeteer proxy Example](/docs/examples/puppeteer-with-proxy).
|
|
134
|
+
*
|
|
135
|
+
* @param [launchContext]
|
|
136
|
+
* All `PuppeteerLauncher` parameters are passed via an launchContext object.
|
|
137
|
+
* If you want to pass custom `puppeteer.launch(options)` options you can use the `PuppeteerLaunchContext.launchOptions` property.
|
|
138
|
+
* @returns
|
|
139
|
+
* Promise that resolves to Puppeteer's `Browser` instance.
|
|
140
|
+
*/
|
|
141
|
+
export declare function launchPuppeteer(launchContext?: PuppeteerLaunchContext): Promise<Browser>;
|
|
142
|
+
//# sourceMappingURL=puppeteer-launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puppeteer-launcher.d.ts","sourceRoot":"","sources":["../../src/internals/puppeteer-launcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,EAAyB,cAAc,EAAE,MAAM,WAAW,CAAC;AAalE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC3G;;OAEG;IACH,aAAa,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACnC;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,eAAe,CAAC,eAAe,EAAE,OAAO,CAAC;IAC5E,iBAA0B,YAAY;;;;;;;;;;MAMpC;IAEF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAE/B;;OAEG;gBACS,aAAa,GAAE,sBAA2B;IA0BvC,MAAM;IAiBZ,mBAAmB;;;CAoC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,eAAe,CAAC,aAAa,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAI9F"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.launchPuppeteer = exports.PuppeteerLauncher = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const ow_1 = tslib_1.__importDefault(require("ow"));
|
|
6
|
+
const browser_pool_1 = require("@crawlee/browser-pool");
|
|
7
|
+
const browser_1 = require("@crawlee/browser");
|
|
8
|
+
const log_1 = tslib_1.__importDefault(require("@apify/log"));
|
|
9
|
+
const stealth_1 = require("./stealth");
|
|
10
|
+
/**
|
|
11
|
+
* The default user agent used by `Actor.launchPuppeteer`.
|
|
12
|
+
* Last updated on 2020-05-22.
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36';
|
|
15
|
+
const LAUNCH_PUPPETEER_DEFAULT_VIEWPORT = {
|
|
16
|
+
width: 1366,
|
|
17
|
+
height: 768,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* `PuppeteerLauncher` is based on the `BrowserLauncher`. It launches `puppeteer` browser instance.
|
|
21
|
+
* @ignore
|
|
22
|
+
*/
|
|
23
|
+
class PuppeteerLauncher extends browser_1.BrowserLauncher {
|
|
24
|
+
/**
|
|
25
|
+
* All `PuppeteerLauncher` parameters are passed via an launchContext object.
|
|
26
|
+
*/
|
|
27
|
+
constructor(launchContext = {}) {
|
|
28
|
+
(0, ow_1.default)(launchContext, 'PuppeteerLauncher', ow_1.default.object.exactShape(PuppeteerLauncher.optionsShape));
|
|
29
|
+
const { launcher = browser_1.BrowserLauncher.requireLauncherOrThrow('puppeteer', 'apify/actor-node-puppeteer-chrome'), userAgent, stealth = false, stealthOptions = {}, ...browserLauncherOptions } = launchContext;
|
|
30
|
+
super({
|
|
31
|
+
...browserLauncherOptions,
|
|
32
|
+
launcher,
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(this, "stealth", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
writable: true,
|
|
38
|
+
value: void 0
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(this, "stealthOptions", {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true,
|
|
44
|
+
value: void 0
|
|
45
|
+
});
|
|
46
|
+
this.userAgent = userAgent;
|
|
47
|
+
this.stealth = stealth;
|
|
48
|
+
this.stealthOptions = {
|
|
49
|
+
hideWebDriver: true,
|
|
50
|
+
...stealthOptions,
|
|
51
|
+
};
|
|
52
|
+
this.Plugin = browser_pool_1.PuppeteerPlugin;
|
|
53
|
+
}
|
|
54
|
+
async launch() {
|
|
55
|
+
const browser = await super.launch();
|
|
56
|
+
if (this.stealth) {
|
|
57
|
+
log_1.default.deprecated('Puppeteer "stealth" and "stealthOptions" are deprecated.'
|
|
58
|
+
+ ' You should use fingerprints instead.'
|
|
59
|
+
+ ' Checkout the fingerprints guide: https://sdk.apify.com/docs/guides/avoid-blocking');
|
|
60
|
+
const { hideWebDriver, ...newStealthOptions } = this.stealthOptions;
|
|
61
|
+
(0, stealth_1.applyStealthToBrowser)(browser, newStealthOptions);
|
|
62
|
+
}
|
|
63
|
+
return browser;
|
|
64
|
+
}
|
|
65
|
+
createLaunchOptions() {
|
|
66
|
+
const launchOptions = super.createLaunchOptions();
|
|
67
|
+
launchOptions.args = launchOptions.args || [];
|
|
68
|
+
try {
|
|
69
|
+
// eslint-disable-next-line
|
|
70
|
+
const { isAtHome } = require('apify');
|
|
71
|
+
if (isAtHome())
|
|
72
|
+
launchOptions.args.push('--no-sandbox');
|
|
73
|
+
// eslint-disable-next-line no-empty
|
|
74
|
+
}
|
|
75
|
+
catch { }
|
|
76
|
+
launchOptions.defaultViewport ?? (launchOptions.defaultViewport = LAUNCH_PUPPETEER_DEFAULT_VIEWPORT);
|
|
77
|
+
// When User-Agent is not set and we're using Chromium or headless mode,
|
|
78
|
+
// it is better to use DEFAULT_USER_AGENT to reduce chance of detection
|
|
79
|
+
let { userAgent } = this;
|
|
80
|
+
if (!userAgent && (!launchOptions.executablePath || launchOptions.headless)) {
|
|
81
|
+
userAgent = DEFAULT_USER_AGENT;
|
|
82
|
+
}
|
|
83
|
+
if (userAgent) {
|
|
84
|
+
launchOptions.args.push(`--user-agent=${userAgent}`);
|
|
85
|
+
}
|
|
86
|
+
if (this.stealthOptions?.hideWebDriver) {
|
|
87
|
+
const idx = launchOptions.args.findIndex((arg) => arg.startsWith('--disable-blink-features='));
|
|
88
|
+
if (idx !== -1) {
|
|
89
|
+
const arg = launchOptions.args[idx];
|
|
90
|
+
launchOptions.args[idx] = `${arg},AutomationControlled`;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
launchOptions.args.push('--disable-blink-features=AutomationControlled');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return launchOptions;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.PuppeteerLauncher = PuppeteerLauncher;
|
|
100
|
+
Object.defineProperty(PuppeteerLauncher, "optionsShape", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
configurable: true,
|
|
103
|
+
writable: true,
|
|
104
|
+
value: {
|
|
105
|
+
...browser_1.BrowserLauncher.optionsShape,
|
|
106
|
+
launcher: ow_1.default.optional.object,
|
|
107
|
+
userAgent: ow_1.default.optional.string,
|
|
108
|
+
stealth: ow_1.default.optional.boolean,
|
|
109
|
+
stealthOptions: ow_1.default.optional.object,
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
/**
|
|
113
|
+
* Launches headless Chrome using Puppeteer pre-configured to work within the Apify platform.
|
|
114
|
+
* The function has the same argument and the return value as `puppeteer.launch()`.
|
|
115
|
+
* See [Puppeteer documentation](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions) for more details.
|
|
116
|
+
*
|
|
117
|
+
* The `launchPuppeteer()` function alters the following Puppeteer options:
|
|
118
|
+
*
|
|
119
|
+
* - Passes the setting from the `APIFY_HEADLESS` environment variable to the `headless` option,
|
|
120
|
+
* unless it was already defined by the caller or `APIFY_XVFB` environment variable is set to `1`.
|
|
121
|
+
* Note that Apify Actor cloud platform automatically sets `APIFY_HEADLESS=1` to all running actors.
|
|
122
|
+
* - Takes the `proxyUrl` option, validates it and adds it to `args` as `--proxy-server=XXX`.
|
|
123
|
+
* The proxy URL must define a port number and have one of the following schemes: `http://`,
|
|
124
|
+
* `https://`, `socks4://` or `socks5://`.
|
|
125
|
+
* If the proxy is HTTP (i.e. has the `http://` scheme) and contains username or password,
|
|
126
|
+
* the `launchPuppeteer` functions sets up an anonymous proxy HTTP
|
|
127
|
+
* to make the proxy work with headless Chrome. For more information, read the
|
|
128
|
+
* [blog post about proxy-chain library](https://blog.apify.com/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212).
|
|
129
|
+
*
|
|
130
|
+
* To use this function, you need to have the [puppeteer](https://www.npmjs.com/package/puppeteer)
|
|
131
|
+
* NPM package installed in your project.
|
|
132
|
+
* When running on the Apify cloud, you can achieve that simply
|
|
133
|
+
* by using the `apify/actor-node-chrome` base Docker image for your actor - see
|
|
134
|
+
* [Apify Actor documentation](https://docs.apify.com/actor/build#base-images)
|
|
135
|
+
* for details.
|
|
136
|
+
*
|
|
137
|
+
* For an example of usage, see the [Puppeteer proxy Example](/docs/examples/puppeteer-with-proxy).
|
|
138
|
+
*
|
|
139
|
+
* @param [launchContext]
|
|
140
|
+
* All `PuppeteerLauncher` parameters are passed via an launchContext object.
|
|
141
|
+
* If you want to pass custom `puppeteer.launch(options)` options you can use the `PuppeteerLaunchContext.launchOptions` property.
|
|
142
|
+
* @returns
|
|
143
|
+
* Promise that resolves to Puppeteer's `Browser` instance.
|
|
144
|
+
*/
|
|
145
|
+
async function launchPuppeteer(launchContext) {
|
|
146
|
+
const puppeteerLauncher = new PuppeteerLauncher(launchContext);
|
|
147
|
+
return puppeteerLauncher.launch();
|
|
148
|
+
}
|
|
149
|
+
exports.launchPuppeteer = launchPuppeteer;
|
|
150
|
+
//# sourceMappingURL=puppeteer-launcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puppeteer-launcher.js","sourceRoot":"","sources":["../../src/internals/puppeteer-launcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const hackPermissions: () => void;
|
|
2
|
+
export declare const addLanguage: () => void;
|
|
3
|
+
export declare const emulateWebGL: () => void;
|
|
4
|
+
export declare const emulateWindowFrame: () => void;
|
|
5
|
+
export declare const addPlugins: () => void;
|
|
6
|
+
export declare const emulateConsoleDebug: () => void;
|
|
7
|
+
export declare const mockChrome: () => void;
|
|
8
|
+
export declare const mockChromeInIframe: () => void;
|
|
9
|
+
export declare const mockDeviceMemory: () => void;
|
|
10
|
+
//# sourceMappingURL=hiding_tricks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hiding_tricks.d.ts","sourceRoot":"","sources":["../../../src/internals/stealth/hiding_tricks.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,YAqC3B,CAAC;AAEF,eAAO,MAAM,WAAW,YAIvB,CAAC;AAEF,eAAO,MAAM,YAAY,YAoBxB,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAS9B,CAAC;AAEF,eAAO,MAAM,UAAU,YAmNtB,CAAC;AAEF,eAAO,MAAM,mBAAmB,YAI/B,CAAC;AAGF,eAAO,MAAM,UAAU,YAStB,CAAC;AAIF,eAAO,MAAM,kBAAkB,YA0D9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,YAK5B,CAAC"}
|