Skip to content

Commit db3d9e7

Browse files
committed
docs: remove outdated HTTP request and download management sections
1 parent 25c3d41 commit db3d9e7

File tree

1 file changed

+165
-177
lines changed

1 file changed

+165
-177
lines changed

README.md

Lines changed: 165 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -81,183 +81,6 @@ on_top = await element.is_on_top()
8181

8282
These additions simplify waiting and state validation before clicking/typing, reducing flakiness and making automations more predictable.
8383

84-
### Browser-context HTTP requests - game changer for hybrid automation!
85-
Ever wished you could make HTTP requests that automatically inherit all your browser's session state? **Now you can!**<br>
86-
The `tab.request` property gives you a beautiful `requests`-like interface that executes HTTP calls directly in the browser's JavaScript context. This means every request automatically gets cookies, authentication headers, CORS policies, and session state, just as if the browser made the request itself.
87-
88-
**Perfect for Hybrid Automation:**
89-
```python
90-
# Navigate to a site and login normally with PyDoll
91-
await tab.go_to('https://example.com/login')
92-
await (await tab.find(id='username')).type_text('[email protected]')
93-
await (await tab.find(id='password')).type_text('password')
94-
await (await tab.find(id='login-btn')).click()
95-
96-
# Now make API calls that inherit the logged-in session!
97-
response = await tab.request.get('https://example.com/api/user/profile')
98-
user_data = response.json()
99-
100-
# POST data while staying authenticated
101-
response = await tab.request.post(
102-
'https://example.com/api/settings',
103-
json={'theme': 'dark', 'notifications': True}
104-
)
105-
106-
# Access response content in different formats
107-
raw_data = response.content
108-
text_data = response.text
109-
json_data = response.json()
110-
111-
# Check cookies that were set
112-
for cookie in response.cookies:
113-
print(f"Cookie: {cookie['name']} = {cookie['value']}")
114-
115-
# Add custom headers to your requests
116-
headers = [
117-
{'name': 'X-Custom-Header', 'value': 'my-value'},
118-
{'name': 'X-API-Version', 'value': '2.0'}
119-
]
120-
121-
await tab.request.get('https://api.example.com/data', headers=headers)
122-
123-
```
124-
125-
**Why this is great:**
126-
- **No more session juggling** - Requests inherit browser cookies automatically
127-
- **CORS just works** - Requests respect browser security policies
128-
- **Perfect for modern SPAs** - Seamlessly mix UI automation with API calls
129-
- **Authentication made easy** - Login once via UI, then hammer APIs
130-
- **Hybrid workflows** - Use the best tool for each step (UI or API)
131-
132-
This opens up incredible possibilities for automation scenarios where you need both browser interaction AND API efficiency!
133-
134-
### New expect_download() context manager — robust file downloads made easy!
135-
Tired of fighting with flaky download flows, missing files, or racy event listeners? Meet `tab.expect_download()`, a delightful, reliable way to handle file downloads.
136-
137-
- Automatically sets the browser’s download behavior
138-
- Works with your own directory or a temporary folder (auto-cleaned!)
139-
- Waits for completion with a timeout (so your tests don’t hang)
140-
- Gives you a handy handle to read bytes/base64 or check `file_path`
141-
142-
Tiny example that just works:
143-
144-
```python
145-
import asyncio
146-
from pathlib import Path
147-
from pydoll.browser import Chrome
148-
149-
async def download_report():
150-
async with Chrome() as browser:
151-
tab = await browser.start()
152-
await tab.go_to('https://example.com/reports')
153-
154-
target_dir = Path('/tmp/my-downloads')
155-
async with tab.expect_download(keep_file_at=target_dir, timeout=10) as download:
156-
# Trigger the download in the page (button/link/etc.)
157-
await (await tab.find(text='Download latest report')).click()
158-
# Wait until finished and read the content
159-
data = await download.read_bytes()
160-
print(f"Downloaded {len(data)} bytes to: {download.file_path}")
161-
162-
asyncio.run(download_report())
163-
```
164-
165-
Want zero-hassle cleanup? Omit `keep_file_at` and we’ll create a temp folder and remove it automatically after the context exits. Perfect for tests.
166-
167-
### Total browser control with custom preferences! (thanks to [@LucasAlvws](https://github.com/LucasAlvws))
168-
Want to completely customize how Chrome behaves? **Now you can control EVERYTHING!**<br>
169-
The new `browser_preferences` system gives you access to hundreds of internal Chrome settings that were previously impossible to change programmatically. We're talking about deep browser customization that goes way beyond command-line flags!
170-
171-
**The possibilities are endless:**
172-
```python
173-
options = ChromiumOptions()
174-
175-
# Create the perfect automation environment
176-
options.browser_preferences = {
177-
'download': {
178-
'default_directory': '/tmp/downloads',
179-
'prompt_for_download': False,
180-
'directory_upgrade': True,
181-
'extensions_to_open': '' # Don't auto-open any downloads
182-
},
183-
'profile': {
184-
'default_content_setting_values': {
185-
'notifications': 2, # Block all notifications
186-
'geolocation': 2, # Block location requests
187-
'media_stream_camera': 2, # Block camera access
188-
'media_stream_mic': 2, # Block microphone access
189-
'popups': 1 # Allow popups (useful for automation)
190-
},
191-
'password_manager_enabled': False, # Disable password prompts
192-
'exit_type': 'Normal' # Always exit cleanly
193-
},
194-
'intl': {
195-
'accept_languages': 'en-US,en',
196-
'charset_default': 'UTF-8'
197-
},
198-
'browser': {
199-
'check_default_browser': False, # Don't ask about default browser
200-
'show_update_promotion_infobar': False
201-
}
202-
}
203-
204-
# Or use the convenient helper methods
205-
options.set_default_download_directory('/tmp/downloads')
206-
options.set_accept_languages('en-US,en,pt-BR')
207-
options.prompt_for_download = False
208-
```
209-
210-
**Real-world power examples:**
211-
- **Silent downloads** - No prompts, no dialogs, just automated downloads
212-
- **Block ALL distractions** - Notifications, popups, camera requests, you name it
213-
- **Perfect for CI/CD** - Disable update checks, default browser prompts, crash reporting
214-
- **Multi-region testing** - Change languages, timezones, and locale settings instantly
215-
- **Security hardening** - Lock down permissions and disable unnecessary features
216-
- **Advanced fingerprinting control** - Modify browser install dates, engagement history, and behavioral patterns
217-
218-
**Fingerprint customization for stealth automation:**
219-
```python
220-
import time
221-
222-
# Simulate a browser that's been around for months
223-
fake_engagement_time = int(time.time()) - (7 * 24 * 60 * 60) # 7 days ago
224-
225-
options.browser_preferences = {
226-
'settings': {
227-
'touchpad': {
228-
'natural_scroll': True,
229-
}
230-
},
231-
'profile': {
232-
'last_engagement_time': fake_engagement_time,
233-
'exit_type': 'Normal',
234-
'exited_cleanly': True
235-
},
236-
'newtab_page_location_override': 'https://www.google.com',
237-
'session': {
238-
'restore_on_startup': 1, # Restore last session
239-
'startup_urls': ['https://www.google.com']
240-
}
241-
}
242-
```
243-
244-
This level of control was previously only available to Chrome extension developers - now it's in your automation toolkit!
245-
246-
Check the [documentation](https://pydoll.tech/docs/features/#custom-browser-preferences/) for more details.
247-
248-
### New `get_parent_element()` method
249-
Retrieve the parent of any WebElement, making it easier to navigate the DOM structure:
250-
```python
251-
element = await tab.find(id='button')
252-
parent = await element.get_parent_element()
253-
```
254-
### New start_timeout option (thanks to [@j0j1j2](https://github.com/j0j1j2))
255-
Added to ChromiumOptions to control how long the browser can take to start. Useful on slower machines or CI environments.
256-
257-
```python
258-
options = ChromiumOptions()
259-
options.start_timeout = 20 # wait 20 seconds
260-
```
26184

26285
## 📦 Installation
26386

@@ -426,6 +249,7 @@ Pydoll offers a series of advanced features to please even the most
426249
demanding users.
427250

428251

252+
429253
### Advanced Element Search
430254

431255
We have several ways to find elements on the page. No matter how you prefer, we have a way that makes sense for you:
@@ -472,6 +296,170 @@ The `find` method is more user-friendly. We can search by common attributes like
472296
If that's not enough, we can use the `query` method to search for elements using CSS selectors, XPath queries, etc. Pydoll automatically takes care of identifying what type of query we're using.
473297

474298

299+
### Browser-context HTTP requests - game changer for hybrid automation!
300+
Ever wished you could make HTTP requests that automatically inherit all your browser's session state? **Now you can!**<br>
301+
The `tab.request` property gives you a beautiful `requests`-like interface that executes HTTP calls directly in the browser's JavaScript context. This means every request automatically gets cookies, authentication headers, CORS policies, and session state, just as if the browser made the request itself.
302+
303+
**Perfect for Hybrid Automation:**
304+
```python
305+
# Navigate to a site and login normally with PyDoll
306+
await tab.go_to('https://example.com/login')
307+
await (await tab.find(id='username')).type_text('[email protected]')
308+
await (await tab.find(id='password')).type_text('password')
309+
await (await tab.find(id='login-btn')).click()
310+
311+
# Now make API calls that inherit the logged-in session!
312+
response = await tab.request.get('https://example.com/api/user/profile')
313+
user_data = response.json()
314+
315+
# POST data while staying authenticated
316+
response = await tab.request.post(
317+
'https://example.com/api/settings',
318+
json={'theme': 'dark', 'notifications': True}
319+
)
320+
321+
# Access response content in different formats
322+
raw_data = response.content
323+
text_data = response.text
324+
json_data = response.json()
325+
326+
# Check cookies that were set
327+
for cookie in response.cookies:
328+
print(f"Cookie: {cookie['name']} = {cookie['value']}")
329+
330+
# Add custom headers to your requests
331+
headers = [
332+
{'name': 'X-Custom-Header', 'value': 'my-value'},
333+
{'name': 'X-API-Version', 'value': '2.0'}
334+
]
335+
336+
await tab.request.get('https://api.example.com/data', headers=headers)
337+
338+
```
339+
340+
**Why this is great:**
341+
- **No more session juggling** - Requests inherit browser cookies automatically
342+
- **CORS just works** - Requests respect browser security policies
343+
- **Perfect for modern SPAs** - Seamlessly mix UI automation with API calls
344+
- **Authentication made easy** - Login once via UI, then hammer APIs
345+
- **Hybrid workflows** - Use the best tool for each step (UI or API)
346+
347+
This opens up incredible possibilities for automation scenarios where you need both browser interaction AND API efficiency!
348+
349+
### New expect_download() context manager — robust file downloads made easy!
350+
Tired of fighting with flaky download flows, missing files, or racy event listeners? Meet `tab.expect_download()`, a delightful, reliable way to handle file downloads.
351+
352+
- Automatically sets the browser’s download behavior
353+
- Works with your own directory or a temporary folder (auto-cleaned!)
354+
- Waits for completion with a timeout (so your tests don’t hang)
355+
- Gives you a handy handle to read bytes/base64 or check `file_path`
356+
357+
Tiny example that just works:
358+
359+
```python
360+
import asyncio
361+
from pathlib import Path
362+
from pydoll.browser import Chrome
363+
364+
async def download_report():
365+
async with Chrome() as browser:
366+
tab = await browser.start()
367+
await tab.go_to('https://example.com/reports')
368+
369+
target_dir = Path('/tmp/my-downloads')
370+
async with tab.expect_download(keep_file_at=target_dir, timeout=10) as download:
371+
# Trigger the download in the page (button/link/etc.)
372+
await (await tab.find(text='Download latest report')).click()
373+
# Wait until finished and read the content
374+
data = await download.read_bytes()
375+
print(f"Downloaded {len(data)} bytes to: {download.file_path}")
376+
377+
asyncio.run(download_report())
378+
```
379+
380+
Want zero-hassle cleanup? Omit `keep_file_at` and we’ll create a temp folder and remove it automatically after the context exits. Perfect for tests.
381+
382+
### Total browser control with custom preferences! (thanks to [@LucasAlvws](https://github.com/LucasAlvws))
383+
Want to completely customize how Chrome behaves? **Now you can control EVERYTHING!**<br>
384+
The new `browser_preferences` system gives you access to hundreds of internal Chrome settings that were previously impossible to change programmatically. We're talking about deep browser customization that goes way beyond command-line flags!
385+
386+
**The possibilities are endless:**
387+
```python
388+
options = ChromiumOptions()
389+
390+
# Create the perfect automation environment
391+
options.browser_preferences = {
392+
'download': {
393+
'default_directory': '/tmp/downloads',
394+
'prompt_for_download': False,
395+
'directory_upgrade': True,
396+
'extensions_to_open': '' # Don't auto-open any downloads
397+
},
398+
'profile': {
399+
'default_content_setting_values': {
400+
'notifications': 2, # Block all notifications
401+
'geolocation': 2, # Block location requests
402+
'media_stream_camera': 2, # Block camera access
403+
'media_stream_mic': 2, # Block microphone access
404+
'popups': 1 # Allow popups (useful for automation)
405+
},
406+
'password_manager_enabled': False, # Disable password prompts
407+
'exit_type': 'Normal' # Always exit cleanly
408+
},
409+
'intl': {
410+
'accept_languages': 'en-US,en',
411+
'charset_default': 'UTF-8'
412+
},
413+
'browser': {
414+
'check_default_browser': False, # Don't ask about default browser
415+
'show_update_promotion_infobar': False
416+
}
417+
}
418+
419+
# Or use the convenient helper methods
420+
options.set_default_download_directory('/tmp/downloads')
421+
options.set_accept_languages('en-US,en,pt-BR')
422+
options.prompt_for_download = False
423+
```
424+
425+
**Real-world power examples:**
426+
- **Silent downloads** - No prompts, no dialogs, just automated downloads
427+
- **Block ALL distractions** - Notifications, popups, camera requests, you name it
428+
- **Perfect for CI/CD** - Disable update checks, default browser prompts, crash reporting
429+
- **Multi-region testing** - Change languages, timezones, and locale settings instantly
430+
- **Security hardening** - Lock down permissions and disable unnecessary features
431+
- **Advanced fingerprinting control** - Modify browser install dates, engagement history, and behavioral patterns
432+
433+
**Fingerprint customization for stealth automation:**
434+
```python
435+
import time
436+
437+
# Simulate a browser that's been around for months
438+
fake_engagement_time = int(time.time()) - (7 * 24 * 60 * 60) # 7 days ago
439+
440+
options.browser_preferences = {
441+
'settings': {
442+
'touchpad': {
443+
'natural_scroll': True,
444+
}
445+
},
446+
'profile': {
447+
'last_engagement_time': fake_engagement_time,
448+
'exit_type': 'Normal',
449+
'exited_cleanly': True
450+
},
451+
'newtab_page_location_override': 'https://www.google.com',
452+
'session': {
453+
'restore_on_startup': 1, # Restore last session
454+
'startup_urls': ['https://www.google.com']
455+
}
456+
}
457+
```
458+
459+
This level of control was previously only available to Chrome extension developers - now it's in your automation toolkit!
460+
461+
Check the [documentation](https://pydoll.tech/docs/features/#custom-browser-preferences/) for more details.
462+
475463
### Concurrent Automation
476464

477465
One of the great advantages of Pydoll is the ability to process multiple tasks simultaneously thanks to its asynchronous implementation. We can automate multiple tabs

0 commit comments

Comments
 (0)