pydoll-python 1.7.0__tar.gz → 2.0.1__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.
Files changed (131) hide show
  1. pydoll_python-2.0.1/PKG-INFO +401 -0
  2. pydoll_python-2.0.1/README.md +381 -0
  3. pydoll_python-2.0.1/pydoll/browser/__init__.py +4 -0
  4. pydoll_python-2.0.1/pydoll/browser/chromium/__init__.py +7 -0
  5. pydoll_python-2.0.1/pydoll/browser/chromium/base.py +549 -0
  6. pydoll_python-2.0.1/pydoll/browser/chromium/chrome.py +61 -0
  7. pydoll_python-2.0.1/pydoll/browser/chromium/edge.py +67 -0
  8. pydoll_python-2.0.1/pydoll/browser/interfaces.py +27 -0
  9. pydoll_python-2.0.1/pydoll/browser/managers/__init__.py +15 -0
  10. pydoll_python-2.0.1/pydoll/browser/managers/browser_options_manager.py +46 -0
  11. pydoll_python-2.0.1/pydoll/browser/managers/browser_process_manager.py +72 -0
  12. pydoll_python-2.0.1/pydoll/browser/managers/proxy_manager.py +85 -0
  13. pydoll_python-2.0.1/pydoll/browser/managers/temp_dir_manager.py +96 -0
  14. {pydoll_python-1.7.0 → pydoll_python-2.0.1}/pydoll/browser/options.py +9 -15
  15. pydoll_python-2.0.1/pydoll/browser/tab.py +695 -0
  16. pydoll_python-2.0.1/pydoll/commands/__init__.py +22 -0
  17. pydoll_python-2.0.1/pydoll/commands/browser_commands.py +239 -0
  18. pydoll_python-2.0.1/pydoll/commands/dom_commands.py +1272 -0
  19. pydoll_python-2.0.1/pydoll/commands/fetch_commands.py +310 -0
  20. pydoll_python-2.0.1/pydoll/commands/input_commands.py +615 -0
  21. pydoll_python-2.0.1/pydoll/commands/network_commands.py +945 -0
  22. pydoll_python-2.0.1/pydoll/commands/page_commands.py +848 -0
  23. pydoll_python-2.0.1/pydoll/commands/runtime_commands.py +512 -0
  24. pydoll_python-2.0.1/pydoll/commands/storage_commands.py +726 -0
  25. pydoll_python-2.0.1/pydoll/commands/target_commands.py +400 -0
  26. pydoll_python-2.0.1/pydoll/connection/__init__.py +5 -0
  27. pydoll_python-2.0.1/pydoll/connection/connection_handler.py +259 -0
  28. pydoll_python-2.0.1/pydoll/connection/managers/__init__.py +7 -0
  29. pydoll_python-2.0.1/pydoll/connection/managers/commands_manager.py +47 -0
  30. pydoll_python-2.0.1/pydoll/connection/managers/events_manager.py +115 -0
  31. pydoll_python-2.0.1/pydoll/constants.py +915 -0
  32. pydoll_python-2.0.1/pydoll/elements/mixins/__init__.py +5 -0
  33. pydoll_python-2.0.1/pydoll/elements/mixins/find_elements_mixin.py +501 -0
  34. pydoll_python-2.0.1/pydoll/elements/web_element.py +397 -0
  35. pydoll_python-2.0.1/pydoll/exceptions.py +235 -0
  36. pydoll_python-2.0.1/pydoll/protocol/__init__.py +1 -0
  37. pydoll_python-2.0.1/pydoll/protocol/base.py +47 -0
  38. pydoll_python-2.0.1/pydoll/protocol/browser/__init__.py +1 -0
  39. pydoll_python-2.0.1/pydoll/protocol/browser/events.py +35 -0
  40. pydoll_python-2.0.1/pydoll/protocol/browser/methods.py +23 -0
  41. pydoll_python-2.0.1/pydoll/protocol/browser/params.py +48 -0
  42. pydoll_python-2.0.1/pydoll/protocol/browser/responses.py +32 -0
  43. pydoll_python-2.0.1/pydoll/protocol/browser/types.py +13 -0
  44. pydoll_python-2.0.1/pydoll/protocol/dom/__init__.py +1 -0
  45. pydoll_python-2.0.1/pydoll/protocol/dom/events.py +149 -0
  46. pydoll_python-2.0.1/pydoll/protocol/dom/methods.py +56 -0
  47. pydoll_python-2.0.1/pydoll/protocol/dom/params.py +228 -0
  48. pydoll_python-2.0.1/pydoll/protocol/dom/responses.py +253 -0
  49. pydoll_python-2.0.1/pydoll/protocol/dom/types.py +81 -0
  50. pydoll_python-2.0.1/pydoll/protocol/fetch/__init__.py +1 -0
  51. pydoll_python-2.0.1/pydoll/protocol/fetch/events.py +57 -0
  52. pydoll_python-2.0.1/pydoll/protocol/fetch/methods.py +13 -0
  53. pydoll_python-2.0.1/pydoll/protocol/fetch/params.py +58 -0
  54. pydoll_python-2.0.1/pydoll/protocol/fetch/responses.py +18 -0
  55. pydoll_python-2.0.1/pydoll/protocol/fetch/types.py +22 -0
  56. pydoll_python-2.0.1/pydoll/protocol/input/__init__.py +1 -0
  57. pydoll_python-2.0.1/pydoll/protocol/input/events.py +20 -0
  58. pydoll_python-2.0.1/pydoll/protocol/input/methods.py +17 -0
  59. pydoll_python-2.0.1/pydoll/protocol/input/params.py +132 -0
  60. pydoll_python-2.0.1/pydoll/protocol/input/types.py +28 -0
  61. pydoll_python-2.0.1/pydoll/protocol/network/__init__.py +1 -0
  62. pydoll_python-2.0.1/pydoll/protocol/network/events.py +518 -0
  63. pydoll_python-2.0.1/pydoll/protocol/network/methods.py +35 -0
  64. pydoll_python-2.0.1/pydoll/protocol/network/params.py +214 -0
  65. pydoll_python-2.0.1/pydoll/protocol/network/responses.py +180 -0
  66. pydoll_python-2.0.1/pydoll/protocol/network/types.py +152 -0
  67. pydoll_python-2.0.1/pydoll/protocol/page/__init__.py +1 -0
  68. pydoll_python-2.0.1/pydoll/protocol/page/events.py +257 -0
  69. pydoll_python-2.0.1/pydoll/protocol/page/methods.py +52 -0
  70. pydoll_python-2.0.1/pydoll/protocol/page/params.py +242 -0
  71. pydoll_python-2.0.1/pydoll/protocol/page/responses.py +245 -0
  72. pydoll_python-2.0.1/pydoll/protocol/page/types.py +263 -0
  73. pydoll_python-2.0.1/pydoll/protocol/runtime/__init__.py +1 -0
  74. pydoll_python-2.0.1/pydoll/protocol/runtime/events.py +93 -0
  75. pydoll_python-2.0.1/pydoll/protocol/runtime/methods.py +27 -0
  76. pydoll_python-2.0.1/pydoll/protocol/runtime/params.py +113 -0
  77. pydoll_python-2.0.1/pydoll/protocol/runtime/responses.py +104 -0
  78. pydoll_python-2.0.1/pydoll/protocol/runtime/types.py +130 -0
  79. pydoll_python-2.0.1/pydoll/protocol/storage/__init__.py +1 -0
  80. pydoll_python-2.0.1/pydoll/protocol/storage/events.py +186 -0
  81. pydoll_python-2.0.1/pydoll/protocol/storage/methods.py +43 -0
  82. pydoll_python-2.0.1/pydoll/protocol/storage/params.py +154 -0
  83. pydoll_python-2.0.1/pydoll/protocol/storage/responses.py +109 -0
  84. pydoll_python-2.0.1/pydoll/protocol/storage/types.py +36 -0
  85. pydoll_python-2.0.1/pydoll/protocol/target/__init__.py +1 -0
  86. pydoll_python-2.0.1/pydoll/protocol/target/events.py +77 -0
  87. pydoll_python-2.0.1/pydoll/protocol/target/methods.py +21 -0
  88. pydoll_python-2.0.1/pydoll/protocol/target/params.py +88 -0
  89. pydoll_python-2.0.1/pydoll/protocol/target/responses.py +59 -0
  90. pydoll_python-2.0.1/pydoll/protocol/target/types.py +19 -0
  91. pydoll_python-2.0.1/pydoll/utils.py +72 -0
  92. {pydoll_python-1.7.0 → pydoll_python-2.0.1}/pyproject.toml +14 -4
  93. pydoll_python-1.7.0/PKG-INFO +0 -812
  94. pydoll_python-1.7.0/README.md +0 -792
  95. pydoll_python-1.7.0/pydoll/browser/__init__.py +0 -4
  96. pydoll_python-1.7.0/pydoll/browser/base.py +0 -594
  97. pydoll_python-1.7.0/pydoll/browser/chrome.py +0 -69
  98. pydoll_python-1.7.0/pydoll/browser/constants.py +0 -6
  99. pydoll_python-1.7.0/pydoll/browser/edge.py +0 -78
  100. pydoll_python-1.7.0/pydoll/browser/managers.py +0 -387
  101. pydoll_python-1.7.0/pydoll/browser/page.py +0 -798
  102. pydoll_python-1.7.0/pydoll/commands/__init__.py +0 -22
  103. pydoll_python-1.7.0/pydoll/commands/browser.py +0 -127
  104. pydoll_python-1.7.0/pydoll/commands/dom.py +0 -397
  105. pydoll_python-1.7.0/pydoll/commands/fetch.py +0 -315
  106. pydoll_python-1.7.0/pydoll/commands/input.py +0 -195
  107. pydoll_python-1.7.0/pydoll/commands/network.py +0 -364
  108. pydoll_python-1.7.0/pydoll/commands/page.py +0 -210
  109. pydoll_python-1.7.0/pydoll/commands/runtime.py +0 -92
  110. pydoll_python-1.7.0/pydoll/commands/storage.py +0 -54
  111. pydoll_python-1.7.0/pydoll/commands/target.py +0 -101
  112. pydoll_python-1.7.0/pydoll/common/__init__.py +0 -1
  113. pydoll_python-1.7.0/pydoll/common/keyboard.py +0 -101
  114. pydoll_python-1.7.0/pydoll/common/keys.py +0 -52
  115. pydoll_python-1.7.0/pydoll/connection/connection.py +0 -419
  116. pydoll_python-1.7.0/pydoll/connection/managers.py +0 -262
  117. pydoll_python-1.7.0/pydoll/constants.py +0 -125
  118. pydoll_python-1.7.0/pydoll/element.py +0 -523
  119. pydoll_python-1.7.0/pydoll/events/__init__.py +0 -13
  120. pydoll_python-1.7.0/pydoll/events/browser.py +0 -26
  121. pydoll_python-1.7.0/pydoll/events/dom.py +0 -108
  122. pydoll_python-1.7.0/pydoll/events/fetch.py +0 -29
  123. pydoll_python-1.7.0/pydoll/events/network.py +0 -160
  124. pydoll_python-1.7.0/pydoll/events/page.py +0 -163
  125. pydoll_python-1.7.0/pydoll/exceptions.py +0 -99
  126. pydoll_python-1.7.0/pydoll/mixins/__init__.py +0 -0
  127. pydoll_python-1.7.0/pydoll/mixins/find_elements.py +0 -244
  128. pydoll_python-1.7.0/pydoll/utils.py +0 -50
  129. {pydoll_python-1.7.0 → pydoll_python-2.0.1}/LICENSE +0 -0
  130. {pydoll_python-1.7.0 → pydoll_python-2.0.1}/pydoll/__init__.py +0 -0
  131. {pydoll_python-1.7.0/pydoll/connection → pydoll_python-2.0.1/pydoll/elements}/__init__.py +0 -0
