如何用Selenium定位AngularJS页面中无ID的特定元素
搞定AngularJS订单表格的Selenium元素定位
嘿,我来帮你解决这个AngularJS页面里无ID元素的定位问题!毕竟在Angular项目里,靠ID定位确实不太靠谱,我们完全可以利用框架自带的属性、元素文本或者位置来精准锁定目标~结合你之前定位price_tir、price_mordad的思路,下面是每个需求元素的具体定位方案:
首先先假设你的订单表格是用ng-repeat循环渲染的(比如<tr ng-repeat="order in orderList">),每行对应一个订单——这种情况下,我们可以先定位到目标订单的整行,再找里面的各个<td>,这样能避免定位到其他行的重复内容,更精准。
1. 合约代码(SAFMO98)
如果合约代码是固定文本,或者你知道它在表格里的列位置,可以这么写:
# 方法1:直接匹配文本内容,一步到位 contract_code_elem = driver.find_element(By.XPATH, "//td[text()='SAFMO98']") # 方法2:先定位目标订单行,再取对应列(假设合约代码是第一列) # 先找到包含SAFMO98的行 target_order_row = driver.find_element(By.XPATH, "//tr[td[text()='SAFMO98']]") # 再从行里拿第一列的合约代码元素 contract_code_elem = target_order_row.find_element(By.XPATH, "./td[1]")
2. 订单类型(买入/卖出)
如果订单类型是通过ng-bind绑定的(比如<td ng-bind="order.type"></td>),可以结合属性和文本定位;或者从已经找到的目标行里取对应列:
# 方法1:直接定位"买入"类型的元素 buy_order_type_elem = driver.find_element(By.XPATH, "//td[ng-bind='order.type' and text()='买入']") # 方法2:从目标订单行里取(假设是第二列) order_type_elem = target_order_row.find_element(By.XPATH, "./td[2]")
3. 已成交量(0)
同理,要么直接匹配文本,要么从目标行里拿对应列:
# 直接匹配已成交量为0的元素 filled_qty_elem = driver.find_element(By.XPATH, "//td[text()='0']") # 从目标行里取(假设是第三列) filled_qty_elem = target_order_row.find_element(By.XPATH, "./td[3]")
4. 挂单量(1)
# 直接定位挂单量为1的元素 pending_qty_elem = driver.find_element(By.XPATH, "//td[text()='1']") # 从目标行里取(假设是第四列) pending_qty_elem = target_order_row.find_element(By.XPATH, "./td[4]")
5. 价格(129900/140000)
如果价格是绑定的order.price,可以结合属性定位;或者从目标行里拿:
# 定位特定价格的元素 price_elem = driver.find_element(By.XPATH, "//td[ng-bind='order.price' and text()='129900']") # 从目标行里取(假设是第五列) price_elem = target_order_row.find_element(By.XPATH, "./td[5]")
6. 订单状态(已在交易所提交)
# 直接匹配状态文本 status_elem = driver.find_element(By.XPATH, "//td[text()='已在交易所提交']") # 从目标行里取(假设是第六列) status_elem = target_order_row.find_element(By.XPATH, "./td[6]")
7. 交易渠道(在线)
# 直接匹配渠道文本 channel_elem = driver.find_element(By.XPATH, "//td[text()='在线']") # 从目标行里取(假设是第七列) channel_elem = target_order_row.find_element(By.XPATH, "./td[7]")
额外实用技巧
用CSS选择器结合Angular属性定位
除了XPath,还可以用CSS选择器结合Angular的专属属性,比如定位所有订单行:
# 拿到所有ng-repeat渲染的订单行 all_order_rows = driver.find_elements(By.CSS_SELECTOR, "tr[ng-repeat='order in orderList']") # 遍历行找目标订单 for row in all_order_rows: current_code = row.find_element(By.CSS_SELECTOR, "td:first-child").text if current_code == "SAFMO98": # 在这里获取该行的所有字段 order_type = row.find_element(By.CSS_SELECTOR, "td:nth-child(2)").text filled_qty = row.find_element(By.CSS_SELECTOR, "td:nth-child(3)").text # ...其他字段依次类推 break
别忘了等待元素加载!
Angular页面加载可能有延迟,别用time.sleep()硬等,用WebDriverWait更靠谱:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待合约代码元素出现,最多等10秒 contract_code_elem = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//td[text()='SAFMO98']")) )
这样就不用担心元素还没加载出来就去定位啦~
内容的提问来源于stack exchange,提问作者lovecode
相关产品推荐
相关产品推荐

