pydoll-python 2.19.0__tar.gz → 2.20.2__tar.gz
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.
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/PKG-INFO +62 -54
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/README.md +61 -53
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/chromium/base.py +1 -1
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/requests/__init__.py +2 -1
- pydoll_python-2.20.2/pydoll/browser/requests/har_recorder.py +638 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/requests/request.py +69 -21
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/tab.py +181 -48
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/connection/connection_handler.py +1 -1
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/mixins/find_elements_mixin.py +2 -2
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/exceptions.py +6 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/interactions/mouse.py +14 -0
- pydoll_python-2.20.2/pydoll/protocol/network/har_types.py +144 -0
- pydoll_python-2.20.2/pydoll/utils/bundle.py +196 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pyproject.toml +1 -1
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/LICENSE +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/chromium/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/chromium/chrome.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/chromium/edge.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/interfaces.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/managers/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/managers/browser_options_manager.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/managers/browser_process_manager.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/managers/proxy_manager.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/managers/temp_dir_manager.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/options.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/browser/requests/response.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/browser_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/dom_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/emulation_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/fetch_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/input_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/network_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/page_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/runtime_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/storage_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/commands/target_commands.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/connection/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/connection/managers/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/connection/managers/commands_manager.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/connection/managers/events_manager.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/constants.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/decorators.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/mixins/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/shadow_root.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/utils/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/utils/selector_parser.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/elements/web_element.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/interactions/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/interactions/iframe.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/interactions/keyboard.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/interactions/scroll.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/interactions/utils.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/base.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/browser/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/browser/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/browser/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/browser/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/debugger/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/dom/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/dom/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/dom/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/dom/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/emulation/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/emulation/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/emulation/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/fetch/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/fetch/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/fetch/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/fetch/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/input/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/input/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/input/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/input/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/io/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/network/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/network/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/network/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/network/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/page/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/page/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/page/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/page/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/runtime/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/runtime/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/runtime/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/runtime/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/security/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/storage/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/storage/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/storage/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/storage/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/target/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/target/events.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/target/methods.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/protocol/target/types.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/py.typed +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/utils/__init__.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/utils/general.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/utils/socks5_proxy_forwarder.py +0 -0
- {pydoll_python-2.19.0 → pydoll_python-2.20.2}/pydoll/utils/user_agent_parser.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydoll-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.20.2
|
|
4
4
|
Summary: Pydoll is a library for automating chromium-based browsers without a WebDriver, offering realistic interactions.
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Author: Thalison Fernandes
|
|
@@ -84,11 +84,66 @@ That's it. No `webdrivers`. No external dependencies.
|
|
|
84
84
|
|
|
85
85
|
## 🆕 What's New
|
|
86
86
|
|
|
87
|
+
<details>
|
|
88
|
+
<summary><b>HAR Network Recording: Capture & Replay Network Traffic</b></summary>
|
|
89
|
+
<br>
|
|
90
|
+
|
|
91
|
+
Record all network activity during a browser session and export it as a standard **HAR 1.2** file. Replay recorded requests to reproduce exact API sequences.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from pydoll.browser.chromium import Chrome
|
|
95
|
+
|
|
96
|
+
async with Chrome() as browser:
|
|
97
|
+
tab = await browser.start()
|
|
98
|
+
|
|
99
|
+
# Record all network traffic
|
|
100
|
+
async with tab.request.record() as capture:
|
|
101
|
+
await tab.go_to('https://example.com')
|
|
102
|
+
|
|
103
|
+
capture.save('flow.har')
|
|
104
|
+
print(f'Captured {len(capture.entries)} requests')
|
|
105
|
+
|
|
106
|
+
# Replay later
|
|
107
|
+
responses = await tab.request.replay('flow.har')
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Filter by resource type** to capture only what you need:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from pydoll.protocol.network.types import ResourceType
|
|
114
|
+
|
|
115
|
+
# Record only fetch/XHR requests (skip documents, images, etc.)
|
|
116
|
+
async with tab.request.record(
|
|
117
|
+
resource_types=[ResourceType.FETCH, ResourceType.XHR]
|
|
118
|
+
) as capture:
|
|
119
|
+
await tab.go_to('https://example.com')
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
[**📖 HAR Recording Docs**](https://pydoll.tech/docs/features/network/network-recording/)
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
<details>
|
|
126
|
+
<summary><b>Page Bundles: Save Pages for Offline Viewing</b></summary>
|
|
127
|
+
<br>
|
|
128
|
+
|
|
129
|
+
Save the current page and all its assets (CSS, JS, images, fonts) as a single `.zip` bundle for offline viewing. Choose between separate asset files or a fully self-contained HTML with everything inlined.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
# Save with separate asset files
|
|
133
|
+
await tab.save_bundle('page.zip')
|
|
134
|
+
|
|
135
|
+
# Or inline everything into a single HTML
|
|
136
|
+
await tab.save_bundle('page-inline.zip', inline_assets=True)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
[**📖 Screenshots, PDFs & Bundles Docs**](https://pydoll.tech/docs/features/automation/screenshots-and-pdfs/)
|
|
140
|
+
</details>
|
|
141
|
+
|
|
87
142
|
<details>
|
|
88
143
|
<summary><b>Shadow DOM Support: Access Closed Shadow Roots with Zero Effort</b></summary>
|
|
89
144
|
<br>
|
|
90
145
|
|
|
91
|
-
Pydoll
|
|
146
|
+
Pydoll provides **full Shadow DOM support**, automatically handling both open and closed shadow roots, something traditional automation tools can't do. Because Pydoll operates at the CDP level (below JavaScript), the `closed` mode restriction simply doesn't apply.
|
|
92
147
|
|
|
93
148
|
```python
|
|
94
149
|
# Get the shadow root of a specific element
|
|
@@ -106,11 +161,11 @@ for sr in shadow_roots:
|
|
|
106
161
|
|
|
107
162
|
**Key highlights:**
|
|
108
163
|
|
|
109
|
-
- **Closed shadow roots just work
|
|
164
|
+
- **Closed shadow roots just work**: no workarounds, no hacks
|
|
110
165
|
- **`find_shadow_roots()`** discovers every shadow root on the page, even when you don't know the host selector
|
|
111
|
-
- **`timeout` parameter** for polling until shadow roots appear asynchronously
|
|
112
|
-
- **`deep=True`** traverses cross-origin iframes (OOPIFs)
|
|
113
|
-
- **Same familiar API
|
|
166
|
+
- **`timeout` parameter** for polling until shadow roots appear asynchronously, works on both `find_shadow_roots()` and `get_shadow_root()`
|
|
167
|
+
- **`deep=True`** traverses cross-origin iframes (OOPIFs), essential for widgets like Cloudflare Turnstile captchas
|
|
168
|
+
- **Same familiar API**: use `find()`, `query()`, and `click()` inside shadow roots just like anywhere else
|
|
114
169
|
|
|
115
170
|
```python
|
|
116
171
|
# Real-world example: Cloudflare Turnstile inside a cross-origin iframe
|
|
@@ -124,53 +179,6 @@ for sr in shadow_roots:
|
|
|
124
179
|
[**📖 Shadow DOM Docs**](https://pydoll.tech/docs/deep-dive/architecture/shadow-dom/)
|
|
125
180
|
</details>
|
|
126
181
|
|
|
127
|
-
<details>
|
|
128
|
-
<summary><b>Humanized Keyboard Input</b></summary>
|
|
129
|
-
<br>
|
|
130
|
-
|
|
131
|
-
Pydoll's typing engine simulates realistic human typing behavior out of the box:
|
|
132
|
-
|
|
133
|
-
- **Variable keystroke timing**: 30-120ms between keys (not fixed intervals)
|
|
134
|
-
- **Realistic typos**: ~2% error rate with automatic correction behavior
|
|
135
|
-
|
|
136
|
-
```python
|
|
137
|
-
# Realistic typing by default
|
|
138
|
-
await element.type_text("hello")
|
|
139
|
-
|
|
140
|
-
# Opt out when speed is critical
|
|
141
|
-
await element.type_text("hello", humanize=False)
|
|
142
|
-
```
|
|
143
|
-
</details>
|
|
144
|
-
|
|
145
|
-
<details>
|
|
146
|
-
<summary><b>Humanized Scroll with Physics Engine</b></summary>
|
|
147
|
-
<br>
|
|
148
|
-
|
|
149
|
-
The scroll API features a **Cubic Bezier curve physics engine** for realistic scrolling:
|
|
150
|
-
|
|
151
|
-
- **Momentum & friction**: Natural acceleration and deceleration
|
|
152
|
-
- **Micro-pauses**: Brief stops during long scrolls (simulates reading)
|
|
153
|
-
- **Jitter injection**: Small random variations in scroll path
|
|
154
|
-
- **Overshoot correction**: Occasionally scrolls past target and corrects back
|
|
155
|
-
|
|
156
|
-
```python
|
|
157
|
-
# Humanized by default (physics engine, anti-bot)
|
|
158
|
-
await tab.scroll.by(ScrollPosition.DOWN, 500)
|
|
159
|
-
await tab.scroll.to_bottom()
|
|
160
|
-
|
|
161
|
-
# CSS smooth scroll (predictable timing)
|
|
162
|
-
await tab.scroll.by(ScrollPosition.DOWN, 500, humanize=False, smooth=True)
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
| Mode | Parameter | Use Case |
|
|
166
|
-
|------|-----------|----------|
|
|
167
|
-
| **Humanized** | default | **Anti-bot evasion** |
|
|
168
|
-
| **Smooth** | `humanize=False, smooth=True` | General browsing simulation |
|
|
169
|
-
| **Instant** | `humanize=False, smooth=False` | Speed-critical operations |
|
|
170
|
-
|
|
171
|
-
[**📖 Human-Like Interactions Docs**](https://pydoll.tech/docs/features/automation/human-interactions/)
|
|
172
|
-
</details>
|
|
173
|
-
|
|
174
182
|
<details>
|
|
175
183
|
<summary><b>Humanized Mouse Movement</b></summary>
|
|
176
184
|
<br>
|
|
@@ -433,6 +441,6 @@ If you find Pydoll useful, consider [sponsoring my work on GitHub](https://githu
|
|
|
433
441
|
Pydoll is licensed under the [MIT License](LICENSE).
|
|
434
442
|
|
|
435
443
|
<p align="center">
|
|
436
|
-
|
|
444
|
+
<b>Pydoll</b>: Web automation, taken seriously.
|
|
437
445
|
</p>
|
|
438
446
|
|
|
@@ -64,11 +64,66 @@ That's it. No `webdrivers`. No external dependencies.
|
|
|
64
64
|
|
|
65
65
|
## 🆕 What's New
|
|
66
66
|
|
|
67
|
+
<details>
|
|
68
|
+
<summary><b>HAR Network Recording: Capture & Replay Network Traffic</b></summary>
|
|
69
|
+
<br>
|
|
70
|
+
|
|
71
|
+
Record all network activity during a browser session and export it as a standard **HAR 1.2** file. Replay recorded requests to reproduce exact API sequences.
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from pydoll.browser.chromium import Chrome
|
|
75
|
+
|
|
76
|
+
async with Chrome() as browser:
|
|
77
|
+
tab = await browser.start()
|
|
78
|
+
|
|
79
|
+
# Record all network traffic
|
|
80
|
+
async with tab.request.record() as capture:
|
|
81
|
+
await tab.go_to('https://example.com')
|
|
82
|
+
|
|
83
|
+
capture.save('flow.har')
|
|
84
|
+
print(f'Captured {len(capture.entries)} requests')
|
|
85
|
+
|
|
86
|
+
# Replay later
|
|
87
|
+
responses = await tab.request.replay('flow.har')
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Filter by resource type** to capture only what you need:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from pydoll.protocol.network.types import ResourceType
|
|
94
|
+
|
|
95
|
+
# Record only fetch/XHR requests (skip documents, images, etc.)
|
|
96
|
+
async with tab.request.record(
|
|
97
|
+
resource_types=[ResourceType.FETCH, ResourceType.XHR]
|
|
98
|
+
) as capture:
|
|
99
|
+
await tab.go_to('https://example.com')
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
[**📖 HAR Recording Docs**](https://pydoll.tech/docs/features/network/network-recording/)
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
<details>
|
|
106
|
+
<summary><b>Page Bundles: Save Pages for Offline Viewing</b></summary>
|
|
107
|
+
<br>
|
|
108
|
+
|
|
109
|
+
Save the current page and all its assets (CSS, JS, images, fonts) as a single `.zip` bundle for offline viewing. Choose between separate asset files or a fully self-contained HTML with everything inlined.
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
# Save with separate asset files
|
|
113
|
+
await tab.save_bundle('page.zip')
|
|
114
|
+
|
|
115
|
+
# Or inline everything into a single HTML
|
|
116
|
+
await tab.save_bundle('page-inline.zip', inline_assets=True)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
[**📖 Screenshots, PDFs & Bundles Docs**](https://pydoll.tech/docs/features/automation/screenshots-and-pdfs/)
|
|
120
|
+
</details>
|
|
121
|
+
|
|
67
122
|
<details>
|
|
68
123
|
<summary><b>Shadow DOM Support: Access Closed Shadow Roots with Zero Effort</b></summary>
|
|
69
124
|
<br>
|
|
70
125
|
|
|
71
|
-
Pydoll
|
|
126
|
+
Pydoll provides **full Shadow DOM support**, automatically handling both open and closed shadow roots, something traditional automation tools can't do. Because Pydoll operates at the CDP level (below JavaScript), the `closed` mode restriction simply doesn't apply.
|
|
72
127
|
|
|
73
128
|
```python
|
|
74
129
|
# Get the shadow root of a specific element
|
|
@@ -86,11 +141,11 @@ for sr in shadow_roots:
|
|
|
86
141
|
|
|
87
142
|
**Key highlights:**
|
|
88
143
|
|
|
89
|
-
- **Closed shadow roots just work
|
|
144
|
+
- **Closed shadow roots just work**: no workarounds, no hacks
|
|
90
145
|
- **`find_shadow_roots()`** discovers every shadow root on the page, even when you don't know the host selector
|
|
91
|
-
- **`timeout` parameter** for polling until shadow roots appear asynchronously
|
|
92
|
-
- **`deep=True`** traverses cross-origin iframes (OOPIFs)
|
|
93
|
-
- **Same familiar API
|
|
146
|
+
- **`timeout` parameter** for polling until shadow roots appear asynchronously, works on both `find_shadow_roots()` and `get_shadow_root()`
|
|
147
|
+
- **`deep=True`** traverses cross-origin iframes (OOPIFs), essential for widgets like Cloudflare Turnstile captchas
|
|
148
|
+
- **Same familiar API**: use `find()`, `query()`, and `click()` inside shadow roots just like anywhere else
|
|
94
149
|
|
|
95
150
|
```python
|
|
96
151
|
# Real-world example: Cloudflare Turnstile inside a cross-origin iframe
|
|
@@ -104,53 +159,6 @@ for sr in shadow_roots:
|
|
|
104
159
|
[**📖 Shadow DOM Docs**](https://pydoll.tech/docs/deep-dive/architecture/shadow-dom/)
|
|
105
160
|
</details>
|
|
106
161
|
|
|
107
|
-
<details>
|
|
108
|
-
<summary><b>Humanized Keyboard Input</b></summary>
|
|
109
|
-
<br>
|
|
110
|
-
|
|
111
|
-
Pydoll's typing engine simulates realistic human typing behavior out of the box:
|
|
112
|
-
|
|
113
|
-
- **Variable keystroke timing**: 30-120ms between keys (not fixed intervals)
|
|
114
|
-
- **Realistic typos**: ~2% error rate with automatic correction behavior
|
|
115
|
-
|
|
116
|
-
```python
|
|
117
|
-
# Realistic typing by default
|
|
118
|
-
await element.type_text("hello")
|
|
119
|
-
|
|
120
|
-
# Opt out when speed is critical
|
|
121
|
-
await element.type_text("hello", humanize=False)
|
|
122
|
-
```
|
|
123
|
-
</details>
|
|
124
|
-
|
|
125
|
-
<details>
|
|
126
|
-
<summary><b>Humanized Scroll with Physics Engine</b></summary>
|
|
127
|
-
<br>
|
|
128
|
-
|
|
129
|
-
The scroll API features a **Cubic Bezier curve physics engine** for realistic scrolling:
|
|
130
|
-
|
|
131
|
-
- **Momentum & friction**: Natural acceleration and deceleration
|
|
132
|
-
- **Micro-pauses**: Brief stops during long scrolls (simulates reading)
|
|
133
|
-
- **Jitter injection**: Small random variations in scroll path
|
|
134
|
-
- **Overshoot correction**: Occasionally scrolls past target and corrects back
|
|
135
|
-
|
|
136
|
-
```python
|
|
137
|
-
# Humanized by default (physics engine, anti-bot)
|
|
138
|
-
await tab.scroll.by(ScrollPosition.DOWN, 500)
|
|
139
|
-
await tab.scroll.to_bottom()
|
|
140
|
-
|
|
141
|
-
# CSS smooth scroll (predictable timing)
|
|
142
|
-
await tab.scroll.by(ScrollPosition.DOWN, 500, humanize=False, smooth=True)
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
| Mode | Parameter | Use Case |
|
|
146
|
-
|------|-----------|----------|
|
|
147
|
-
| **Humanized** | default | **Anti-bot evasion** |
|
|
148
|
-
| **Smooth** | `humanize=False, smooth=True` | General browsing simulation |
|
|
149
|
-
| **Instant** | `humanize=False, smooth=False` | Speed-critical operations |
|
|
150
|
-
|
|
151
|
-
[**📖 Human-Like Interactions Docs**](https://pydoll.tech/docs/features/automation/human-interactions/)
|
|
152
|
-
</details>
|
|
153
|
-
|
|
154
162
|
<details>
|
|
155
163
|
<summary><b>Humanized Mouse Movement</b></summary>
|
|
156
164
|
<br>
|
|
@@ -413,5 +421,5 @@ If you find Pydoll useful, consider [sponsoring my work on GitHub](https://githu
|
|
|
413
421
|
Pydoll is licensed under the [MIT License](LICENSE).
|
|
414
422
|
|
|
415
423
|
<p align="center">
|
|
416
|
-
|
|
424
|
+
<b>Pydoll</b>: Web automation, taken seriously.
|
|
417
425
|
</p>
|
|
@@ -881,7 +881,7 @@ class Browser(ABC): # noqa: PLR0904
|
|
|
881
881
|
return False
|
|
882
882
|
|
|
883
883
|
async def _execute_command(
|
|
884
|
-
self, command: Command[T_CommandParams, T_CommandResponse], timeout: int =
|
|
884
|
+
self, command: Command[T_CommandParams, T_CommandResponse], timeout: int = 60
|
|
885
885
|
) -> T_CommandResponse:
|
|
886
886
|
"""Execute CDP command and return result (core method for browser communication)."""
|
|
887
887
|
logger.debug(f'Executing command: {command.get("method")} (timeout={timeout})')
|
|
@@ -3,7 +3,8 @@ This module provides HTTP client functionality using the browser's fetch API.
|
|
|
3
3
|
It allows making HTTP requests within the browser context, reusing cookies and headers.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
from .har_recorder import HarCapture
|
|
6
7
|
from .request import Request
|
|
7
8
|
from .response import Response
|
|
8
9
|
|
|
9
|
-
__all__ = ['Request', 'Response']
|
|
10
|
+
__all__ = ['HarCapture', 'Request', 'Response']
|