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

Selenium WebDriver can control a browser that loads Google Flights; Beautiful Soup can then parse HTML that the browser has already obtained. They serve different steps, not competing ones. This is an educational workflow, not a promise that Google Flights has a stable scraper interface or that a particular automated use is permitted. Check Google’s current terms and page instructions before proceeding.

What Selenium and Beautiful Soup each do

Selenium WebDriver opens and controls a browser: it can navigate to a page, interact with controls, and wait for page state. Beautiful Soup parses HTML or XML that your code already has; it does not render a page or fetch its dynamically loaded content by itself.

For a page that depends on browser-side rendering, the conceptual sequence is: load it with Selenium, wait for the content you need, inspect the delivered markup, pass that markup to Beautiful Soup, extract a small set of fields, validate them, and close the browser. This explains the technical roles, but does not establish that automated access is allowed for a particular purpose.

Check access rules before automating

Google’s Terms of Service restrict automated access that violates machine-readable instructions on its pages, such as robots.txt, and prohibit bypassing protective measures. Review the current terms and applicable page instructions for your use. Do not evade a block, CAPTCHA, or other protection. This general guidance does not determine the legality of a specific use in every jurisdiction.

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

Google describes Google Flights as a metasearch service that presents flight options and booking links. Its partner material concerns onboarding airlines and online travel agencies and describes an invite-only process; it does not document a general-purpose public API for arbitrary developers. If you need structured data for a product or service, investigate currently authorized partner or licensed-data routes rather than assuming a browser script is an approved feed.

Set up Python and Selenium

Use an isolated Python environment so the dependencies for this script do not affect other projects. The Selenium Python API documentation lists version 4.49.0 as its latest release at the time reflected in that documentation; check the live API documentation for the current release and installation guidance.

  1. Create and activate a virtual environment from your project directory: python -m venv .venv. On macOS or Linux, activate it with source .venv/bin/activate; on Windows PowerShell, use .venvScriptsActivate.ps1.

  2. Install the packages: python -m pip install selenium beautifulsoup4.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  3. Use a browser supported by your Selenium installation. Selenium Manager handles driver setup for most supported platforms and browsers, so a separate manual driver download is often unnecessary. Platform support and browser compatibility can vary; consult Selenium’s current documentation if setup fails.

Load a page and wait for a real condition

Do not assume a fixed sleep makes a page ready. Prefer an explicit wait for a condition that matters to your permitted task, such as the presence of a known element you have just verified in the browser. Google Flights is an interactive interface, and its markup and selectors can change. The example below is deliberately a framework: it waits for the document to finish loading, captures the current HTML, and parses the title. It does not claim a Google Flights-specific selector or extract flight results.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from bs4 import BeautifulSoup

url = "https://www.google.com/travel/flights"
driver = webdriver.Chrome()

try:
    driver.get(url)
    WebDriverWait(driver, 30).until(
        lambda browser: browser.execute_script(
            "return document.readyState"
        ) == "complete"
    )

    html = driver.page_source
    soup = BeautifulSoup(html, "html.parser")
    print("Page title:", soup.title.get_text(strip=True) if soup.title else "(missing)")
finally:
    driver.quit()

A completed document load is not proof that every result or client-rendered component has appeared. For your own permitted test page, inspect the rendered page with browser developer tools, identify a stable element associated with the content, and wait for that element to become present or visible. If a selector disappears or a wait expires, treat that as a signal to inspect the page rather than to bypass a protection.

Inspect markup and parse only what you need

Once Selenium has obtained the markup, Beautiful Soup builds a navigable parse tree. Specify a parser explicitly, as in BeautifulSoup(html, "html.parser"). Beautiful Soup documents that parsers can produce different trees, particularly for malformed documents, so a parse result can depend on the parser choice as well as on the input HTML.

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

For a page you are authorized to inspect, first examine the relevant element in browser developer tools and confirm that its content appears in the HTML Selenium returns. Then target a narrowly scoped element and handle missing fields rather than assuming every result has the same shape. For example, after verifying that your own page has an element with a class named fare, you could use:

fare = soup.select_one(".fare")
price_text = fare.get_text(" ", strip=True) if fare else None
print(price_text)

The class above is an illustrative example, not a verified Google Flights selector. Do not copy it into a Google Flights scraper and expect it to work. If the needed content is not present in the captured markup, Beautiful Soup cannot conjure it; inspect the browser state and use an appropriate, permitted workflow instead.

Validate extracted flight information

Extraction is not complete when a script prints a price. Verify each value against what the rendered page actually shows, and preserve missing or ambiguous fields rather than silently guessing.

Do not confuse the first result with the cheapest fare

Google says its default Best Flights ordering considers price, duration, time of day, and other factors. Its best departing flights reflect trade-offs between price and convenience, including trip duration, stops, and airport changes. Consequently, a result’s position in the default list does not by itself mean it is the lowest priced option. If a permitted analysis needs a price comparison, define the comparison criteria and validate the displayed values rather than using rank position as a substitute.

Reliability, performance, and maintenance

Browser automation has more moving parts than parsing a saved HTML document: a browser must start, load the page, reach the relevant state, and expose markup to your code. There is no sourced benchmark here for runtime, success rate, or coverage, so do not plan around an assumed throughput figure. Test the workflow in the environment and at the scale your allowed use requires.

  • Selectors are implementation details. A site redesign or changed markup can break a selector. Keep selectors in one place, fail clearly when required data is absent, and re-inspect the rendered page when extraction changes.

  • Keep sessions bounded. Always call driver.quit() in a finally block so the browser session is closed even after a parsing or wait error.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Use waits tied to state. A fixed delay can be too short on a slow load and waste time on a fast one. An explicit wait for a verified, relevant condition is easier to reason about.

  • Choose the parser deliberately. Beautiful Soup’s documentation notes that parser choices may yield different trees for malformed input. If a document’s structure matters, use a consistent parser and validate the fields you extract.

  • Respect access boundaries. A technically functioning script is not evidence of authorization. Stop when a page instruction or protection disallows the activity; do not try to work around it.

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

Troubleshooting common failures

WebDriver cannot start or find a browser

Confirm that a supported browser is installed and available to the user running Python, and that your Selenium version supports the browser/platform combination. Selenium Manager handles setup on most supported configurations, but not every environment. Check Selenium’s current installation documentation and the exact exception text before attempting manual driver configuration.

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

The explicit wait times out

The condition may not match the page state, the target may not have loaded, or the page’s markup may have changed. Inspect the browser window and developer tools, verify the element exists and is in the state your wait expects, and update your code only after confirming the current markup. Do not respond to a block or CAPTCHA by attempting evasion.

Beautiful Soup returns no matching element

Print a small, relevant portion of the captured HTML or inspect the page source saved for diagnosis. Confirm that the target content is actually in driver.page_source, then verify the selector against that markup. If the content is absent, a parser selector cannot retrieve it; reassess the permitted data source or browser state.

The text is malformed or fields are missing

Check which parser you selected, whether the input HTML is complete, and whether the source structure is malformed or different than expected. Add explicit missing-value handling and compare extracted values with the rendered page. Do not silently map an unknown or missing value to a plausible-looking fare.

The output’s ordering does not match your price expectations

Check whether you are reading the default Best Flights ordering. Google describes that ordering as factoring in more than price, so verify the displayed fare and the ordering context instead of assuming the first item is cheapest.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Or skip the browser setup

If you need screenshots rather than a Google Flights data feed, ScreenshotNeo is a screenshot API and MCP server for developers. It can accept a URL in one GET request and return a PNG, JPEG, WebP, or PDF. A screenshot is an image or document, not structured flight data for a scraper.

For permitted pages, a basic request is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for parameters and formats. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed, and response headers identify the page verdict and billing status. Its MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for free.

When this approach is—and is not—the right fit

Selenium plus Beautiful Soup is useful for learning how browser control and markup parsing fit together, or for authorized tests where browser-rendered state is part of the task. It is not a documented Google Flights data API, and no specific selector or extraction script here is presented as tested against current Google Flights markup. For a dependable service or product integration, pursue a currently authorized structured-data source and verify its terms and availability before building around it.

Frequently Asked Questions

Can Beautiful Soup scrape dynamically loaded content by itself?

No. Beautiful Soup parses markup already obtained; it does not render browser-side content. Selenium can load and control the browser, after which you can pass captured HTML to Beautiful Soup.

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

Does Google provide a public Google Flights API for any developer?

The Google Flights partner material described here is invite-only and does not document a general-purpose public API for arbitrary developers. Check Google’s current partner information for current options.

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.