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 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