How to Scroll Page using Selenium in Python

Valentina Skakun Valentina Skakun
Last update: 13 Aug 2024

Selenium is a leading framework for mimicking user interactions within a web browser. It’s a cornerstone in software testing and data extraction. While we’ve detailed a Selenium Python guide for beginners in a previous article, our focus here is on a core functionality: scrolling.

This article will provide a simple Python tutorial on different scrolling techniques and their practical implementation. We’ll explore various methods, from simple scrolling to more complex scenarios, ensuring you understand how to use Selenium’s scrolling capabilities effectively.

Using JavaScript Executor

The simplest and most commonly used method for scrolling is executing JavaScript code in Chromedriver, which implements the required functionality. JavaScript allows for three main types of scrolling, disregarding horizontal and vertical differences:

  1. Scrolling to a specific position. This includes scrolling to the top or end of the page.

  2. Scrolling to a specific element. If we don’t know the exact scrolling destination but know the target element, we can easily scroll web pages to that element.

  3. Scrolling to specific coordinates. This is useful when you need to scroll a certain number of pixels from the current position. 

Let’s look at practical examples and write simple code to implement these scrolling types. For all examples in this article, we’ll use the following template:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

url = "https://demo.opencart.com/"

chrome_options = Options()
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)

# Here will be code

driver.quit()

Only the part after navigating to the page will change. Here, we’ve preloaded the necessary modules from the Selenium library. Moving forward, we’ll only provide scrolling examples, so you can use this template to run them. 

Scrolling to a specific element 

Since scrolling to a specific position or by coordinates involves similar methods, we’ll cover those together later. For now, let’s focus on scrolling to a particular element. To do this, we need a way to identify that element. CSS selectors, XPath, or other methods can be used.

Let’s try scrolling to an element with a specific ID using JavaScript. Since each element can have only one unique ID, this provides a reliable way to identify it. However, only some elements have IDs, so this approach is only sometimes feasible. So, first, we’ll locate the desired element and then scroll to it:

element = driver.find_element(By.ID, "carousel-banner-1")
driver.execute_script("arguments[0].scrollIntoView(true);", element)

This code is generally applicable to any element. The By method supports various ways to find specific elements, making the code adaptable for different scenarios simply by changing the search method and the data used to identify the target element.

Scrolling to a specific position

Typically, when we want to scroll to a specific position on a webpage, we use the window.scrollTo(x, y) function. Here, x and y represent the absolute coordinates on the page. To scroll horizontally, you would adjust the x value, and to scroll vertically, you would change the y value.

Since vertical scrolling is more common, let’s focus on scrolling up and down. This script scrolls the page to the very bottom by setting the y coordinate to the total height of the document body:

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

To scroll back to the top, we set both x and y to 0, placing the top-left corner of the viewport at the origin of the document:

driver.execute_script("window.scrollTo(0, 0);")

If you know the exact height you want to scroll to, you can manually set the y value. However, remember that these coordinates are absolute and don’t depend on your current scroll position.

Scrolling by coordinates

Scrolling by coordinates is very similar to scrolling to a specific position. The main difference is that absolute values are used in the case of a position, whereas when scrolling by coordinates, the change relative to the current position is specified. This is implemented using the window.scrollBy(x, y) function.

Since this function implements a change in position relative to the current position, the value can be set as both positive and negative. The values are positive for scrolling right and down, and for up or left, they are negative.

For example, to scroll down by 500 pixels, you can use the following code:

driver.execute_script("window.scrollBy(0, 500);")  

To scroll up by 500 pixels:

driver.execute_script("window.scrollBy(0, -500);")

To scroll right:

driver.execute_script("window.scrollBy(500, 0);")

To scroll left:

driver.execute_script("window.scrollBy(-500, 0);")

You can change the x and y values simultaneously if you scroll diagonally. 

Using Action Class

Selenium also provides a dedicated set of functions called ‘Actions’ that enable a comprehensive emulation of real user interactions on a webpage. These actions include mouse movements, key presses, and scrolling.

To use these functions, we need to create an ActionChains object:

actions = ActionChains(driver)

We’ll use this object in both examples, so we’re defining it beforehand to avoid repeating it.

Using Action Chains for Scrolling to an Element

Let’s replicate the JavaScript example using Selenium’s Action Chains. Locate the desired element using By.ID, scroll to this element and act:

element = driver.find_element(By.ID, 'carousel-banner-1')
actions.move_to_element(element).perform()

This achieves the same outcome as our previous JavaScript solution. However, the power of action chains lies in their ability to chain multiple actions together. For instance, you can locate an element, click on it, and input text in a single sequence.

 actions.move_to_element(element).click().perform()

This is particularly useful for automating interactions with dropdowns, menus, and forms. By chaining actions, Action Chains simplifies complex automation tasks compared to using raw JavaScript execution. This makes it an invaluable tool for larger projects.

