You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Learn which parts of Crawlee are designed to be extended, what contract each extension point defines, and where to find the detailed guide for each one.
4
+
description: The extension points Crawlee exposes, the contract each one defines, and how to choose between them.
5
5
---
6
6
7
7
importApiLinkfrom'@site/src/components/ApiLink';
8
8
9
-
Crawlee is built around a small number of abstract base classes that you can subclass to plug in your own behavior. This guide is the map: it lists every extension point, states the contract each one defines, and links to the guide that covers it in depth.
9
+
Crawlee covers the common cases out of the box, but sooner or later you'll hit something it doesn't do: a parser for a format no built-in crawler understands, an HTTP backend your company mandates, a database you want your data in, or a browser that isn't launched the standard Playwright way. Rather than forking, you can plug your own implementation into the layer that differs and keep everything else.
10
10
11
-
If you maintain a third-party integration, such as an alternative browser backend or a storage adapter, you can build it against these contracts and host the integration guide in your own project. This page gives your users a stable reference for the interface your integration implements.
11
+
This guide is the map. It covers the extension points, the contract each one defines, and links to the guide that goes deeper on it. If you maintain a third-party integration, you can build it against these contracts and host your own guide for it.
12
12
13
13
## Extension points
14
14
15
-
Crawlee currently has four extension points.
15
+
The four extension points below are the main ones, and they're where most integrations plug in. They aren't the only abstract classes you can subclass - <ApiLinkto="class/RequestLoader">`RequestLoader`</ApiLink>, <ApiLinkto="class/FingerprintGenerator">`FingerprintGenerator`</ApiLink>, and <ApiLinkto="class/RenderingTypePredictor">`RenderingTypePredictor`</ApiLink> are extensible too.
16
16
17
17
```mermaid
18
18
---
@@ -27,6 +27,10 @@ class BasicCrawler {
27
27
<<abstract>>
28
28
}
29
29
30
+
class AbstractHttpCrawler {
31
+
<<abstract>>
32
+
}
33
+
30
34
class PlaywrightCrawler
31
35
32
36
class HttpClient {
@@ -35,64 +39,91 @@ class HttpClient {
35
39
36
40
class StorageClient {
37
41
<<abstract>>
42
+
create_dataset_client()
43
+
create_kvs_client()
44
+
create_rq_client()
45
+
}
46
+
47
+
class DatasetClient {
48
+
<<abstract>>
49
+
}
50
+
51
+
class KeyValueStoreClient {
52
+
<<abstract>>
53
+
}
54
+
55
+
class RequestQueueClient {
56
+
<<abstract>>
38
57
}
39
58
40
59
class BrowserPool
41
60
42
61
class BrowserPlugin {
43
62
<<abstract>>
63
+
new_browser()
44
64
}
45
65
46
-
BasicCrawler --> HttpClient : uses
47
-
BasicCrawler --> StorageClient : uses
66
+
class BrowserController {
67
+
<<abstract>>
68
+
}
69
+
70
+
BasicCrawler --|> AbstractHttpCrawler
48
71
BasicCrawler --|> PlaywrightCrawler
72
+
AbstractHttpCrawler --> HttpClient : uses
73
+
BasicCrawler --> StorageClient : uses
74
+
StorageClient --> DatasetClient : opens
75
+
StorageClient --> KeyValueStoreClient : opens
76
+
StorageClient --> RequestQueueClient : opens
49
77
PlaywrightCrawler --> BrowserPool : uses
50
78
BrowserPool --> BrowserPlugin : manages
79
+
BrowserPlugin --> BrowserController : returns
51
80
```
52
81
53
82
### Crawlers
54
83
55
-
Subclass a crawler when you need a parsing strategy or a request-handler context that the built-in crawlers do not provide.
84
+
A crawler drives the whole run: it takes requests from the queue, fetches each one, builds the context object your handler receives, and manages retries, concurrency, sessions, and storage along the way. <ApiLinkto="class/BasicCrawler">`BasicCrawler`</ApiLink> implements all of that and stays agnostic about how a page is fetched or parsed, which is what makes it the base every other crawler builds on.
56
85
57
-
For HTTP-based crawling, <ApiLinkto="class/AbstractHttpCrawler">`AbstractHttpCrawler`</ApiLink> is the base class. A custom crawler supplies a parser that turns an HTTP response into your parsed type, a context type that exposes that parsed data to request handlers, and the crawler class that ties the two together. Everything else, including retries, concurrency, session management, and storage, is inherited from <ApiLinkto="class/BasicCrawler">`BasicCrawler`</ApiLink>.
86
+
For HTTP-based crawling, <ApiLinkto="class/AbstractHttpCrawler">`AbstractHttpCrawler`</ApiLink> adds the fetch-and-parse layer on top. Extending it means supplying a parser that implements <ApiLinkto="class/AbstractHttpParser">`AbstractHttpParser`</ApiLink>: `parse`turns an <ApiLinkto="class/HttpResponse">`HttpResponse`</ApiLink> into your parsed type, `parse_text` does the same for a string, `select` and `is_matching_selector` apply selectors to it, and `find_links` extracts the URLs used for link enqueuing. You then pair that parser with a context type that exposes the parsed data to handlers, and a crawler class that ties the two together.
58
87
59
-
See [HTTP crawlers guide](./http-crawlers) for a worked example built on `selectolax`, and [Architecture overview](./architecture-overview) for how crawlers relate to the other components.
88
+
See the [HTTP crawlers guide](./http-crawlers) for a worked example built on `selectolax`, and the[Architecture overview](./architecture-overview) for how crawlers relate to the other components.
60
89
61
90
### HTTP clients
62
91
63
-
Subclass an HTTP client when you want crawlers to talk to servers through a different HTTP library, or through a proxy or transport layer that the bundled clients do not cover.
92
+
An HTTP client is what actually performs the network calls for HTTP-based crawlers. Swapping it changes the transport - the TLS stack, connection pooling, proxy handling, and browser impersonation - without touching how pages are parsed or how the crawl is orchestrated.
64
93
65
-
<ApiLinkto="class/HttpClient">`HttpClient`</ApiLink> is the base class. Implementations must be async-compatible and must manage their own connection lifecycle and cleanup, because a single client instance is shared across concurrent requests.
94
+
The contract is <ApiLinkto="class/HttpClient">`HttpClient`</ApiLink>. `crawl` performs a request inside the crawler's pipeline and returns the result the crawler consumes, `send_request` covers standalone calls made from a handler, `stream` yields a response you read incrementally, and `cleanup` releases whatever the client holds open. Crawlee ships <ApiLinkto="class/ImpitHttpClient">`ImpitHttpClient`</ApiLink>, <ApiLinkto="class/HttpxHttpClient">`HttpxHttpClient`</ApiLink>, and <ApiLinkto="class/CurlImpersonateHttpClient">`CurlImpersonateHttpClient`</ApiLink>.
66
95
67
-
See [HTTP clients guide](./http-clients) for the full interface and the built-in implementations.
96
+
See the [HTTP clients guide](./http-clients) for the full contract and the trade-offs between the built-in clients.
68
97
69
98
### Storage clients
70
99
71
-
Subclass a storage client when you want Crawlee's storages to be backed by a system that is not covered by the built-in memory, file system, SQL, and Redis clients.
100
+
A storage client is the backend behind Crawlee's three storages. <ApiLinkto="class/Dataset">`Dataset`</ApiLink>, <ApiLinkto="class/KeyValueStore">`KeyValueStore`</ApiLink>, and <ApiLinkto="class/RequestQueue">`RequestQueue`</ApiLink> are the API you write against, and the storage client decides where that data actually lives. That separation is what lets you move a crawler from the local file system to a database or a cloud service without changing crawl code.
72
101
73
-
<ApiLinkto="class/StorageClient">`StorageClient`</ApiLink> is the base class. It is a factory: it opens the per-storage clients for datasets, key-value stores, and request queues, and those clients implement the actual create, read, update, and delete operations.
102
+
<ApiLinkto="class/StorageClient">`StorageClient`</ApiLink> itself is only three factory methods - `create_dataset_client`, `create_kvs_client`, and `create_rq_client`. The real work sits in what they return: <ApiLinkto="class/DatasetClient">`DatasetClient`</ApiLink> handles appending and reading items, <ApiLinkto="class/KeyValueStoreClient">`KeyValueStoreClient`</ApiLink> handles record get, set, delete, and iteration, and <ApiLinkto="class/RequestQueueClient">`RequestQueueClient`</ApiLink> handles adding, fetching, and marking requests as handled. A custom backend implements all four.
74
103
75
-
See [Storage clients guide](./storage-clients) for the interface, a custom client example, and how clients are registered and resolved.
104
+
See the [Storage clients guide](./storage-clients) for the built-in implementations and a custom client example.
76
105
77
106
### Browser plugins
78
107
79
-
Subclass a browser plugin when an integration launches browsers through an API other than the standard Playwright one. Configuration options on <ApiLinkto="class/PlaywrightBrowserPlugin">`PlaywrightBrowserPlugin`</ApiLink> cover the cases where the standard launch API is enough, so reach for a subclass only when the launch path itself differs.
108
+
A browser plugin is what launches browsers for <ApiLinkto="class/PlaywrightCrawler">`PlaywrightCrawler`</ApiLink>. The crawler never launches one itself: it goes through <ApiLinkto="class/BrowserPool">`BrowserPool`</ApiLink>, which initializes the plugins it's given, forwards browser context options when creating pages, and manages each browser's lifecycle.
80
109
81
-
A plugin's `new_browser()` launches the browser and returns a <ApiLinkto="class/PlaywrightBrowserController">`PlaywrightBrowserController`</ApiLink>; <ApiLinkto="class/BrowserPool">`BrowserPool`</ApiLink> initializes the plugin, forwards browser context options when creating pages, and manages the controller's lifecycle.
110
+
The contract is <ApiLinkto="class/BrowserPlugin">`BrowserPlugin`</ApiLink>. Its `new_browser` launches a browser and returns a <ApiLinkto="class/BrowserController">`BrowserController`</ApiLink>, which is what the pool then drives to open pages and tear things down. Reach for a subclass when the launch path itself differs from the standard Playwright one, since <ApiLinkto="class/PlaywrightBrowserPlugin">`PlaywrightBrowserPlugin`</ApiLink>'s configuration options already cover the cases where it doesn't.
82
111
83
-
See [Playwright crawler guide](./playwright-crawler) for the contract and the responsibilities a subclass has to preserve, and the [Camoufox example](../examples/playwright-crawler-with-camoufox) for a complete integration.
112
+
See the [Playwright crawler guide](./playwright-crawler) for the responsibilities a subclass has to preserve, and the [Camoufox example](../examples/playwright-crawler-with-camoufox) for a complete integration.
84
113
85
114
## Choosing an extension point
86
115
87
116
Match the layer to what actually differs in your integration.
88
117
89
-
- The response is fetched the usual way but parsed differently: extend a **crawler**.
90
-
- The response is fetched over a different HTTP library or transport: extend an **HTTP client**.
91
-
-Requests and results should live somewhere other than the built-in backends: extend a **storage client**.
92
-
- Browsers are launched through a different API: extend a **browser plugin**.
118
+
- The response format is one no built-in crawler parses - subclass <ApiLinkto="class/AbstractHttpCrawler">`AbstractHttpCrawler`</ApiLink> with your own parser.
119
+
- The transport differs, but parsing doesn't - implement <ApiLinkto="class/HttpClient">`HttpClient`</ApiLink> and pass it to any HTTP crawler.
120
+
-Data needs to live somewhere Crawlee doesn't support yet - implement <ApiLinkto="class/StorageClient">`StorageClient`</ApiLink> and its three per-storage clients.
121
+
- Browsers need to be launched through a different API - implement <ApiLinkto="class/BrowserPlugin">`BrowserPlugin`</ApiLink> and hand it to <ApiLinkto="class/BrowserPool">`BrowserPool`</ApiLink>.
93
122
94
-
Prefer configuration over a subclass wherever the built-in class already exposes the knob you need. Subclassing ties your integration to a contract that only changes with Crawlee's major versions, while configuration keeps you on the maintained path.
123
+
When more than one fits, pick the narrowest. A custom HTTP client works with every HTTP crawler, so it's easier to maintain than a crawler subclass that hard-codes the same transport.
95
124
96
125
## Conclusion
97
126
98
-
Crawlee's extension points are crawlers, HTTP clients, storage clients, and browser plugins. Each is an abstract base class with a documented contract and a guide that covers it in depth. If you are building an integration, start from the contract that matches the layer you are replacing, and keep the rest of the pipeline on the built-in path.
127
+
Each extension point is a small abstract class with a documented contract, and everything above it keeps working once you implement one. If you're building a third-party integration, these contracts are also the stable surface to write your own documentation against.
128
+
129
+
If anything here is unclear or you hit a case the contracts don't cover, open an issue on [GitHub](https://github.com/apify/crawlee-python) or join our [Discord](https://discord.com/invite/jyEM2PRvMU).
0 commit comments