A Playwright adaptation of HumanCursor for human-like mouse movements
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file humancursor_playwright-0.1.1.tar.gz.
File metadata
- Download URL: humancursor_playwright-0.1.1.tar.gz
- Upload date:
- Size: 16.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
036b6ab799f476d5dae2c3d2ea64c8951867f1589144604e12e222ad25c146b6
|
|
| MD5 |
83c2e1b8dc078cbaab94830a8d8736c5
|
|
| BLAKE2b-256 |
03733f80a630724589419e2e813f3ca7477bdf2b681166a645853289acc6db46
|
File details
Details for the file humancursor_playwright-0.1.1-py3-none-any.whl.
File metadata
- Download URL: humancursor_playwright-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ace5403d586f1f68d7b3dacc3f163b6352711a8df46a67c52900df735cda6eed
|
|
| MD5 |
c485894310993843fc1f9beb85671605
|
|
| BLAKE2b-256 |
7d91cd0b1c5b0e07e76d3b2e8eb8b3a58b06d5fc68ea29de3548824e6008acc8
|