How to Use PyAutoGUI.scroll
Use PyAutoGUI.scroll(clicks) to scroll vertically: positive values go up, negative values go down. Learn how to target the right control and handle platform differences.
Call pyautogui.scroll(clicks). A positive integer requests upward scrolling and a negative integer requests downward scrolling. To send the wheel event over a particular control, supply its screen coordinates with x and y. The scroll distance represented by one click varies by platform, so clicks are not a fixed number of pixels or lines. PyAutoGUI’s mouse documentation
import pyautogui
pyautogui.scroll(5) # Up 5 scroll clicks at the current pointer
pyautogui.scroll(-5) # Down 5 scroll clicks at the current pointer
pyautogui.scroll(5, x=400, y=300) # Up at screen position (400, 300)
1. Install and run a minimal example
Install PyAutoGUI in the Python environment that will run the automation:
python -m pip install pyautogui
Save this as scroll_demo.py and run it while the target application is visible. The short pause lets you switch to the application before the scroll is sent.
import time
import pyautogui
print("Switch to the target window; scrolling starts in 3 seconds.")
time.sleep(3)
pyautogui.scroll(5) # Up
pyautogui.sleep(0.5)
pyautogui.scroll(-5) # Down
PyAutoGUI controls the desktop pointer. The event goes to whichever window or control is under the pointer at the event location and able to receive wheel input. It does not identify a web page element by name or selector.
2. Choose direction and target location
Vertical scrolling
scroll(clicks) is the vertical scroll interface. Positive values request upward movement; negative values request downward movement. For example:
pyautogui.scroll(10) # Request upward scrolling
pyautogui.scroll(-10) # Request downward scrolling
The integer represents scroll clicks, not pixels, lines, or a guaranteed page distance. An application may also apply its own wheel behavior, so use smaller steps and observe the resulting screen when a precise stopping point matters.
Scroll over a specific control
If you omit coordinates, the current pointer position is used. Pass both coordinates to move the pointer to the desired screen position before scrolling:
pyautogui.scroll(-3, x=800, y=500)
Coordinates use screen space: (0, 0) is the top-left, X increases to the right, and Y increases downward. Determine the screen size and current pointer position with pyautogui.size() and pyautogui.position(). Check a candidate point with pyautogui.onScreen(x, y) before automating it.
import pyautogui
print("screen:", pyautogui.size())
print("pointer:", pyautogui.position())
x, y = 800, 500
print("target is on screen:", pyautogui.onScreen(x, y))
if pyautogui.onScreen(x, y):
pyautogui.scroll(-3, x=x, y=y)
A window moving, a changed display arrangement, or a different screen resolution can make previously recorded coordinates point at the wrong control. Recompute positions in the environment where the automation runs.
Horizontal scrolling
For horizontal wheel movement, PyAutoGUI exposes hscroll(clicks). Its documentation describes support on macOS and Linux; availability and behavior are platform-dependent. Positive values request rightward movement and negative values leftward movement in the documented examples.
pyautogui.hscroll(4) # Request rightward scrolling where supported
pyautogui.hscroll(-4) # Request leftward scrolling where supported
3. Use repeatable, bounded scrolling
When an automation must inspect a long interface, send modest scroll increments and check for a visible condition between steps. A fixed number of clicks is simple, but it does not guarantee that a specific item becomes visible because click distance and application behavior vary.
import time
import pyautogui
# Move to the content pane so its scroll container receives the event.
x, y = 900, 600
for step in range(4):
pyautogui.scroll(-3, x=x, y=y)
time.sleep(0.25) # Give the application time to repaint
For GUI workflows that need to stop at a particular row or button, pair scrolling with a reliable observation step, such as checking a known visual marker. Do not assume a wheel event completed instantly or moved by an exact distance. Keep a maximum number of iterations so a missing marker cannot create an endless loop.
4. Options and API details
| Call or argument | Purpose | Notes |
|---|---|---|
scroll(clicks) |
Send a vertical wheel event. | Positive requests up; negative requests down. |
x, y |
Choose where the event occurs. | If omitted, current pointer location is used. Coordinates are screen coordinates. |
hscroll(clicks) |
Send horizontal scroll where supported. | Documentation specifies macOS and Linux support. |
logScreenshot |
Implementation-level optional parameter in the public source signature. | Not needed for ordinary use. |
_pause |
Implementation-level pause control in the public source signature. | Underscored parameter; generally leave its default alone. |
The current public source signature is scroll(clicks, x=None, y=None, logScreenshot=None, _pause=True). It also accepts a two-item tuple or list in x as coordinates, for example pyautogui.scroll(-2, x=(400, 300)). The function delegates to the platform backend and documents a None return value. These source-level details can change between PyAutoGUI versions; rely on the installed version’s documentation when exact behavior matters. PyAutoGUI source
5. Reliability, performance, and safety
- Distance varies: one click does not correspond to a portable pixel or line distance. Use incremental steps and verify the UI state.
- Choose the right recipient: scrolling is directed by pointer position. Position the event inside the intended scrollable pane, especially when a page has nested panels.
- Allow rendering time: applications may animate or asynchronously load content after the wheel event. Add a short wait only when the target app needs it, and prefer checking a condition to using a long fixed delay.
- Keep desktop state stable: unexpected dialogs, focus changes, display scaling, or window movement can invalidate coordinate-based actions.
- Use bounded loops: cap retries and provide a recovery path if the expected content never appears.
The dossier contains no PyAutoGUI scroll performance benchmarks. Runtime is usually dominated by the target application’s response and any waits or observation logic added by the automation; do not infer a fixed completion time from the click count.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The content moves in the opposite direction from what was expected. | The sign of clicks was reversed. |
Use positive clicks for up and negative clicks for down. |
| The wrong panel or window scrolls. | The pointer is over a different scrollable area, or the current position is not where expected. | Supply x and y, or move the pointer into the target pane before calling scroll(). |
| The distance is much larger or smaller than expected. | Click distance varies across platforms and applications. | Reduce the number of clicks per call and inspect after each step. Do not convert clicks to a fixed pixel distance. |
| The page appears not to move. | The pointer may be outside the scrollable region, the pane may be at its boundary, or the application may not accept wheel input. | Check the pointer coordinates and try a small scroll over the content area. Confirm the target can scroll manually. |
| Horizontal movement does nothing. | hscroll() support is operating-system dependent, or the target does not handle horizontal wheel events. |
Check the target platform and application support; the docs identify macOS and Linux for hscroll(). |
| A coordinate-based script breaks on another machine. | Screen resolution, scaling, monitor layout, or window position changed. | Read the current screen size and recalibrate coordinates at runtime or for each environment. |
Or skip the browser setup
If your goal is to capture a web page after handling its scrollable content, ScreenshotNeo provides a screenshot API that returns an image or PDF from one GET request. See the ScreenshotNeo API documentation for its options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Learn about ScreenshotNeo or sign up free.
FAQ
Does scroll() return the new scroll position?
No. Its documented return is None; use a separate observation step if your automation needs to know what is visible.
Can I scroll a browser page by CSS selector?
Not with pyautogui.scroll() itself. It sends a desktop wheel event at screen coordinates, so aim it over the page region. Browser automation tools that address DOM elements are a different approach.
Can I use fractional clicks for finer movement?
The documented API describes an integer number of clicks. Use smaller integer calls and observe between them rather than relying on fractional values.


