如何使用Selenium + Python根据其他元素文本点击正确链接?
问题描述
我有如下HTML结构:
<tbody> <tr role="row" class="odd"> <td class="text-center dtr-control"></td> <td class="text-center"> <a href="#" class="px-2 text-dark" onclick="bookPatient('1351','')"> <i class="fa-solid fa-pen-to-square cursor-pointer fa-lg"></i> <i class="fa-solid fa-pen-to-square cursor-pointer fa-lg"></i> </a> </td> <td>Dedeh</td> <td class="text-center">Female</td> <td class="text-center">07/02/1983</td> <td class style>PT MAJU JAYA</td> </tr> <tr role="row" class="odd"> <td class="text-center dtr-control"></td> <td class="text-center"> <a href="#" class="px-2 text-dark" onclick="bookPatient('1352','')"> <i class="fa-solid fa-pen-to-square cursor-pointer fa-lg"></i> <i class="fa-solid fa-pen-to-square cursor-pointer fa-lg"></i> </a> </td> <td>Mira</td> <td class="text-center">Female</td> <td class="text-center">17/10/2002</td> <td class style>PT MAJU JAYA</td> </tr> </tbody>
我想用Selenium找到包含指定出生日期(searched_text_bod)的行,然后点击该行内的<a>元素,但现有代码无法稳定识别目标<a>元素,网站元素缺少可用的类名或ID,定位起来很麻烦。
我尝试的代码如下:
searched_text_bod = "20/03/1990" # Improved XPath targeting based on confirmed structure base_xpath = "//tbody/tr[@role='row']" patient_row_xpath = f"{base_xpath}/td[text()='{searched_text_bod}']" try: # Find patient row containing the exact date of birth patient_link = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, patient_row_xpath))) edit_patient_info = patient_link.find_element(By.XPATH, "/following-sibling::td/a") if patient_link: print(f"Found patient with date of birth: {searched_text_bod}") edit_patient_info.click( ) # Click on the 'a' element (assuming it's the link) else: print( f"Patient with date of birth '{searched_text_bod}' not found using DoB search" )
解决方案
你的代码存在两个核心问题,修正后即可稳定定位元素:
XPath路径错误
你使用/following-sibling::td/a时,开头的/会让XPath从根节点重新查找,而非从当前patient_link节点的同级元素开始。同时看HTML结构,出生日期所在<td>在<a>所在<td>的后方,following-sibling是查找后续同级元素,方向完全反了,应该用preceding-sibling。更稳妥的写法是先回到父级
<tr>,再直接定位第2个<td>内的<a>,相对路径可写成../../td[2]/a,或者直接定位整行后再查找<a>。定位逻辑缺陷
你当前定位的是出生日期的<td>元素而非整行,后续查找同级元素容易出错。建议直接定位包含目标出生日期的<tr>,再从行内查找<a>元素。
修正后的代码示例:
searched_text_bod = "20/03/1990" # 直接定位包含目标出生日期的行 patient_row_xpath = f"//tbody/tr[@role='row'][td[text()='{searched_text_bod}']]" try: # 等待行元素加载完成且可点击 patient_row = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, patient_row_xpath)) ) # 从行内查找第2个<td>里的<a>元素 edit_patient_info = patient_row.find_element(By.XPATH, "./td[2]/a") print(f"找到出生日期为 {searched_text_bod} 的患者") edit_patient_info.click() except TimeoutException: print(f"未找到出生日期为 '{searched_text_bod}' 的患者")
额外优化建议:
- 使用
element_to_be_clickable代替presence_of_element_located,确保元素不仅存在还可点击 - 如果日期
<td>包含空格或格式问题,可用normalize-space(text())='{searched_text_bod}'处理空白字符,或用contains(text(), '{searched_text_bod}')做模糊匹配
内容的提问来源于stack exchange,提问作者Vin_
相关产品推荐
相关产品推荐