@@ -0,0 +1,401 @@
1
+ Metadata-Version: 2.3
2
+ Name: pydoll-python
3
+ Version: 2.0.1
4
+ Summary:
5
+ Author: Thalison Fernandes
6
+ Author-email: thalissfernandes99@gmail.com
7
+ Requires-Python: >=3.10,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: aiofiles (>=23.2.1,<24.0.0)
14
+ Requires-Dist: aiohttp (>=3.9.5,<4.0.0)
15
+ Requires-Dist: bs4 (>=0.0.2,<0.0.3)
16
+ Requires-Dist: mkdocstrings (>=0.29.1,<0.30.0)
17
+ Requires-Dist: websockets (>=13.1,<14.0)
18
+ Description-Content-Type: text/markdown
19
+
20
+ <p align="center">
21
+ <img src="https://github.com/user-attachments/assets/219f2dbc-37ed-4aea-a289-ba39cdbb335d" alt="Pydoll Logo" /> <br><br>
22
+ </p>
23
+
24
+ <p align="center">
25
+ <a href="https://codecov.io/gh/autoscrape-labs/pydoll">
26
+ <img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
27
+ </a>
28
+ <img src="https://github.com/thalissonvs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
29
+ <img src="https://github.com/thalissonvs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
30
+ <img src="https://github.com/thalissonvs/pydoll/actions/workflows/release.yml/badge.svg" alt="Release">
31
+ <img src="https://github.com/thalissonvs/pydoll/actions/workflows/mypy.yml/badge.svg" alt="MyPy CI">
32
+ </p>
33
+
34
+ <p align="center">
35
+ <a href="https://autoscrape-labs.github.io/pydoll/">Documentation</a> •
36
+ <a href="#getting-started">Getting Started</a> •
37
+ <a href="#advanced-features">Advanced Features</a> •
38
+ <a href="#contributing">Contributing</a> •
39
+ <a href="#support-my-work">Support</a> •
40
+ <a href="#license">License</a>
41
+ </p>
42
+
43
+
44
+ ## Key Features
45
+
46
+ 🔹 **Zero Webdrivers!** Say goodbye to webdriver compatibility nightmares
47
+ 🔹 **Native Captcha Bypass!** Smoothly handles Cloudflare Turnstile and reCAPTCHA v3*
48
+ 🔹 **Async Performance** for lightning-fast automation
49
+ 🔹 **Human-like Interactions** that mimic real user behavior
50
+ 🔹 **Powerful Event System** for reactive automations
51
+ 🔹 **Multi-browser Support** including Chrome and Edge
52
+
53
+ ## Why Pydoll Exists
54
+
55
+ Picture this: you need to automate browser tasks. Maybe it's testing your web application, scraping data from websites, or automating repetitive processes. Traditionally, this meant dealing with external drivers, complex configurations, and a host of compatibility issues that seemed to appear out of nowhere.
56
+
57
+ But there's another challenge that's even more frustrating: **modern web protection systems**. Cloudflare Turnstile captchas, reCAPTCHA v3, and sophisticated bot detection algorithms that can instantly identify and block traditional automation tools. Your perfectly written automation script fails not because of bugs, but because websites can tell it's not human.
58
+
59
+ **Pydoll was born to change that.**
60
+
61
+ Built from the ground up with a different philosophy, Pydoll connects directly to the Chrome DevTools Protocol (CDP), eliminating the need for external drivers entirely. More importantly, it incorporates advanced human behavior simulation and intelligent captcha bypass capabilities that make your automations virtually indistinguishable from real human interactions.
62
+
63
+ We believe that powerful automation shouldn't require you to become a configuration expert or constantly battle with anti-bot systems. With Pydoll, you focus on what matters: your automation logic, not the underlying complexity or protection bypassing.
64
+
65
+ ## What Makes Pydoll Special
66
+
67
+ - **Intelligent Captcha Bypass**: Built-in automatic solving for Cloudflare Turnstile and reCAPTCHA v3 captchas without external services, API keys, or complex configurations. Your automations continue seamlessly even when encountering protection systems.
68
+
69
+ - **Truly Human Interactions**: Advanced algorithms simulate authentic human behavior patterns - from realistic timing between actions to natural mouse movements, scroll patterns, and typing rhythms that fool even sophisticated bot detection systems.
70
+
71
+ - **Genuine Simplicity**: We don't want you wasting time configuring drivers or dealing with compatibility issues. With Pydoll, you install and you're ready to automate, even on protected sites.
72
+
73
+ - **Native Async Performance**: Built from the ground up with `asyncio`, Pydoll doesn't just support asynchronous operations - it was designed for them, enabling concurrent processing of multiple protected sites.
74
+
75
+ - **Powerful Network Monitoring**: Intercept, modify, and analyze all network traffic with ease, giving you complete control over requests and responses - perfect for bypassing additional protection layers.
76
+
77
+ - **Event-Driven Architecture**: React to page events, network requests, and user interactions in real-time, enabling sophisticated automation flows that adapt to dynamic protection systems.
78
+
79
+ - **Intuitive Element Finding**: Modern `find()` and `query()` methods that make sense and work as you'd expect, even with dynamically loaded content from protection systems.
80
+
81
+ - **Robust Type Safety**: Comprehensive type system for better IDE support and error prevention in complex automation scenarios.
82
+
83
+ ## Installation
84
+
85
+ ```bash
86
+ pip install pydoll-python
87
+ ```
88
+
89
+ That's it. No drivers to download, no complex configurations. Just install and start automating.
90
+
91
+ ## Getting Started
92
+
93
+ ### Your First Automation
94
+
95
+ Let's start with something simple. The code below opens a browser, navigates to a website, and interacts with elements:
96
+
97
+ ```python
98
+ import asyncio
99
+ from pydoll.browser import Chrome
100
+
101
+ async def my_first_automation():
102
+ # Create a browser instance
103
+ async with Chrome() as browser:
104
+ # Start the browser and get a tab
105
+ tab = await browser.start()
106
+
107
+ # Navigate to a website
108
+ await tab.go_to('https://example.com')
109
+
110
+ # Find elements intuitively
111
+ button = await tab.find(tag_name='button', class_name='submit')
112
+ await button.click()
113
+
114
+ # Or use CSS selectors/XPath directly
115
+ link = await tab.query('a[href*="contact"]')
116
+ await link.click()
117
+
118
+ # Run the automation
119
+ asyncio.run(my_first_automation())
120
+ ```
121
+
122
+ ### Custom Configuration
123
+
124
+ Sometimes you need more control. Pydoll offers flexible configuration options:
125
+
126
+ ```python
127
+ from pydoll.browser import Chrome
128
+ from pydoll.browser.options import ChromiumOptions
129
+
130
+ async def custom_automation():
131
+ # Configure browser options
132
+ options = ChromiumOptions()
133
+ options.add_argument('--proxy-server=username:password@ip:port')
134
+ options.add_argument('--window-size=1920,1080')
135
+ options.add_argument('--disable-web-security')
136
+ options.binary_location = '/path/to/your/browser'
137
+
138
+ async with Chrome(options=options) as browser:
139
+ tab = await browser.start()
140
+
141
+ # Your automation code here
142
+ await tab.go_to('https://example.com')
143
+
144
+ # The browser is now using your custom settings
145
+
146
+ asyncio.run(custom_automation())
147
+ ```
148
+
149
+ ## Advanced Features
150
+
151
+ ### Intelligent Captcha Bypass
152
+
153
+ One of Pydoll's most revolutionary features is its ability to automatically handle modern captcha systems that typically block automation tools. This isn't just about solving captchas - it's about making your automations completely transparent to protection systems.
154
+
155
+ **Supported Captcha Types:**
156
+ - **Cloudflare Turnstile** - The modern replacement for reCAPTCHA
157
+ - **reCAPTCHA v3** - Google's invisible captcha system
158
+ - **Custom implementations** - Extensible framework for new captcha types
159
+
160
+ ```python
161
+ import asyncio
162
+ from pydoll.browser import Chrome
163
+
164
+ async def advanced_captcha_bypass():
165
+ async with Chrome() as browser:
166
+ tab = await browser.start()
167
+
168
+ # Method 1: Context manager (waits for captcha completion)
169
+ async with tab.expect_and_bypass_cloudflare_captcha():
170
+ await tab.go_to('https://site-with-cloudflare.com')
171
+ print("Cloudflare Turnstile automatically solved!")
172
+
173
+ # Continue with your automation - captcha is handled
174
+ await tab.find(id='username').type('user@example.com')
175
+ await tab.find(id='password').type('password123')
176
+ await tab.find(tag_name='button', text='Login').click()
177
+
178
+ # Method 2: Background processing (non-blocking)
179
+ await tab.enable_auto_solve_cloudflare_captcha()
180
+ await tab.go_to('https://another-protected-site.com')
181
+ # Captcha solved automatically in background while code continues
182
+
183
+ # Method 3: Custom captcha selector for specific implementations
184
+ await tab.enable_auto_solve_cloudflare_captcha(
185
+ custom_selector=(By.CLASS_NAME, 'custom-captcha-widget'),
186
+ time_before_click=3, # Wait 3 seconds before solving
187
+ time_to_wait_captcha=10 # Timeout after 10 seconds
188
+ )
189
+
190
+ await tab.disable_auto_solve_cloudflare_captcha()
191
+
192
+ asyncio.run(advanced_captcha_bypass())
193
+ ```
194
+
195
+ **Why This Matters:**
196
+ - **No External Dependencies**: No need for captcha solving services or API keys
197
+ - **Cost Effective**: Eliminate monthly captcha solving service fees
198
+ - **Reliable**: Works consistently without depending on third-party availability
199
+ - **Fast**: Instant solving without network delays to external services
200
+ - **Seamless Integration**: Captcha bypass happens transparently in your automation flow
201
+
202
+
203
+ ### Advanced Element Finding
204
+
205
+ Pydoll offers multiple intuitive ways to find elements. No matter how you prefer to work, we have an approach that makes sense for you:
206
+
207
+ ```python
208
+ import asyncio
209
+ from pydoll.browser import Chrome
210
+
211
+ async def element_finding_examples():
212
+ async with Chrome() as browser:
213
+ tab = await browser.start()
214
+ await tab.go_to('https://example.com')
215
+
216
+ # Find by attributes (most intuitive)
217
+ submit_btn = await tab.find(
218
+ tag_name='button',
219
+ class_name='btn-primary',
220
+ text='Submit'
221
+ )
222
+
223
+ # Find by ID
224
+ username_field = await tab.find(id='username')
225
+
226
+ # Find multiple elements
227
+ all_links = await tab.find(tag_name='a', find_all=True)
228
+
229
+ # CSS selectors and XPath
230
+ nav_menu = await tab.query('nav.main-menu')
231
+ specific_item = await tab.query('//div[@data-testid="item-123"]')
232
+
233
+ # With timeout and error handling
234
+ delayed_element = await tab.find(
235
+ class_name='dynamic-content',
236
+ timeout=10,
237
+ raise_exc=False # Returns None if not found
238
+ )
239
+
240
+ # Advanced: Custom attributes
241
+ custom_element = await tab.find(
242
+ data_testid='submit-button',
243
+ aria_label='Submit form'
244
+ )
245
+
246
+ asyncio.run(element_finding_examples())
247
+ ```
248
+
249
+ ### Concurrent Automation
250
+
251
+ One of the great advantages of Pydoll's asynchronous design is the ability to process multiple tasks simultaneously:
252
+
253
+ ```python
254
+ import asyncio
255
+ from pydoll.browser import Chrome
256
+
257
+ async def scrape_page(url):
258
+ """Extract data from a single page"""
259
+ async with Chrome() as browser:
260
+ tab = await browser.start()
261
+ await tab.go_to(url)
262
+
263
+ title = await tab.execute_script('return document.title')
264
+ links = await tab.find(tag_name='a', find_all=True)
265
+
266
+ return {
267
+ 'url': url,
268
+ 'title': title,
269
+ 'link_count': len(links)
270
+ }
271
+
272
+ async def concurrent_scraping():
273
+ urls = [
274
+ 'https://example1.com',
275
+ 'https://example2.com',
276
+ 'https://example3.com'
277
+ ]
278
+
279
+ # Process all URLs simultaneously
280
+ tasks = [scrape_page(url) for url in urls]
281
+ results = await asyncio.gather(*tasks)
282
+
283
+ for result in results:
284
+ print(f"{result['url']}: {result['title']} ({result['link_count']} links)")
285
+
286
+ asyncio.run(concurrent_scraping())
287
+ ```
288
+
289
+ ### Event-Driven Automation
290
+
291
+ React to page events and user interactions in real-time. This enables more sophisticated and responsive automations:
292
+
293
+ ```python
294
+ import asyncio
295
+ from pydoll.browser import Chrome
296
+ from pydoll.protocol.page.events import PageEvent
297
+
298
+ async def event_driven_automation():
299
+ async with Chrome() as browser:
300
+ tab = await browser.start()
301
+
302
+ # Enable page events
303
+ await tab.enable_page_events()
304
+
305
+ # React to page load
306
+ async def on_page_load(event):
307
+ print("Page loaded! Starting automation...")
308
+ # Perform actions after page loads
309
+ search_box = await tab.find(id='search-box')
310
+ await search_box.type('automation')
311
+
312
+ # React to navigation
313
+ async def on_navigation(event):
314
+ url = event['params']['url']
315
+ print(f"Navigated to: {url}")
316
+
317
+ await tab.on(PageEvent.LOAD_EVENT_FIRED, on_page_load)
318
+ await tab.on(PageEvent.FRAME_NAVIGATED, on_navigation)
319
+
320
+ await tab.go_to('https://example.com')
321
+ await asyncio.sleep(5) # Let events process
322
+
323
+ asyncio.run(event_driven_automation())
324
+ ```
325
+
326
+ ### Working with iFrames
327
+
328
+ Pydoll provides seamless iframe interaction through the `get_frame()` method. This is especially useful for dealing with embedded content:
329
+
330
+ ```python
331
+ import asyncio
332
+ from pydoll.browser.chromium import Chrome
333
+
334
+ async def iframe_interaction():
335
+ async with Chrome() as browser:
336
+ tab = await browser.start()
337
+ await tab.go_to('https://example.com/page-with-iframe')
338
+
339
+ # Find the iframe element
340
+ iframe_element = await tab.query('.hcaptcha-iframe', timeout=10)
341
+
342
+ # Get a Tab instance for the iframe content
343
+ frame = await tab.get_frame(iframe_element)
344
+
345
+ # Now interact with elements inside the iframe
346
+ submit_button = await frame.find(tag_name='button', class_name='submit')
347
+ await submit_button.click()
348
+
349
+ # You can use all Tab methods on the frame
350
+ form_input = await frame.find(id='captcha-input')
351
+ await form_input.type('verification-code')
352
+
353
+ # Find elements by various methods
354
+ links = await frame.find(tag_name='a', find_all=True)
355
+ specific_element = await frame.query('#specific-id')
356
+
357
+ asyncio.run(iframe_interaction())
358
+ ```
359
+
360
+ ## Documentation
361
+
362
+ For comprehensive documentation, detailed examples, and deep dives into Pydoll's features, visit our [official documentation site](https://autoscrape-labs.github.io/pydoll/).
363
+
364
+ The documentation includes:
365
+ - **Getting Started Guide** - Step-by-step tutorials
366
+ - **API Reference** - Complete method documentation
367
+ - **Advanced Techniques** - Network interception, event handling, performance optimization
368
+ - **Troubleshooting** - Common issues and solutions
369
+ - **Best Practices** - Patterns for reliable automation
370
+
371
+ ## Contributing
372
+
373
+ We'd love your help making Pydoll even better! Check out our [contribution guidelines](CONTRIBUTING.md) to get started. Whether it's fixing bugs, adding features, or improving documentation - all contributions are welcome!
374
+
375
+ Please make sure to:
376
+ - Write tests for new features or bug fixes
377
+ - Follow coding style and conventions
378
+ - Use conventional commits for pull requests
379
+ - Run lint and test checks before submitting
380
+
381
+ ## Support My Work
382
+
383
+ If you find my projects helpful, consider [sponsoring me on GitHub](https://github.com/sponsors/thalissonvs).
384
+ You'll get access to exclusive perks like prioritized support, custom features, and more!
385
+
386
+ Can't sponsor right now? No problem — you can still help a lot by:
387
+ - Starring the repo
388
+ - Sharing it on social media
389
+ - Writing blog posts or tutorials
390
+ - Giving feedback or reporting issues
391
+
392
+ Every bit of support makes a difference — thank you!
393
+
394
+ ## License
395
+
396
+ Pydoll is licensed under the [MIT License](LICENSE).
397
+
398
+ <p align="center">
399
+ <b>Pydoll</b> — Making browser automation magical!
400
+ </p>
401
+