当前位置: 首页 > 知识库问答 >
问题:

有没有办法给硒找到元素/S的限制时间?

许华清
2023-03-14

我正在尝试使用Python Selenium Chrome驱动程序实现谷歌地图的自动化,我的代码是稳定的,可以得到我需要的东西,但不是性能时间。

我使用迭代代码在Google Maps上获取商家数据,使用Selenium获取1个商家数据的时间速率低于1秒,但是当代码捕获到异常时,需要花费很长的时间,比如6-7秒。

下面是一些执行时间的总结:

https://picoolio.net/image/dgxc(正常执行时间)

https://picoolio.net/image/dgxt(打开时间发生异常时的执行时间,太长)

https://picoolio.net/image/dgxv(发生异常时的执行时间,有时按预期运行)

下面是获取开放时间列表的一些代码:

try:
      openhour = wait(driver, 1).until(EC.visibility_of_element_located((By.XPATH, 
                           './/span[@class="section-open-hours-button maps-sprite-pane-info-arrowup"]')))

      driver.execute_script("arguments[0].scrollIntoView(true);", openhour)
      openhour.click()
      openhourstacked = wait(driver, 1).until(EC.visibility_of_element_located((By.CLASS_NAME, 
                                  'section-open-hours-container-hoverable'))).get_attribute("aria-label")
      openhourlist = openhourstacked.split(",")
      openhourlist[len(openhourlist) - 1] = openhourlist[len(openhourlist) - 1].split(".")
      openhourlist[len(openhourlist) - 1] = openhourlist[len(openhourlist) - 1][0]

      except NoSuchElementException:
         openhourlist = []
         print("No Open Hour list in this merchant!")
         openhour_trig = True
      except WebDriverException:
         openhourlist = []
         print("Failed to load Open Hour list in this merchant!")
         openhour_trig = True

很多建议都说,要正确地执行显式等待,我应该使用WebDriverWait和EC(预期条件)的组合,我直接用上面的代码尝试了它,但是WebDriverWait似乎不能处理所有传入的异常,换句话说,有时成功,有时失败。

我尝试将ec.visibility_of_all_element_located替换为ec.presence_of_all_element_located,但没有任何区别。

我希望在有任何异常发生的情况下使执行时间仍然平稳,除了以上的方法之外,有没有什么方法可以使硒在超时的情况下停止寻找元素呢?还是这是一个互联网连接的问题?欢迎有任何想法!

更新:所以我修改开放时间代码如下所示

try:
              if len(driver.find_elements(By.XPATH, './/span[@class="section-open-hours-button maps-sprite-pane-info-arrowup"]'))>0:
                        openhour = wait(driver, 5).until(EC.visibility_of_element_located((By.XPATH, 
                                       './/span[@class="section-open-hours-button maps-sprite-pane-info-arrowup"]')))
                        #openhour = driver.find_element_by_xpath('.//span[@class="section-open-hours-button maps-sprite-pane-info-arrowup"]')
                        driver.execute_script("arguments[0].scrollIntoView(true);", openhour)
                        openhour.click()
                        #openhourstacked = driver.find_element_by_class_name('section-open-hours-container-hoverable').get_attribute("aria-label")
                        openhourstacked = wait(driver, 5).until(EC.visibility_of_element_located((By.CLASS_NAME, 
                                              'section-open-hours-container-hoverable'))).get_attribute("aria-label")
                        openhourlist = openhourstacked.split(",")
                        openhourlist[len(openhourlist) - 1] = openhourlist[len(openhourlist) - 1].split(".")
                        openhourlist[len(openhourlist) - 1] = openhourlist[len(openhourlist) - 1][0]
                    else:
                        openhourlist = []
                        print("No Open Hour list in this merchant! (Not an Exception)")
                except NoSuchElementException:
                    openhourlist = []
                    print("No Open Hour list in this merchant!")
                    openhour_trig = True
                except WebDriverException:
                    openhourlist = []
                    print("Failed to load Open Hour list in this merchant!")
                    openhour_trig = True

是的,这种方式确实避免了异常,但这会重复以前的搜索,所以当元素没有找到时,可能会再次进行长达6-7秒的长时间搜索…我认为,在这些术语中,明确的等待也没有什么帮助

共有2个答案

苏高旻
2023-03-14

是的,显式等待(webdriver wait)解决此问题。另一个简单的方法是创建一个带有timeseconds的for循环,并在循环中写入find元素,因此即使失败,它也将检查180secs并写入超出预期等待时间的条件

  for (int second = 0; second < 60; second++) {
  try {} 
  catch (WebDriverException we) 
  {}
  if (second >= 60) {
  //write failure 
  }
乜华翰
2023-03-14

摘要:

在代码中,尝试增加显式等待的时间。它不会减慢你的速度,但它会防止那些例外。尝试5秒而不是1秒。尝试此等待(驱动程序,5)

我们使用waits是因为加载DOM需要时间,有时我们需要等待页面/元素加载/隐藏/更改,并且我们必须根据更改执行操作。
显式waits的作用是等待给定的时间以满足预期的条件,并每隔500milisconds检查条件是否满足。这样,在执行下一个任务之前,您将损失最多500miliseconds的时间。如果这些条件没有及时满足,它将抛出一个超时异常。显式等待并不能解决您的所有问题。

您仍然需要检查可能出现的异常,并决定在发生异常时执行什么操作。有些站点加载速度很慢,或者有时您的带宽很低。那么你就没有办法加快进程了。

您必须首先分析页面并确定需要什么。如果您正在等待某个元素出现,但有可能它不存在,那么您应该相应地处理异常。

如果您正在检查页面中是否存在某个元素,那么最好不要等待该元素,而是尝试使用find_elements_并检查列表的大小。这样您就可以避免异常,并且速度更快。

driver.find_elements(By.ID, "locator").size()>0
 类似资料:
  • 问题内容: 我有一个整数数组列表。我需要找到两者之间的共同点。我能想到的是 两个列表 中“ 通用”元素中列出的内容 的扩展 数组中也没有重复项。 有没有直接的方法可以做到这一点? 问题答案: 您可以将列表转换为集合,然后使用方法在不同集合之间进行交集。与所有集合相交后,剩下的就是公共元素,可以将结果集合转换回列表。

  • 使用Java8+,您可以轻松找到与匹配的集合的所有元素。

  • 我是硒的新手,请帮帮我。整个代码: 如何为以粗体突出显示的元素选择xpath?我试过很多例子,但不幸的是没有一个像预期的那样有效。任何帮助都会很好。

  • “进入库存警报”对象 我不想单击“添加到购物车”。我只想把定位器信息存储在WebElement“AddToCart”中。因为对象具有非常相同的属性,所以我选择了这个唯一的属性“data-tl-id”,但没有起作用。 Web驱动程序 我得到错误“no such element:Unable to locate element:”。如何定位“添加到购物车”对象?

  • 我试图创建一个流,使AWS DynamoDB流仅在达到批量大小限制或达到指定时间间隔(即批量大小为100,时间间隔为5分钟)时触发Lambda函数。假设只有50个记录更新,距离上次调用只有4分钟。如果记录更新未达到100,我希望在下一分钟触发lambda。如果在下一分钟之前达到100,则触发lambda并重置时钟。 我试着只使用批量大小限制。这不起作用。如果我做两次更新,它会调用lambda两次。