【问题标题】:Python selenium - Select children elementsPython selenium - 选择子元素
【发布时间】:2019-07-09 10:55:35
【问题描述】:

我使用 selenium 来获取 url 的元素。在此我需要链接,但需要一个特定的 div 标签。 我按类名选择 div,然后按 xpath 选择链接。但是,它会返回所有链接,包括那些不在 div 中的链接。我做错了什么?

browser.get(url)

elems = []
try:
    obj_div = browser.find_element_by_class_name("jss504")
    try:
        elems = obj_div.find_elements_by_xpath("//a[@href]")
    except NoSuchElementException:
        pass
except NoSuchElementException:
    pass

print(len(elems))

结果,我得到了 41。但是,如果我对浏览器对象做同样的事情,我也有同样的数量。这41个链接不属于obj_div对象,属于整个浏览器。

【问题讨论】:

    标签: python selenium


    【解决方案1】:

    Xpath 可以是bidirectional,表示它会向前和向后查找元素。

    作为您的 xPath,它不仅会在之后请求上下文,它还能够在 DOM 中向前和向后查看。

    来自文档:

    前进步骤
    此步骤选择出现在上下文节点(或上下文节点本身)之后的后代或节点。

    反向步骤
    此步骤选择出现在上下文节点(或上下文节点本身)之前的祖先或节点。


    您可以尝试用 css_selector 替换 xpath:

        elems = obj_div.find_elements_by_css_selector("a[href]")
    

    并不是说这段代码永远不会引发NoSuchElementException 异常。如果找不到您要查找的内容,它将返回一个空列表。

    如果您的第一个类元素是唯一的,您还可以通过一个查询来简化您的代码:

    obj_div = browser.find_elements_by_css_selector(".jss504 a[href]")
    

    【讨论】:

    • @JeffC 点取并更改为“可以”,只有在我知道的情况下,如果您使用绝对路径,它不会是。使用嵌套将使它们始终是双向的。不确定是否反对,但如果有的话,您可以提供更好的选择。对我来说,无论如何都应该避免使用 xPath。
    • 在这种情况下,您必须提供一些关于“双向”含义的文档。据我所知和听说过,所有定位器都从 DOM 的顶部开始向下移动。在某些情况下,您可以向上搜索祖先或向下搜索后代。有关 OP 所见内容的解释,请参阅我的答案,但我确实建议您针对 OP 要求的解决方案。
    • OP 不是从 DOM 开始的,因此我的回答不够广泛。我将添加请求的链接
    • 您能否指出链接页面中关于 XPath 是双向的部分?我搜索了这个词,但它没有出现在页面上。
    • @JeffC 它可能没有在文档中明确说明,而是隐含地说明。我在我的答案中复制了隐含部分。对于明确的,您也可以从该链接获取信息:pragmatictestlabs.com/2018/05/16/…
    【解决方案2】:

    您正在寻找起始元素下的元素。为此,您必须使用自身轴,.,例如.//a[@href]。这表示从当前元素开始并在下面搜索。因为您没有包含它,所以 XPath 搜索整个页面,即使您的代码似乎表明(在您理解原因之前它以这种方式工作有点令人困惑)它应该从 obj_div 元素开始并只搜索后代。

    补充说明:

    您的嵌套try 不是必需的,因为您使用的是.find_elements_*。它总是返回一个集合,因此您必须查看集合是否为空才能知道是否找到了元素。

    修改后的完整代码如下所示

    browser.get(url)
    
    elems = []
    try:
        obj_div = browser.find_element_by_class_name("jss504")
        elems = obj_div.find_elements_by_xpath(".//a[@href]")
    except NoSuchElementException:
        pass
    
    print(len(elems))
    

    说了这么多,我建议你按照 Nic Laforge 的建议使用 CSS 选择器。我只是想解释您问题的答案并提供一些额外的反馈,以防将来对您或其他人有用。

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-28
      • 2020-10-02
      相关资源
      最近更新 更多