Tutorial XPath¶
Neste tutorial, você receberá uma sucinta introdução ao XPath uma linguagem de consulta que pode ser usada para selecionar partes aleatórias de documentos `HTML<https://en.wikipedia.org/wiki/HTML>`_ de forma segmentada. O XPath é um padrão muito difundido e uma consulta ao Google resultará em um grande volume de informações. Este tutorial, entretanto, se concentra no uso de tarefas relacionadas a livros eletrônicos, como encontrar cabeçalhos de capítulos em um documento HTML não estruturado.
Selecionar por nome de etiqueta¶
A forma mais simples de seleção é selecionar etiquetas pelo nome. Por exemplo, suponha que você deseja selecionar todas as tags <h2>
em um documento. A consulta XPath para isso é simplesmente:
//h:h2 (Selects all <h2> tags)
The prefix // means search at any level of the document. Now suppose you
want to search for <span>
tags that are inside <a>
tags. That can be
achieved with:
//h:a/h:span (Selects <span> tags inside <a> tags)
Se você quiser buscar por tags em um determinado nível do documento, mude o prefixo:
/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
children of the <body> tag)
Isto corresponderá apenas com <p>Um livro eletrônico curto para demonstrar o uso da XPath.</p>
na :ref:sample_ebook
mas não em qualquer uma das outras tags <p>
. O prefixo 'h'
nos exemplos acima é necessário para combinar etiquetas XHTML. Isto porque internamente o Calibre representa todo o conteúdo XHTML. As tags XHTML têm um namespace e h:
é o prefixo de namespace para tags HTML.
Agora suponha que você queira selecionar ambas as etiquetas <h1>
e <h2>
. Para fazer isso, é necessário uma construção XPath chamada predicado. Um predicate é simplesmente um teste usado para selecionar tags. Testes podem ser arbitrariamente poderosos e, no decorrer do tutorial, você verá mais exemplos poderosos. Cria-se um predicado ao colocar a expressão teste entre colchetes:
//*[name()='h1' or name()='h2']
Existem vários novos recursos nesta expressão do XPath. A primeira é o uso do caractere universal *
. Significa corresponder a qualquer tag. Agora veja a expressão de teste``name()=”h1” ou name()=”h2”. :term:`name()` é um exemplo de uma *função interna*. Ela simplesmente resulta no nome da tag. Então, usando-a, podemos selecionar etiquetas cujos nomes são `h1` ou `h2`. Observe que a função :term:`name()` ignora namespaces, de modo a que não há necessidade para o prefixo ``h:
. O XPath tem várias funções internas úteis. Mais algumas serão apresentadas neste tutorial.
Selecionar por atributos¶
Para selecionar tags com base em seu conteúdo, é necessário o uso de predicados:
//*[@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")
Aqui, o operador @
refere-se aos atributos da tag. Você pode usar alguma das funções internas do XPath para executar correspondências mais sofisticadas em valores de atributos.
Selecionar por conteúdo da etiqueta¶
Usando XPath, você também pode selecionar tags baseado nos textos que elas contêm. A melhor maneira para fazer isso é usar o poder das expressões regulares através da função interna re:test():
//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
section)
Aqui o operador .
refere-se ao conteúdo da tag, assim como o operador @
refere-se aos seus atributos.
Ebook de amostra¶
<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>
Funções nucleares do XPath¶
- name()¶
O nome da etiqueta atual
- contains()¶
contains(s1, s2)
devolve true se s1 contém s2.- re:test()¶
re:test(src, pattern, flags)
retornaTrue
se a stringsrc
corresponde à expressão regularpattern
Uma flag particularmente útil éi
, que torna a correspondência insensível a maiúsculas e minúsculas. Uma boa introdução sobre a sintaxe para expressões regulares pode ser encontrada em sintaxe regexp