Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To scrape JavaScript-rendered pages with Selenium and Python, open the page in a real browser, wait for the specific content you need, extract its text or attributes, and always close the browser session. A page finishing its initial load does not necessarily mean its dynamic content is ready. The selector and permission to access any particular site depend on that site.

What Selenium does—and what you need first

Selenium’s Python WebDriver binding controls a browser through a browser-specific driver. Before writing a scraper, install the Selenium package in the Python environment you plan to use, choose a supported browser, and follow Selenium’s current setup guide for that browser and its driver: Selenium WebDriver driver setup. The browser, Python binding, and driver setup are all part of the workflow; setup details can depend on your chosen browser and its current version.

This approach is useful when the information appears only after client-side JavaScript runs, or when you need rendered browser content. It is not automatically the best tool for every site: if the site offers an official API or a permitted data export, consider that route first.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A minimal Selenium scraper

The example below opens a page, waits until an article element is visible, prints its rendered text, and closes the browser even if an error occurs. Replace both the URL and selector with ones appropriate for a site you are allowed to access. The example selector is illustrative, not a universal match.

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

url = "https://example.com"

driver = webdriver.Chrome()
try:
    driver.get(url)

    wait = WebDriverWait(driver, 10)
    article = wait.until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "article"))
    )
    print(article.text)
finally:
    driver.quit()

This follows Selenium’s introductory lifecycle: create a Chrome WebDriver, navigate with get(), locate an element, read its text, then call quit(). See the official first-script guide and wait documentation for the APIs used here.

Run it in your project environment

  1. Install Selenium in the Python environment used to run the script, and set up a supported browser and driver using the official driver instructions.

  2. Save the example as a Python file. Change url to the permitted target page and inspect its rendered DOM to choose a selector that identifies the desired content.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  3. Run the file with the Python interpreter for that environment. If the selector matches and the page exposes the element, its text is printed; the finally block closes the browser session.

Choose selectors that match the rendered page

Inspect the page’s rendered DOM in browser developer tools. Selenium recommends using a unique, predictable ID when one is available. Otherwise, a readable CSS selector is often a practical choice. XPath can express more complex relationships, but Selenium notes it can be harder to debug and may be slower. See Selenium’s locator guidance.

Wait for the condition you actually need

driver.get() waits for a document readiness state, but that is not proof that a JavaScript application has finished adding or changing the data you want. Selenium distinguishes document loading from later dynamic rendering. Wait for a useful application condition—such as an element becoming visible, an expected element appearing, or expected text being present—instead of treating navigation completion as the end of every page load. See Selenium’s wait strategies.

Explicit waits for specific states

An explicit wait polls for a condition you choose. In the example, WebDriverWait(driver, 10) waits up to 10 seconds for the selected article to become visible. The value is a timeout for that wait, not a promise that every page will load in that time. Choose a condition that reflects the data you intend to extract; if a page first renders an empty shell, visibility alone may not mean its contents are populated.

Other useful conditions include the presence of a particular element or expected text. For content that appears in stages, wait for the text or populated descendant that indicates the data is ready, rather than merely waiting for the outer container.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why fixed sleeps and mixed waits cause trouble

A fixed sleep guesses how long rendering will take: a short pause may fail on a slow run, while a long one wastes time on a fast run. Selenium also supports implicit waits, which apply across element lookups, but warns: “Do not mix implicit and explicit waits.” Combining them can make total wait timing unpredictable. For dynamic pages, use a consistent explicit-wait strategy rather than layering the two types together.

Extract the fields you need and validate the result

Use .text when you want an element’s visible rendered text. For links or form values, inspect the appropriate DOM attribute or property and extract that instead; the right field depends on how the page represents the data. For repeated records, gather matching elements and extract only the fields needed from each one.

Before processing a large set of pages, inspect a small sample. Check for missing fields, duplicate records, and unexpected text. A selector can match an element without returning the intended data, especially when a site has several similar regions or populates content asynchronously.

Pagination, infinite scrolling, login state, and shadow DOM require target-specific handling. There is no single locator or extraction pattern that solves these cases for every site. Determine how the permitted page exposes the content, then adapt the navigation, waits, and selectors to that structure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Close the browser reliably

Call driver.quit() when finished so Selenium closes the browser session. Put it in a finally block, as in the example, so it also runs when locating or extracting content raises an exception. Without cleanup, failed scripts can leave browser processes or sessions running.

Responsible access: check the specific site

This is a browser-automation guide, not permission to collect data from an unnamed website. Review the target site’s terms, access controls, and permitted methods before running a scraper; use an official API where one is offered. Selenium itself cautions that some sites do not permit scraping and others block Selenium. That warning does not determine the contractual or legal status of scraping a particular site, use case, or jurisdiction. If access is denied or a site blocks automation, stop and review the site’s allowed access route rather than trying to evade the restriction.

Troubleshooting common Selenium scraping problems

No matching element

Check that the browser opened the expected URL and that the selector identifies an element in the rendered DOM. Verify that the content is not inside a different frame and that the selector is scoped to the correct part of the page. If JavaScript creates the element later, add an explicit wait for its presence or visibility.

The element exists but its text is empty

The selector may match a container before the application fills it. Inspect the rendered DOM to see whether the text or a populated child appears later, then wait for expected text or that child. Confirm that you are reading visible text when that is the desired field; a link or input value may instead be represented by an attribute or property.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The scraper is flaky or takes longer than expected

Replace fixed sleeps with waits for meaningful conditions. Keep the wait strategy consistent: Selenium warns against mixing implicit and explicit waits because their combined timing can be unpredictable. Also make the wait condition specific enough to distinguish ready content from an empty page shell.

The site blocks access or returns a bot check

Review the site’s terms and permitted access methods, and stop if the activity is not allowed. Selenium’s guidance notes that some sites prohibit scraping or block Selenium; it does not establish what a particular website permits.

Browser or driver setup fails

Confirm that Selenium is installed in the Python environment running the script, that the selected browser is installed and supported, and that its driver setup follows Selenium’s current instructions. Browser and driver setup is browser-specific, so consult the official setup guide rather than assuming one configuration works for every browser.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a screenshot or PDF rather than extracting structured records, ScreenshotNeo offers a website screenshot API and MCP server. Its API accepts a URL in a GET request and can return a PNG, JPEG, WebP, or PDF. For example, save this as shot.webp using cURL:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

For other client code and request options, see the ScreenshotNeo API documentation. This captures a page visually; it is not a substitute for Selenium when you need to extract and process page data.

  • Before capture, ScreenshotNeo accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off.

  • Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Responses include X-Page-Verdict and X-Billed headers to show the result and billing status.

  • An MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

    What’s actually slowing this PC down?

    Pick the symptom - the matching free tool is one click away.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • The Free plan includes 1,000 screenshots per month with no card required. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Frequently Asked Questions

Does Selenium scrape the HTML source or the rendered page?

Selenium controls a browser, so you can locate and read elements in the rendered page after client-side JavaScript changes it.

Can Selenium determine whether scraping a particular website is allowed?

No. Check the specific site’s terms and permitted access methods; Selenium’s general warning does not resolve permission for an individual site or use.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use Selenium if I only need a screenshot?

Not necessarily. Selenium is useful for browser-driven extraction; ScreenshotNeo can return a screenshot or PDF from a URL without setting up a browser session.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.