Skip to content
>GLB_
Go back

Selenium vs Beautiful Soup: when to use each, and how to combine them

· Updated

Selenium and Beautiful Soup are often named together, but they solve different parts of a scraping job. Selenium automates a real browser: it opens pages, clicks, fills forms and runs JavaScript. Beautiful Soup parses HTML and XML that you already have; it never talks to a website itself, so you fetch the page with another library such as requests. Picking the wrong one is the most common reason a first scraper either can’t see the data or is far slower than it needs to be.

Which one to use

You need to…Use
Parse static HTML that a plain GET request returnsrequests + Beautiful Soup
Read content that JavaScript loads after the page opensSelenium
Click, type, submit forms, or log in before the data appearsSelenium
Interact with the page and then extract a lot of structured dataSelenium to load, Beautiful Soup to parse

The quick test: open the page source (not the browser inspector) and search for the data. If it is there, a GET request and Beautiful Soup are enough. If it only appears after scripts run or after you interact with the page, you need Selenium.

Selenium: automating the browser

Selenium controls a browser programmatically. Besides scraping, it is widely used for automated testing of web applications.

A basic Selenium 4 script:

from selenium import webdriver
from selenium.webdriver.common.by import By

# Set up the browser
driver = webdriver.Chrome()

# Navigate to a webpage
driver.get("https://example.com")

# Interact with elements
search_box = driver.find_element(By.NAME, "q")
search_box.send_keys("Web Scraping with Selenium")
search_box.submit()

# Extract data
results = driver.find_elements(By.CLASS_NAME, "result")
for result in results:
    print(result.text)

# Close the browser
driver.quit()

Beautiful Soup: parsing HTML

Beautiful Soup builds a parse tree from HTML or XML and gives you a Pythonic way to search and navigate it. It works best on static content, and pairs with requests to fetch pages.

from bs4 import BeautifulSoup
import requests

# Fetch the webpage
response = requests.get("https://example.com")
html_content = response.content

# Parse the HTML
soup = BeautifulSoup(html_content, 'html.parser')

# Extract data
for item in soup.find_all('h2'):
    print(item.text)

Combining them: Selenium to load, Beautiful Soup to parse

When the page needs a browser but the extraction itself is plain HTML parsing, let Selenium render the page, hand page_source to Beautiful Soup, and close the browser as early as possible.

Load the page with Selenium and wait for the content you need:

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

# Set up the browser
driver = webdriver.Chrome()
driver.get("https://example.com")

# Wait until the dynamic content is present
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "h2")))

# Get page source
html_content = driver.page_source

# Close the browser
driver.quit()

Then parse it with Beautiful Soup:

soup = BeautifulSoup(html_content, 'html.parser')

# Extract data
for item in soup.find_all('h2'):
    print(item.text)

Gotchas


Share this post:

Related Posts


Previous Post
Retries in Python: from a basic retry loop to exponential backoff for API rate limits
Next Post
Soda Core with SQL Server: connection, Windows auth, SSL errors and checks