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>”_。