当我“读取”列的文本内容时,为什么会得到StaleElementReferenceException?

时间:2019-05-19 09:14:50

标签: python python-3.x selenium google-chrome selenium-chromedriver

仅当我尝试两次收集(“抓取”)表的内容时,才会出现此问题。第一次读取表内容成功,但是第二次总是失败。

仅在Chrome浏览器(带有相应chromedriver的74版)上会发生这种情况。我用FireFox尝试了同样的方法,但从未发生过。我在Chrome中找到了一种解决方法,这没有任何意义,但确实可以解决问题。

当我“转到”除包含该表的屏幕以外的其他屏幕,然后返回时,表爬网成功。

以下是我用来收集表格的功能:

def Get_Faults_List(Port_Number=None, PSU=None, Retries=5):
    for attempt in range(Retries):
        try:
            if Port_Number:
                # Show the Faults view in the context of "Port_Number"
                Device_Panel_Frame.Click_Port(self, Port_Number)
            elif PSU:
                if not Device_Panel_Frame.Click_PSU(self, PSU):
                    return None
            Left_Panel_Frame.Click_Fault(self)

            self.driver.switch_to_default_content()
            Main_Body = self.driver.find_element_by_name('main_page')
            self.driver.switch_to.frame(Main_Body)
            alarms_tab = self.driver.find_element_by_id('tab_alarms')
            alarms_tab.click()
            Fault_Screen = self.driver.find_element_by_name('faults')
            self.driver.switch_to.frame(Fault_Screen)
            # the rows that the following variable collect are automatically
            # the relevant fault lines. The XPATH that was used omits the two
            # irrelevant lines
            faultTable_rows = WebDriverWait(self.driver, timeout=3, poll_frequency=0.5).until(
                EC.presence_of_all_elements_located((By.XPATH, "//table[@id='faultTab']//tr[not(@id or @style)]")))

            current_faults = []
            row_index = 0
            for row in faultTable_rows:  # Go through each of the rows
                current_faults.append([])
                # Collect all the column elements of a certain row into a list
                faultTable_row_cols = row.find_elements_by_tag_name("td")
                for col in faultTable_row_cols:
                    # Each row of the Faults table is separated into 5 columns each column holds a string
                    current_faults[row_index].append(col.text)
                row_index += 1

            break
        except:
            print(attempt + 1, 'attempt failed', Retries - (attempt + 1), 'to go')
            self.Refresh_Screen()
            sleep(5)
            continue

如果我打开新的浏览器,我还将成功收集表格的内容。顺便说一句,故障总是发生在下表的第一行(标题之后)。该行是current_faults[row_index].append(col.text),我不明白为什么。例外没有任何意义。

还有另一种方法可以有效地爬网表的内容吗?

表: enter image description here

1 个答案:

答案 0 :(得分:1)

有关获得Stale Element Reference Exception的原因,请参见this answer

  

当元素:{p>      

      
  1. 已被删除
  2.   
  3. 不再与DOM相连(如您的情况)
  4.   
  5. 已更改
  6.   
     

从文档中

     
    

您应该丢弃当前持有的引用并替换它,可能是通过将元素附加到DOM上再次找到它来实现。

  
     

即:再次“查找”该元素。

我的建议是捕获HTML并在其上循环:

您可以依次使用driver.page_sourceStale Element Reference Exception

html = driver.page_source
soup = BeautifulSoup(html, "lxml")

这应该在切换帧之后实现。

希望这对您有帮助!