为啥我的 XPath 选择文本不起作用?

Posted

技术标签:

【中文标题】为啥我的 XPath 选择文本不起作用?【英文标题】:Why is my XPath to select text not working?为什么我的 XPath 选择文本不起作用? 【发布时间】:2021-05-14 15:01:45 【问题描述】:

如果 XPath 中没有节点,如何访问文本? 文本在引号中,并在另一个节点内的单独行中

我无法在 XPath 中选择正确的元素

 <span>
    <a href="www.imagine_a_link_here.org">
      "
                This is the text I need to access
             "
    </a>
 </span>

我通常会通过写作来做到这一点

import requests
from lxml import html,etree
from lxml.html import document_fromstring

page = requests.get('https://www.the_link_im_trying_to_webscrape.org')
tree = html.fromstring(page.content)
the_text_i_need_to_access_xpath = '/span/a/text()'
the_text_i_need_to_access = tree.xpath(the_text_i_need_to_access_xpath)

不幸的是,这只会返回一个空列表。有谁知道我必须如何修改 XPath 才能获得我正在寻找的字符串?

【问题讨论】:

对于您发布的示例 HTML,XPath 是正确的,应该选择锚点内的文本。您确定 HTML 不包含其他包装元素,例如 &lt;html&gt;&lt;body&gt;?您可以尝试对后代轴使用更通用的 XPath:即//span/a/text() @MadsHansen:如果你对文本进行硬编码,它不会给出结果 【参考方案1】:

如果 XPath 中没有节点,如何访问文本?

XML 或 HTML 文档中的文本将与一个节点相关联。这不是这里的问题。 " " 分隔符只是用来显示周围的空白。

您的 XPath 应该选择 a 元素中的文本。以下是一些可能不会发生的原因:

    作为@MadsHansen mentioned in comments,实际HTML 的根元素可能不是span,如图所示。见:

    Difference between "//" and "/" in XPath?

    在执行 XPath 时可能不会加载文本,因为文档尚未完全加载,或者因为 javascript 稍后会动态更改 DOM。见:

    Selenium wait until document is ready Selenium WebDriver: Wait for complex page with JavaScript to load

    fromstring() 可以使用比预期更多的魔法:

fromstring(string): 返回 document_fromstringfragment_fromstring,基于 字符串看起来像一个完整的文档,还是只是一个片段。

鉴于此,以下是对您的代码的更新,它将按预期选择目标文本:

import requests
from lxml import html
from lxml.html import document_fromstring

htmlstr = """
<span>
   <a href="www.imagine_a_link_here.org">
     "
               This is the text I need to access
            "
   </a>
</span>
"""

tree = html.fromstring(htmlstr)
print(html.tostring(tree))
the_text_i_need_to_access_xpath = '//span/a/text()'
the_text_i_need_to_access = tree.xpath(the_text_i_need_to_access_xpath)
print(the_text_i_need_to_access)

或者,如果您不需要/想要 HTML 惊喜,这也会选择文本:

import lxml.etree as ET

xmlstr = """
 <span>
    <a href="www.imagine_a_link_here.org">
      "
                This is the text I need to access
             "
    </a>
 </span>
"""

root = ET.fromstring(xmlstr)
print(root.xpath('/span/a/text()'))

致谢:感谢@ThomasWeller 指出额外的并发症并帮助解决这些问题。

【讨论】:

如果对文本进行硬编码,即使 span 是根元素,它也不会给出结果。 / 也不是 /span 选择的东西。 @ThomasWeller:嗨,Thomas,告诉我你对文本进行硬编码是什么意思——我没有关注。您似乎在说,如果 XPath 不正确地引用了目标文本,它将不匹配。同意,但 OP 仅将其引用为 text(),因此不确定我是否遵循您的观点。 大声笑,是的,这有点乱。如果没有返回 OP 文档的服务器,将很难重现。 chat.***.com/rooms/228547/lxml-htmlelement 无需从服务器获取字符串。只需硬编码

以上是关于为啥我的 XPath 选择文本不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 IBAction 更改标签文本不起作用?

为啥这个 MotionEvent 模拟不起作用?

为啥这个 SwiftUI Picker 代码不起作用?

为啥我的直系后代选择器不起作用?

为啥我的选择排序代码不起作用?

为啥我的 jQuery :not() 选择器在 CSS 中不起作用?