【问题标题】:Python Selenium: How to wait and switch to a dynamic iframe?Python Selenium:如何等待并切换到动态 iframe?
【发布时间】:2018-12-11 03:45:30
【问题描述】:
我目前正在抓取this website。
该网站嵌入了谷歌地图 iframe。每次我在搜索框中输入地址时它都会刷新。
在地图刷新完成之前如何检查?
我目前正在使用:
WebDriverWait(driver, 120).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".gm-style > iframe:nth-child(2)")))
我不确定这是否有效,因为我的互联网速度太快,无法测试。
我在 selenium 网站上查看了definitions of waits,但我不明白它们的意思。
我还发现 a post 使用相同的方法,但不确定它是仅等待 iframe 最初加载还是也等待它更改。
【问题讨论】:
标签:
python
python-3.x
selenium
selenium-webdriver
css-selectors
【解决方案1】:
根据您的问题,如果您打算切换到标识为 (By.CSS_SELECTOR, ".gm-style > iframe:nth-child(2)") 的 <iframe>,您需要诱导 WebDriverWait 以使 <iframe> 可用并切换到它 您可以使用以下解决方案:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,".gm-style > iframe:nth-child(2)")))
【解决方案2】:
我试过这段代码:
driver.get('https://www.bungol.ca/map/location/scarborough/?')
time.sleep(3)
refresh_count = 0
while True:
try:
driver.refresh()
# WebDriverWait(driver, 120).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".gm-style > iframe:nth-child(2)")))
el = driver.find_element_by_css_selector(".gm-style > iframe:nth-child(2)")
assert el.is_displayed()
refresh_count += 1
except Exception:
print("Refresh count = " + str(refresh_count))
输出是:
Refresh count = 0
Refresh count = 43
Refresh count = 44
Refresh count = 56
Refresh count = 62
Refresh count = 63
Refresh count = 64
Refresh count = 68
Refresh count = 69
iframe 不在 DOM 的 0、43、44、...处。第一次失败是因为第一次加载时间长。然后很好,我决定通过将Chrome 切换到移动版本来模拟慢速连接。然后它已经相对经常失败了。
然后我设置了WebDriverWait:
while True:
try:
driver.refresh()
WebDriverWait(driver, 120).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".gm-style > iframe:nth-child(2)")))
el = driver.find_element_by_css_selector(".gm-style > iframe:nth-child(2)")
assert el.is_displayed()
refresh_count += 1
except Exception:
print("Refresh count = " + str(refresh_count))
它没有抛出任何异常。所以你可以使用EC.presence_of_element_...