【问题标题】:Why this Xpath not working?为什么这个 Xpath 不工作?
【发布时间】:2018-03-13 08:15:49
【问题描述】:

例如这个 HTML

<div>
    <span></span> I want to find this <b>this works ok</b>.
</div>

我想找到一个包含I want to find this 的 DIV,然后抓取该 DIV 中的整个文本,包括子元素

我的 XPATH,//*[contains(text(), 'I want to find this')] 根本不起作用。

如果我这样做 //*[contains(text(), 'this works')] 它可以工作,但我想根据 I want to find this 文本找到任何 DIV

但是,如果我从该 HTML 中删除 &lt;span&gt;&lt;/span&gt;,它会起作用,这是为什么呢?

【问题讨论】:

  • 将标题更新为 “为什么这个 Xpath 不起作用?” 根本没有提供任何信息。另请注意,//*[contains(text(), 'this works')] 实际上不起作用。只能返回b,不能返回div
  • @Umair,如果您想使用 css 选择器找到解决方案,那么这项工作有一个解决方案。
  • @Shahin 我实际上使用包含选择器

标签: parsing xpath web-scraping html-parsing


【解决方案1】:

你可以试试Replace text() with string():

//div[contains(string(), " I want to find this")]
Or, you can check that span's following text sibling contains the text:

//div[contains(span/following-sibling::text(), " I want to find this")] 

【讨论】:

    【解决方案2】:

    text() 只获取第一个内部元素之前的文本。您可以将其替换为. 以使用当前节点进行搜索。

    //div[contains(., 'I want to find this')]
    

    这将搜索当前节点内所有文本节点的字符串连接。

    如果你使用 lxml,你可以使用node.itertext() 来获取所有的文本来迭代所有的内部文本:

    from lxml import etree
    
    html = """
    <div>
        <span></span> I want to find this <b>this works ok</b>.
    </div>
    """
    
    root = etree.fromstring(html, etree.HTMLParser())
    for div in root.xpath('//div[contains(., "I want to find this")]'):
        print(''.join([x for x in div.itertext()]))
    # =>    I want to find this this works ok.
    

    【讨论】:

    • 警告:text() 仅获取第一个文本节点并不完全正确。相反,在 XPath 1.0 下, contains() 函数会忽略所提供参数中除第一个节点之外的所有节点。在 XPath 2.0 下,如果第一个参数是包含多个项目的列表,则 contains() 函数将引发错误。但该解决方案适用于所有 XPath 版本。
    • 并注意一般原则:95% 的人在写text() 时,应该改写.
    【解决方案3】:

    尝试使用 //*[text()=' I want to find this '] ,这将选择 div 标签,然后对于文本,您可以使用 getText() 方法获取文本

    【讨论】:

    • 这会检查确切的文本,我想检查一个 DIV 是否包含该文本,因为在我的情况下,也可以有一个像 I want to find this bla bla 这样的长字符串,在这种情况下,你的答案将不起作用
    猜你喜欢
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多