Scrolling Using Keyboard Keys in Action Chains

Another scrolling option involves using keyboard keys within Action Chains. This is similar to regular keyboard scrolling (which we’ll discuss next) but can be more convenient when combining actions.

To scroll up or down, you can use this code:

actions.send_keys(Keys.PAGE_DOWN).perform() 
actions.send_keys(Keys.PAGE_UP).perform()

If you don’t need additional actions and prefer a simpler approach without Action Chains, the next section provides a basic keyboard scrolling example.

Scrolling with Keyboard Events

To interact with keyboard keys, we first need to identify the target element. For scrolling, we’ll interact with the entire visible portion of the page, which is typically contained within the body tag.

body = driver.find_element(By.TAG_NAME, "body")

Once we have the body element, we can simulate keystrokes. For example, to scroll to the top of the page, we can use:

body.send_keys(Keys.HOME)

And to scroll down of the page:

body.send_keys(Keys.END) 

As you can see, this approach is similar to using ActionChains, but it’s slightly more straightforward.

Scrolling an Element with Overflow

When a web element has styles that enable scrolling (like overflow: auto or overflow: scroll), you can use Selenium and JavaScript to scroll within that element.

Let’s say we have an element with the ID 'scrollbar' on our page that we want to scroll. First, we need to find this element:

scrollable_element = driver.find_element(By.ID, 'scrollbar')

Then, we can scroll down:

driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight;", scrollable_element)

Or scroll up:

driver.execute_script("arguments[0].scrollTop = 0;", scrollable_element)

Note that you can scroll the entire page and specific elements within it.

Tips and Tricks

Sometimes, specific questions or problems arise during the web scraping process. However, small tricks can help you overcome these difficulties using the skills discussed in this article.

Infinite Scrolling

Infinite scrolling is a common technique for loading content dynamically as a user scrolls down a page. This creates a seemingly endless feed of content, often seen on social media and news websites.

To implement infinite scroll using Selenium, we can use the following algorithm:

  1. Create a loop. This loop will continuously scroll the page to the bottom.

  2. Check for new content. After each scroll, you’d inspect the page to see if new content has been loaded.

  3. Repeat. If new content is found, the loop continues; otherwise, it might terminate.

The ready example might look like this:

while (True):
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(2)

To make the loop finite, you can introduce a counter or a conditional statement to break out of the loop when a specific condition is met. For instance, you could stop scrolling after a certain number of iterations or when you encounter a particular element on the page. 

Scrolling Accuracy

Another common task is scrolling to the exact middle of a specific element. We can modify the previous examples by using the scrollIntoView method with the behaviour and block options:

driver.execute_script("arguments[0].scrollIntoView({ behavior: 'smooth', block: 'center' });", element)

While this task is less frequent, its solution can be crucial in specific scenarios. 

Pop-ups and Overlays

Pop-ups are a common challenge when building web scrapers or automating tasks with Selenium. They often obstruct scrolling, significantly hindering your automation process.

To address this, let’s introduce a simple technique: before scrolling, we can attempt to close any pop-ups. 

try:
    popup_close_button = driver.find_element(By.ID, 'popup_id')
    popup_close_button.click()
except:
    print("Pop-up not found.")

This code block tries to find an element with the ID ‘popup_id’ and then clicks it to close the pop-up. The try-except block ensures the script doesn’t crash if the pop-up or closing button isn’t found.

Frames and Nested Elements

To interact with elements within an iframe, you first need to switch the context into the iframe. Once inside, you can apply the same principles we’ve discussed for scrolling elements with overflow. Let’s break down an example.

First, find the iframe with the specified ID and switch the driver’s focus to it:

iframe = driver.find_element(By.ID, 'iframe_id')
driver.switch_to.frame(iframe)

After switching to the iframe, you can locate the specific element you want to interact with and scroll it:

nested_element = driver.find_element(By.ID, 'nested_element_id')
driver.execute_script("arguments[0].scrollIntoView(true);", nested_element)

Finally, to resume interacting with elements in the main document, you switch back to the default content:

driver.switch_to.default_content()

Following these steps, you can effectively extract data from containers containing content from external sources. This is particularly useful for automating web page tasks that use iframes to embed third-party content.

Conclusion and Takeaways

This article explored various methods for implementing scrolling in Selenium with Python. We covered essential techniques such as using JavaScript Executor to scroll to specific elements and positions and how to navigate by coordinates. The Action Chains were highlighted for their capabilities in achieving smooth scrolling and handling complex scenarios like scrolling using keyboard keys and handling key events.

We also discussed advanced topics, including dealing with overflowing elements, infinite scrolling, and ensuring scrolling accuracy. Solutions for common challenges, such as managing pop-ups, overlays, and scrolling within frames and nested elements, were also provided.

By understanding and applying these techniques, you can effectively scrape, automate and test dynamic web pages, ensuring robust and reliable scripts.

Blog

Might Be Interesting