CodeGym /Courses /Python SELF EN /Script Optimization for Stability and Error Minimization

Script Optimization for Stability and Error Minimization

Python SELF EN
Level 38 , Lesson 3
Available

1. Performance Analysis

Why optimization?

Imagine a powerful car that can go from 0 to 60 mph in three seconds but guzzles gas like a whale with plankton. Your script might be lightning fast, but super "resource-hungry" when it comes to execution time and memory usage. Moreover, "leaks" of resources can destabilize it, leading to errors. Optimization helps avoid these problems.

First thing, as surgeons say, make an "incision." Perform a performance analysis of your script to figure out where it's "hurting."

Methods for checking script speed and stability

One simple way to analyze is by using basic Python tools, like the time module. Let's add a few lines to our script to identify which operations take the most time.

Python

import time

start_time = time.time()
# Your code for performing actions with Selenium goes here
end_time = time.time()

print(f"Execution time: {end_time - start_time} seconds")
  

This small snippet helps you determine how long each part of the code takes to execute. Using such "timers," you can locate the bottlenecks.

Identifying weak spots and optimizing them

Once you've found the part of the code that's a "time-hog," it's time to act. Maybe you're accessing dynamic elements more often than needed, or your code has turned into a "spaghetti mess." Step one is identifying the issue; step two is solving it.

Reducing the number of requests: Check if you're making too many unnecessary page navigations or DOM updates. For example, using the WebDriverWait method helps run the script only after the desired elements are fully loaded.

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, 'myDynamicElement'))
)
  

Caching data: If you’re working with the same data multiple times, consider caching it. Store data in variables or a cache to minimize resource-intensive operations.

2. Improving Script Structure

If your code reads like a subway map with no signs or station names, it's time for an upgrade. An optimal code structure is the key to easy understanding and error-resilience.

Using data pipelines and optimal algorithmic solutions

Think about structuring your code into pipelines, where each function or module handles its own slice of logic. Breaking code into logical blocks not only improves readability but also simplifies debugging.

Python

def load_page(url):
    driver.get(url)

def extract_data():
    # Code for data extraction
    pass

def save_data():
    # Code for data saving
    pass

load_page("http://example.com")
extract_data()
save_data()
  

Improving readability and testability of code

Follow the principle of "one function — one task." This will make testing and refactoring easier. Use named constants instead of "magic numbers" and strings for greater clarity.

Python

MAX_RETRIES = 5

def fetch_data_with_retry():
    for attempt in range(MAX_RETRIES):
        try:
            # Attempt to fetch data
            pass
        except Exception as e:
            print(f"Attempt {attempt+1} failed: {e}")
  

3. If the code can be improved, improve it

Use explicit waits instead of implicit ones

Explicit waits allow you to precisely control when Selenium starts performing actions, waiting for the desired elements to appear. Instead of relying on implicit waits (like implicitly_wait), use the WebDriverWait library, which lets you set conditions for specific elements (e.g., element is visible, clickable, etc.).

Example of using explicit wait

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "target_element"))
)
  

Ensure page readiness

After the page loads, not all elements might be immediately available, especially if the site uses asynchronous methods like AJAX. Use document.readyState to check for full document readiness before interacting with it.

Example of checking full page load

Python

def wait_for_page_load(driver):
    WebDriverWait(driver, 10).until(
        lambda d: d.execute_script("return document.readyState") == "complete"
    )
  

Minimize the use of time.sleep

The time.sleep() method makes the script wait for a fixed amount of time and slows it down, especially for long delays. Instead, use WebDriverWait, which is more flexible and stops waiting as soon as the required condition is met.

Use robust element locators

Fragile locators, like XPath paths that depend on specific HTML structures, can quickly break if the site's structure changes. Avoid this by using more robust locators, such as id, name, class, and data-* attributes, which are more stable.

Example of reliable attribute usage

Python

# Use id for locating if available
element = driver.find_element(By.ID, "submit_button")

# If no id, use data-* attribute or unique classes
element = driver.find_element(By.CSS_SELECTOR, "[data-role='main-button']")
  

Close pop-ups and banners

Some websites have popups that can interfere with the script execution. Handling such elements avoids blocking core actions.

Example of closing a popup

Python

from selenium.common.exceptions import ElementClickInterceptedException

try:
    close_popup = driver.find_element(By.CLASS_NAME, "popup-close-button")
    close_popup.click()
except (NoSuchElementException, ElementClickInterceptedException):
    pass  # Ignore if the element is not found or can't be closed
  

Set up logging

Logging helps track script actions and identify issues. Use the built-in logging module to log important script steps, making debugging and analysis easier.

Example of logging setup

Python

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info("Script started")
logging.warning("Element not found, continuing execution")
logging.error("An error occurred")
  

Check element visibility before interacting

Sometimes elements load on the page but are invisible or inaccessible. Use WebDriverWait with the element_to_be_clickable condition to ensure an element is accessible before clicking or entering data.

Python

from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "button_id"))
)
element.click()
  

Handle connection errors and timeouts

When scraping websites, connection errors or timeouts can occur if the server doesn't respond. Set up error handling to skip or retry actions in case the site is temporarily unavailable.

Example of connection error handling

Python

from selenium.common.exceptions import TimeoutException

try:
    driver.get("https://example.com")
except TimeoutException:
    logging.error("Failed to connect to the page. Moving on to the next task.")
  

Close the browser

To avoid resource buildup and ensure the browser is closed in case of errors, always use try-finally or similar constructs to end properly.

Python

try:
    # Your Selenium actions here
    pass
finally:
    driver.quit()  # Close the browser
  

4. Common Rookie Mistakes

Don’t forget to update web drivers and libraries. This helps avoid incompatibility and errors that come with browser updates or changes in Selenium's API.

Finally, if your script often "crashes" without an obvious reason, the test server might be blocking frequent requests. Check if you're violating access rules and consider using proxy servers or adjusting the request frequency.

Optimizing scripts isn’t just a technical task; it’s an art that comes with experience. Hope these tips today help you create reliable and stable scripts that can handle any workload.

1
Task
Python SELF EN, level 38, lesson 3
Locked
Basics of script performance analysis
Basics of script performance analysis
2
Task
Python SELF EN, level 38, lesson 3
Locked
Using Explicit Waits
Using Explicit Waits
4
Task
Python SELF EN, level 38, lesson 3
Locked
Code structure optimization using functions
Code structure optimization using functions
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION