HumanCursor-Playwright
A Playwright adaptation of HumanCursor that provides human-like mouse movements for web automation using Playwright/Patchright.
Description
HumanCursor-Playwright is a Python library that enables human-like mouse movements in web automation using Playwright. It's designed to help you create more natural and less detectable web automation by simulating human-like cursor movements, clicks, and interactions.
This library is adapted from the HumanCursor-Botasaurus project, modified to work with Playwright's async API instead of Botasaurus driver.
Features
- Human-like mouse movements using Bezier curves
- Randomized movement patterns to avoid detection
- Support for clicking, dragging, and scrolling with human-like behavior
- Full async/await support with Playwright
- Easy integration with existing Playwright scripts
- Customizable movement parameters
- Visual cursor tracking for debugging
Installation
pip install humancursor-playwright
Or install from source:
git clone https://github.com/yourusername/humancursor-playwright
cd humancursor-playwright
pip install -e .
Prerequisites
You'll also need to install Playwright browsers:
playwright install
Usage
Basic Example
import asyncio
from playwright.async_api import async_playwright
from humancursor_playwright import PlaywrightCursor
async def main():
async with async_playwright() as playwright:
# Launch browser
browser = await playwright.chromium.launch(headless=False)
page = await browser.new_page()
try:
# Navigate to a website
await page.goto("https://www.example.com")
# Initialize HumanCursor
cursor = PlaywrightCursor(page)
# Find an element
button = page.locator("button.login")
# Move to the element and click it with human-like movement
await cursor.click_on(button)
finally:
await browser.close()
asyncio.run(main())
Advanced Usage
import asyncio
from playwright.async_api import async_playwright
from humancursor_playwright import PlaywrightCursor
async def main():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=False)
page = await browser.new_page()
try:
await page.goto("https://www.example.com")
# Initialize HumanCursor
cursor = PlaywrightCursor(page)
# Show the cursor (adds a red dot to visualize movements)
await cursor.show_cursor()
# Find elements
input_field = page.locator("input[name='username']")
login_button = page.locator("button.login")
# Move to the input field with human-like movement and click
await cursor.click_on(input_field)
# Type something
await input_field.type("example_user")
# Find password field and click on it
password_field = page.locator("input[name='password']")
await cursor.click_on(password_field)
# Type password
await password_field.type("example_password")
# Move to login button and click
await cursor.click_on(login_button)
finally:
await browser.close()
asyncio.run(main())
Drag and Drop Example
import asyncio
from playwright.async_api import async_playwright
from humancursor_playwright import PlaywrightCursor
async def main():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=False)
page = await browser.new_page()
try:
await page.goto("https://jqueryui.com/droppable/")
# Switch to iframe
iframe = page.frame_locator("iframe.demo-frame")
# Initialize HumanCursor
cursor = PlaywrightCursor(page)
# Find elements in iframe
drag_element = iframe.locator("#draggable")
drop_target = iframe.locator("#droppable")
# Perform drag and drop with human-like movement
await cursor.drag_and_drop(drag_element, drop_target)
finally:
await browser.close()
asyncio.run(main())
Using with Patchright
HumanCursor-Playwright works seamlessly with Patchright, the undetected Playwright fork:
import asyncio
from patchright.async_api import async_playwright
from humancursor_playwright import PlaywrightCursor
async def main():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=False)
page = await browser.new_page()
# The rest of the code is identical
cursor = PlaywrightCursor(page)
await cursor.click_on(page.locator("button"))
await browser.close()
asyncio.run(main())
API Reference
PlaywrightCursor
__init__(page: Page)
Initialize the cursor with a Playwright page object.
async move_to(element_or_pos, relative_position=None, absolute_offset=False, origin_coordinates=None, steady=False)
Move to an element or coordinates with human-like movement.
element_or_pos: Playwright Locator or [x, y] coordinatesrelative_position: [x, y] relative position within element (0.0 to 1.0)absolute_offset: Whether coordinates are absolute offsetsorigin_coordinates: Starting coordinatessteady: Use steadier, less random movement
async click_on(element_or_pos, number_of_clicks=1, click_duration=0, button='left', ...)
Move to element and click with human-like movement.
async drag_and_drop(drag_from_element, drag_to_element, ...)
Perform drag and drop operation with human-like movement.
async show_cursor() / async hide_cursor()
Show/hide a red dot that follows the cursor for debugging.
Movement Parameters
The library automatically adjusts movement parameters based on distance and randomization:
- Short distances (<100px): Minimal curve complexity
- Medium distances (100-300px): Moderate curve complexity
- Long distances (>300px): Higher curve complexity with more natural arcs
Parameters include:
- Bezier curve control points
- Movement speed variations
- Random distortions and offsets
- Easing functions (easeOutQuad, easeInOutSine, etc.)
Comparison with Original
| Feature | HumanCursor-Botasaurus | HumanCursor-Playwright |
|---|---|---|
| Browser Support | Botasaurus | Playwright/Patchright |
| Async Support | No | Full async/await |
| API Style | Synchronous | Asynchronous |
| Browser Control | Limited | Full Playwright API |
| Performance | Good | Better (native async) |
| Detection Resistance | Good | Better with Patchright |
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Credits
- Original HumanCursor project by zajcikk
- HumanCursor-Botasaurus adaptation
- Playwright by Microsoft
- Patchright by Vinyzu
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
v0.1.0
- Initial Playwright adaptation
- Full async/await support
- Compatible with both Playwright and Patchright
- Improved error handling and debugging features
Metadata
Release files for humancursor-playwright 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| humancursor_playwright-0.1.1.tar.gz | 16.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| humancursor_playwright-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.6 kB
Release files / humancursor_playwright-0.1.1.tar.gz
| Download URL | humancursor_playwright-0.1.1.tar.gz |
|---|---|
| Size | 16.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
036b6ab799f476d5dae2c3d2ea64c8951867f1589144604e12e222ad25c146b6
|
|
BLAKE2b-256 checksum How to use checksums |
03733f80a630724589419e2e813f3ca7477bdf2b681166a645853289acc6db46
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|
Release files / humancursor_playwright-0.1.1-py3-none-any.whl
| Download URL | humancursor_playwright-0.1.1-py3-none-any.whl |
|---|---|
| Size | 15.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ace5403d586f1f68d7b3dacc3f163b6352711a8df46a67c52900df735cda6eed
|
|
BLAKE2b-256 checksum How to use checksums |
7d91cd0b1c5b0e07e76d3b2e8eb8b3a58b06d5fc68ea29de3548824e6008acc8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|