XPath教程

在本教程中,将对`XPath <https://en.wikipedia.org/wiki/XPath>`_进行简要介绍,这是一种查询语言,在cllibre中可用于选择`HTML<https://en.wikipedia.org/wiki/HTML>`_文档的任意部分。 XPath是一种广泛使用的标准,并且对其进行谷歌搜索将产生大量信息。 但是,本教程重点介绍如何将XPath用于与电子书相关的任务,例如在非结构化HTML文档中查找章节标题。

按标记名选取

最简单的选择形式是按名称选择 标记。例如,假设您要选择文档中的所有``<h2>``标签。针对此的XPath查询简单地为:

//h:h2        (Selects all <h2> tags)

前缀`//` 表示“在文档的任何级别搜索”。现在假设您要搜索``<a>``标记内的``<span>`` 标记。这可以通过以下方式实现:

//h:a/h:span    (Selects <span> tags inside <a> tags)

如果要搜索文档中特定级别的 标记,请更改前缀:

/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
             children of the <body> tag)

这将仅与"样本_电子书"中的“<p>A非常简短的电子书来演示XPath。</p>的使用”匹配,而不与其他任何“<p>” 标记匹配。上面示例中的“h:”前缀需要匹配XHTML标签。这是因为在内部,Calibre将所有内容表示为XHTML。在XHTML标签中,有一个*命名空间*,而且“h:”是HTML标签的命名空间前缀。

现在假设您要同时选择“<h1>”和“<h2>” 标记。为此,我们需要一个称为*谓词*的XPath结构。A:“谓词”只是一个用于选择标签的测试。测试可以是任意强大的,随着本教程的进行,您将看到更强大的示例。谓词是通过将测试表达式括在方括号中创建的:

//*[name()='h1' or name()='h2']

此XPath表达式中有几个新功能。第一个是通配符“*”的使用。它的意思是*匹配任何标签*。现在看一下测试表达式“name()='h1'或name()='h2'”。“名称()”是一个*内置函数*的例子。 它只是评估标签的名称。 因此通过使用它,我们可以选择名称为“h1”或“h2”的标签。注意:“名称()”函数忽略命名空间,因此不需要“h:”前缀。XPath有几个有用的内置函数。本教程还将介绍更多内容。

按属性选择

要根据属性选择标签,需要使用谓词:

//*[@style]              (Select all tags that have a style attribute)
//*[@class="chapter"]    (Select all tags that have class="chapter")
//h:h1[@class="bookTitle"] (Select all h1 tags that have class="bookTitle")

这里的“@”操作符指的是标签的属性。 您可以使用某些“XPath内置函数”_对属性值执行更复杂的匹配。

按标签内容选择

使用XPath,您甚至可以根据标签中包含的文本选择标签。 最好的方法是通过内置函数“re:test()”使用*正则表达式*的功能:

//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
                                          section)

这里的``.``运算符指代标签的内容,就像``@``运算符指代标签的属性一样。

电子书样本

<html>
    <head>
        <title>A very short e-book</title>
        <meta name="charset" value="utf-8" />
    </head>
    <body>
        <h1 class="bookTitle">A very short e-book</h1>
        <p style="text-align:right">Written by Kovid Goyal</p>
        <div class="introduction">
            <p>A very short e-book to demonstrate the use of XPath.</p>
        </div>

        <h2 class="chapter">Chapter One</h2>
        <p>This is a truly fascinating chapter.</p>

        <h2 class="chapter">Chapter Two</h2>
        <p>A worthy continuation of a fine tradition.</p>
    </body>
</html>

XPath内置函数

名称()

当前标记的名称。

包含()

如果s1包含s2,contains(s1, s2) 返回 true

re:test()

如果字符串`src`与正则表达式`pattern`匹配,则``re:test(src, pattern, flags)``返回true。一个特别有用的标志是``i``,它使匹配不区分大小写。有关正则表达式语法的入门知识,请参见“正则表达式语法<https://docs.python.org/library/re.html>”_。