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.

Now suppose you want to select both <h1> and <h2> tags. To do that, we need an XPath construct called predicate. A predicate is simply a test that is used to select tags. Tests can be arbitrarily powerful and as this tutorial progresses, you will see more powerful examples. A predicate is created by enclosing the test expression in square brackets:

//*[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 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) retorna True se a string src corresponde à expressão regular pattern 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