【问题标题】:Why XPath is selecting node with svg child when using not(svg)为什么 XPath 在使用 not(svg) 时选择带有 svg 子节点的节点
【发布时间】:2020-09-19 20:19:08
【问题描述】:

我是 XPath 的新手,尝试了一些不同的东西,但有一个查询对我来说真的没有意义。

我想选择所有不包含svg 子节点的span 节点,如下所示:

对我来说,添加[not(svg)] 应该会阻止查询选择它正在选择的确切元素,这是一些奇怪的行为还是我很愚蠢?我使用的 XPath 查询是:

//div/a/span[not(svg)]

谢谢!

编辑:

svg 节点的完整 XPath 是:

/html/body/div[1]/div[2]/div/div[1]/div[2]/div[1]/div[1]/a/span[1]/svg

还有一个sn-p的代码:

<!DOCTYPE html>
<!-- saved from url=(0019)https://medium.com/ -->
<html xmlns:cc="http://creativecommons.org/ns#" class="">

<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# medium-com: http://ogp.me/ns/fb/medium-com#"></head>

<body itemscope="" class="browser-chrome os-windows is-withMagicUnderlines v-glyph v-glyph--m2 is-js is-resizing" data-action-scope="_actionscope_0" data-gr-c-s-loaded="true">
  <div class="site-main surface-container" id="container">
    <div class="butterBar butterBar--error" data-action-scope="_actionscope_1"></div>
    <div class="surface" id="_obv.shell._surface_1600536527994" style="display: block; visibility: visible;">
      <div class="screenContent surface-content" data-used="true" data-action-scope="_actionscope_2">
        <div class="metabar u-clearfix js-metabar is-withBottomSection metabar--affixed is-transitioning is-maximized">
          <div class="branch-journeys-top"></div>
          <div class="js-metabarMiddle metabar-inner u-marginAuto u-maxWidth1032 u-flexCenter u-justifyContentSpaceBetween u-height65 u-xs-height56 u-paddingHorizontal20">
            <div class="metabar-block u-flex1 u-flexCenter">
              <div class="u-xs-show js-metabarLogoLeft"><a href="https://medium.com/" data-log-event="home" class="siteNav-logo u-fillTransparentBlackDarker u-flex0 u-flexCenter u-paddingTop0"><span class="svgIcon svgIcon--logoMonogram svgIcon--45px"><svg class="svgIcon-use" width="45" height="45"><path d="M5 40V5h35v35H5zm8.56-12.627c0 .555-.027.687-.318 1.03l-2.457 2.985v.396h6.974v-.396l-2.456-2.985c-.291-.343-.344-.502-.344-1.03V18.42l6.127 13.364h.714l5.256-13.364v10.644c0 .29 0 .342-.185.528l-1.848 1.796v.396h9.19v-.396l-1.822-1.796c-.184-.186-.21-.238-.21-.528V15.937c0-.291.026-.344.21-.528l1.823-1.797v-.396h-6.471l-4.622 11.542-5.203-11.542h-6.79v.396l2.14 2.64c.239.292.291.37.291.768v10.353z"></path></svg></span><span class="u-textScreenReader">Homepage</span></a></div>
              <div class="u-xs-hide js-metabarLogoLeft"><a href="https://medium.com/" data-log-event="home" class="siteNav-logo u-fillTransparentBlackDarker u-flex0"><span class="svgIcon svgIcon--logoWordmark svgIcon--112x22px u-xs-hide u-flex"><svg class="svgIcon-use" height="22" width="112" viewBox="0 0 111.5 22"><path d="3-.7V7.3c0-.5 0-1.2.1-1.8L11.4 22h-.1L4.5 6.8c-.1-.4-.2-.4-.3-.6v10c-.1.7 0 1.3.3 1.9l2.7 3.6v.1H0v-.1L2.7 18c.3-.6.4-1.3.3-1.9v-11c0-.5-.1-1.1-.5-1.5L.7 1.1V1h7l5.8 12.9L18.6 1h6.8v.1l-1.9 2.2c-.2.2-.3.5-.3.7v15.2c0 .2.1.5.3.6zm7.6-5.9c0 3.8 1.9 5.3 4.2 5.3 1.9.1 3.6-1 4.4-2.7h.1c-.8 3.7-3.1 5.5-6.5 5.5-3.7 0-7.2-2.2-7.2-7.4 0-5.5 3.5-7.6 7.3-7.6 3.1 0 6.4 1.5 6.4 6.2v.8h-8.7zm0-.8h4.3v-.8c0-3.9-.8-4.9-2-4.9-1.4.1-2.3 1.6-2.3 5.7z"></path></svg></span><span class="svgIcon svgIcon--logoWordmark svgIcon--122x45px u-xs-show u-flex"><svg class="svgIcon-use" width="122" height="45"><path d="0 00-.487-1.602l-2.089-2.708v-.065h7.494l6.277 13.686 5.527-13.686h7.335v.065l-2.061 2.296a.806.806 0 00-.319.786v16.15a.75.75 0 00.319.759zm8.215-6.332v.065c0 4.01 2.07 5.62 4.497 5.62a5.105 5.105 0 004.777-2.894h.066c-.844 3.963-3.298 5.836-6.97 5.836-3.962 0-7.7-2.389-7.7-7.925 0-5.817 3.747-8.14 7.887-8.14 3.335 0 6.886 1.573 6.886 6.632v.806h-9.443zm0-.806h4.618v-.815c0-4.122-.852-5.218-2.136-5.218-1.555 0-2.5 1.64-2.5 6.033h.018z"></path></svg></span><span class="u-textScreenReader">Homepage</span></a></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

另外,上面代码sn-p的顶部div元素的XPath是:

/html/body/div[1]/div[2]/div/div[1]/div[2]/div[1]/div[1]

【问题讨论】:

  • 是的,我认为您的期望是正确的。请以其他人可以运行的形式提供您的代码(即完整的示例,而不是片段,而不是图像),以便人们可以尝试复制它。
  • @MichaelKay 我在帖子中添加了更多代码,我希望这会更好,谢谢。
  • 您还没有创建一个minimal reproducible example 来说明问题。 SVG 元素通常位于不同的命名空间中。你没有显示你在哪里添加了[not(svg)]。等等。阅读该链接并提供一个完整的、最小的、reproducible 示例,无需我们猜测您做了什么即可复制。谢谢。
  • 如果您在浏览器中运行并且这是一个 HTML DOM,那么它可能是一个命名空间问题。见stackoverflow.com/questions/23319537/…
  • @kjhughes 完整的 HTML 文档大约有 25K 行,我试图只删掉一部分,它涵盖了我发现这个问题的一小部分范围,是不是更好?虽然我认为你和迈克尔是正确的,因为它位于不同的命名空间中。

标签: html xml xpath web-scraping


【解决方案1】:

对于任何偶然发现此问题的人,该问题是由于 SVG 和 HTML 命名空间差异造成的,这些差异在 MichealKay 的 cmets 中包含的答案中有所说明。

要选择 SVG 元素,我必须写:

//span/*[name()="svg"]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    • 2017-07-12
    • 2014-10-10
    • 1970-01-01
    相关资源
    最近更新 更多