python 什么是最好的方式来处理等待元素,并不总是与 selenium ?

dffbzjpn  于 2023-05-05  发布在  Python
关注(0)|答案(2)|浏览(107)

例如,如果我有一个这样的代码:

<div id='parent'>
  <div class='profile-pic'>...</div>
  <p class='email'>I'm not always present</p>
  <span class='name'>John Smith</span>
</div>

这是一个随机的例子。但应该有助于形象化我的意思。我想抓个人资料图片,电子邮件和名称。它们都不一定总是出现在页面上。
我可以像这样分别为每个元素设置一个wait:

try:
  wait = WebDriverWait(driver, 10)
  wait.until(EC.visibility_of_element_located((By.CLASS_NAME, 'email')))
except:
  pass

但这意味着每当一个或多个元素不在页面上时,我会为每个元素等待10秒。现在让我们假设我有20个这样的元素,它们可以存在,但并不总是存在,我有1000页要看。这种方法将永远。
这就是我的问题所在。处理这种情况的最佳解决方案是什么?或者这是不应该用Selenium做的事情吗?
到目前为止,我一直在做的是选择父元素并等待它加载,但正如我所了解的那样,这并不能保证所有的子元素都被加载。

wlwcrazw

wlwcrazw1#

这里可以做的是迭代父元素。
对于每个父元素,等待它的出现。
我不知道这里的父元素是否可见。
如果父元素是可见的-等待它的可见性。
现在,等待所需的子元素可见性。这里你可以使用一个短的超时,因为这个超时是在父元素已经存在(但可能还没有完全加载)而子元素仍然需要加载的情况下使用的。
2-3秒应该更多的足够在这里,直到你有非常糟糕的互联网连接/加载是做极低。

wz3gfoph

wz3gfoph2#

如果我理解正确,比你只想进一步进行,如果所有3个必要的元素都存在,那么你可以尝试下面的方法

1下面的代码反复尝试查找所需的元素,直到找到所有元素。当未找到元素时,会捕获NoSuchElementException,循环在重试之前会等待很短的时间,但在这种方法中,您必须指定每个定位器

while True:
    try:
        email = driver.find_element(By.CLASS_NAME('email'))
        profile_pic = driver.find_element(By.CLASS_NAME('profile-pic'))
        name = driver.find_element(By.CLASS_NAME('name'))
        break
    except NoSuchElementException:
        time.sleep(1)

2如果你有一个共同的定位器来识别元素,下面的方法可能是有用的,当你不知道确切的元素数量将出现在页面上,但你知道至少有一定的数量为您的脚本正常工作。我们使用findelements方法在循环内检查给定定位器的元素数量,循环睡眠1秒之间的每一个检查。找到所需数量的元素后,循环退出,脚本可以继续根据需要使用这些元素。

wait = WebDriverWait(driver, 10)
elements = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, '')))
while len(elements) < 10:
    elements = driver.find_elements_by_class_name('')
    time.sleep(1)

# Now we have at least 10 email elements

相关问题