使用 XPATH 语句定位动态生成的 Web 元素后的错误

问题描述 投票:0回答:1

正如主题提到的,我在使用 XPATH 语句定位 Web 元素时遇到了麻烦。在我的程序首次启动时,该脚本将使用从单独文件检索的信息来处理数百个条目。当 DOM 内的结构发生明显变化导致错误发生时,就会出现问题。导致 selenium 的 WebDriver 重新定位程序中先前引用的不需要的元素。

错误视频

为了提供更多信息,该元素正在通过此代码片段被 XPATH 定位。

def diagnosis(self, driver, patient): try: wait = WebDriverWait(driver,10) valid_diagnoses = [dx for dx in patient.diagnosis if dx and len(str(dx)) < 1000 and not re.search(r"\bnan\b",str(dx))] xpath_id = [7, 10, 13, 16, 19, 22, 25] count = 0 diagnosis_index = 0 while count < len(valid_diagnoses)/2: wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-sm.btn-secondary.font-medium.text-sm.text-gray-700"))).click() time.sleep(2) try: diagnosis_field = None diagnosis_field = wait.until(EC.visibility_of_element_located((By.XPATH, f'//*[@id="919e06c4ea7e2a5bb720134d693a8671"]/div[2]/div[1]/div[2]/div/form/div/div/div[{xpath_id[count]}]//input[not(@disabled)]'))) text = valid_diagnoses[diagnosis_index].strip() diagnosis_field.send_keys(text) wait.until(EC.text_to_be_present_in_element_value((By.XPATH, f'//*[@id="919e06c4ea7e2a5bb720134d693a8671"]/div[2]/div[1]/div[2]/div/form/div/div/div[{xpath_id[count]}]//input[not(@disabled)]'), text)) except: print(f'An error related to the patient\'s diagnosis being entered is occurring. Program will wait 100 seconds, inspect the HTML') time.sleep(100) patient.dx_issue = True diagnosis_index += 2 count += 1 except TimeoutError: print("Timed out while completing the diagnosis process in Webdriver.py")

DOM 上的目标元素

上图从检查器复制时的 XPATH://*[@id="919e06c4ea7e2a5bb720134d693a8671"]/div[2]/div[1]/div[2]/div/form/div/div/div[10]/div[2]/input

上图从检查器复制时的 XPATH://*[@id="919e06c4ea7e2a5bb720134d693a8671"]/div[2]/div[1]/div[2]/div/form/div/div/div[10]/div[2]/input

提供更多背景信息

我使用了不同类型的选择器,迭代了不同的 CSS_Selectors 和 XPATH 语句,XPATH 最终最适合我的要求,并通过首先使用来解决问题

//*[@id="919e06c4ea7e2a5bb720134d693a8671"]/div[2]/div[1]/div[2]/div/form/div/div/div[{xpath_id[count]}]/div[1]/input

然后将其修改为

//*[@id="919e06c4ea7e2a5bb720134d693a8671"]/div[2]/div[1]/div[2]/div/form/div/div/div[{xpath_id[count]}]//input[not(@disabled)]
我发现第二种方法更可靠地针对 WebElement,因为可能存在我在第一个语句中没有考虑到的 DOM 更改。事实证明,这种方法更具弹性,并且适合我的要求,因为它已经处理了数百个条目。

我可能忽略的“可能的问题”是 Selenium 在长时间运行 WebDriver 时的局限性。我对硒比较陌生,所以我不完全理解程序可以继续运行多长时间而不最终遇到错误的限制。尤其是数百个条目,每个条目都包含一次独特的办公室访问的详细信息。

参考文献

Selenium 长时间运行后出现问题

其他信息

Google Chrome 版本 122.0.6261.95(官方版本)(64 位)

Windows 11 主页
  • 硒4.15.2
  • 编辑
  • 包含
HTML 页面

,可以更深入地了解 DOM 结构

下面是您要查找的输入的相关 HTML。我剪掉了一些不相关的元素和属性,以使其更易于阅读。

python selenium-webdriver selenium-chromedriver
1个回答
0
投票

下面的定位器唯一标识上面的INPUT,

//label[contains(text(),'Diagnosis 2:')]/following-sibling::div/input[@placeholder='Search diagnosis...']


语法意义//标签[contains(text(),'诊断2:')]包含文本“诊断 2:”的 LABEL 标签DIV 标签是上面 LABEL 的同级标签上面 LABEL 的子输入,包含属性 placeholder
/以下兄弟姐妹::div
/input[@placeholder='搜索诊断...']
,其中包含文本“搜索诊断...”
© www.soinside.com 2019 - 2024. All rights reserved.