【问题标题】:In XPath, how do i look for something between two elements?在 XPath 中,我如何在两个元素之间寻找一些东西?
【发布时间】:2021-11-06 04:51:21
【问题描述】:

问题: 我正在使用 Selenium 在本网站的输入字段中输入数据。 其中一个表有问题,因为它没有这些字段的唯一 ID。 我想在“name2”上的“project2”下的输入字段中输入文本。所有项目在其项目中具有相同的名称。名称可能会更改,并且将来可能会添加一些新字段。

问题: 是否可以在我在 project2 之后但同时在 project3 之前做某事的地方进行 XPATH 查询? 例如://something/preceding-sibling::tr and //something_else/following-sibling::tr

提前致谢。

示例代码:

<table border="0">
    <tr><td>project1</td><td></td></tr>
    <tr><td>name1</td><td><input type="text"></td></tr>
    <tr><td>name2</td><td><input type="text"></td></tr>
    <tr><td>name3</td><td><input type="text"></td></tr>
    <tr><td>name4</td><td><input type="text"></td></tr>

    <tr><td>project2</td><td></td></tr>
    <tr><td>name1</td><td><input type="text"></td></tr>
    <tr><td>name2</td><td><input type="text"></td></tr>
    <tr><td>name3</td><td><input type="text"></td></tr>
    <tr><td>name4</td><td><input type="text"></td></tr>

    <tr><td>project3</td><td></td></tr>
    <tr><td>name1</td><td><input type="text"></td></tr>
    <tr><td>name2</td><td><input type="text"></td></tr>
    <tr><td>name3</td><td><input type="text"></td></tr>
    <tr><td>name4</td><td><input type="text"></td></tr>
</table>

截图:

【问题讨论】:

    标签: selenium dom xpath xpath-2.0 xpath-1.0


    【解决方案1】:

    你可以试试下面的xpath:

    //td[text()='project2']/../following-sibling::tr[2]/descendant::input
    

    更新:

    如果td[2] 是问题,那么可能使用这个:

    //td[text()='project2']/../following-sibling::*/td[text()='name2']/following-sibling::td/input
    

    甚至是下面的一个:

    (//*[text()='project2']/../following-sibling::*/*[text()='name2'])[1]/following-sibling::td/input
    

    【讨论】:

    • 是的,这可能会起作用,但问题是如果他们在两者之间添加另一个字段,对吗?但如果以其他方式不可能,这是一个很好的候选。
    • 见上文,稍作修改。不推荐最后一个,但即使他们添加更多 trtd,最后一个也会起作用
    • 我会推荐使用这个//td[text()='project2']/../following-sibling::*/td[text()='name2']/following-sibling::td/input,因为即使它有多个匹配节点,Selenium find_element 总是会选择第一个
    【解决方案2】:

    这会给你你想要的:

    //tr[preceding-sibling::tr[td[.="project2"]]][not(preceding-sibling::tr[td[.="project3"]])][td[.="name2"]]/td/input
    

    上面将找到所有&lt;tr&gt; 元素:

    1. &lt;tr&gt; 元素之后出现,该元素包含&lt;td&gt; 和文本“project2” -> [preceding-sibling::tr[td[.="project2"]]]
    2. 位于&lt;tr&gt; 元素之前,该元素包含带有文本“project3”的&lt;td&gt; -> [not(preceding-sibling::tr[td[.="project3"]])]
    3. 带有&lt;td&gt; 元素,其中包含文本“name2” -> [td[.="name2"]]

    然后它将深入到该行中&lt;td&gt; 元素内的&lt;input&gt; 元素。

    【讨论】:

    • project 3hardcoded,如果他们添加 project4project5 甚至将项目 3 名称更改为其他名称会怎样?
    • 如果产品 4 出现在项目 3 之后,则不会发生任何事情。这是在名为 project 2 和 project 3 的行之间搜索一行。如果在 project 2 和 project 3 之间添加了 project 4,它将不再解析为单个元素,而是基于标记当前布局的方式是奇怪和不寻常的行为。如果(在这种情况下)您正在检查使用我提供的 XPath 返回了多少输入字段,您会得到一个快速而清晰的指示,表明这个新标记是奇怪/错误的。
    • 另外值得指出的是,如果项目 4 位于项目 2 和项目 3 之间,如果您使用基本的 .findElement() 调用,您仍然会获得预期的元素,因为它会拾取它找到的第一个节点。如果项目 4 放在项目 2 之前,它将被忽略,因为它不在项目 2 和项目 3 之间。
    • 如果项目 3 的名称被更改为其他名称,您将在项目 2 之后获得所有输入字段,但如果您使用基本的 .findElement() 调用,它将再次选择找到的第一个节点.
    • 虽然所有这一切都没有实际意义,但如果标记发生重大变化,大多数复杂的 XPath 都会中断,这就是为什么人们建议向元素添加 ID 以使其易于查找并避免使用基于 XPath 的需要标记结构。
    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多