Scraping data from tables connected to each dot on a map
Some key things to take into account when using selenium:

if you have an id of an element - use it - it's the fastest way to locate an element
wait.until() returns a WebElement with most of the Expected Conditions - there is no need to find the element again if you want to use the element you've been waiting for
WebDriverWait() can be instantiated once per driver and reused
time.sleep() waits have to be avoided - they are making the code slower than needed most of the time, they are unreliable and not tied to any condition on a page, and sometimes the delay you set is not enough

You don't have to click through every circle on the map
We can seriously improve on web-scraping speed by extracting the &quot;token&quot; (let's call it this way) from the iframe URL and then making a REST API request to a specific endpoint with the data using requests:
from urllib.parse import parse_qs, urlparse

import requests
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    


driver = webdriver.Chrome()
driver.get(&quot;https://acwi.gov/monitoring/vm/programs/vm_map.html&quot;)

wait = WebDriverWait(driver, 10)

# get the token from the frame src
frame = wait.until(EC.presence_of_element_located((By.TAG_NAME, 'iframe')))
token = parse_qs(urlparse(frame.get_attribute(&quot;src&quot;)).query)['webmap'][0]

driver.close()

# parse data
response = requests.get(&quot;http://www.arcgis.com/sharing/rest/content/items/{token}/data?f=json&quot;.format(token=token))
data = response.json()

for item in data[&quot;operationalLayers&quot;][0][&quot;featureCollection&quot;][&quot;layers&quot;][0][&quot;featureSet&quot;][&quot;features&quot;]:
    coordinates = item[&quot;geometry&quot;][&quot;x&quot;], item[&quot;geometry&quot;][&quot;y&quot;]
    attributes = item[&quot;attributes&quot;]

    print(coordinates, attributes[&quot;MPN&quot;])