PyQuery: jQuery do Python

Neste tutorial, você verá PyQuery, uma biblioteca Python que permite fazer consultas jQuery em documentos XML. Sintaticamente, é bastante semelhante ao jQuery e, se você estiver familiarizado com o jQuery, será mais fácil segui-lo.

Introdução ao PyQuery

Para começar com PyQueryinstale o pacote Python usando PIP.

Depois de ter instalado PyQueryimporte-o para o programa Python.

1
from pyquery import PyQuery as pq

Depois de importar a classe PyQuery, você pode usá-la para carregar dados de uma string, um arquivo ou até mesmo uma URL.

Vamos começar com um exemplo básico para ver como funciona. Considere o seguinte HTML que está dentro de um arquivo chamado document.html.

1

2
 class="no-js" lang="">
3
    
4
     charset="utf-8">
5
    </span>A Simple Webpage<span style="color: #bb0066;font-weight: bold">
6
     name="viewport" content="width=device-width, initial-scale=1">
7
    
8
9
    
10
        

Hello world! This is a basic webpage.

11
        

Here is a list of some random words:

12
         class="big-words">
13
            
  • Impedimenta
  • 14
                
  • Decompensation
  • 15
                
  • Tergiversation
  • 16
                
  • Transcendentalism
  • 17
                
  • Polyphiloprogenitive
  • 18
            
    
    19
        
    
    20
    
    

    Podemos passar o arquivo HTML como um argumento para o PyQuery objeto e, em seguida, poderemos aplicar consultas de estilo jQuery a ele.

    1
    webpage = pq(filename = 'document.html')
    

    O valor retornado pela chamada para PyQuery objeto é semelhante ao que você obtém com jQuery() ou $() ao usar a biblioteca jQuery. Assim como o html() método em jQuery, há um html() método em PyQuery onde você poderá obter ou definir o conteúdo HTML do elemento selecionado.

    Atualmente, o objeto da página da Web é representativo de todo o documento, portanto, retorna a marcação da página inteira:

    1
    print(webpage.html())
    
    2
    3
    '''
    
    
    4
    
    
    
    5
    
    
    
    6
    A Simple Webpage
    
    
    7
    
    
    
    8
    
    
    
    9
    
    
    
    10
    
    
    
    11
        

    Hello world! This is a basic webpage.

    12
        

    Here is a list of some random words:

    13
        
    14
            
  • Impedimenta
  • 15
            
  • Decompensation
  • 16
            
  • Tergiversation
  • 17
            
  • Transcendentalism
  • 18
            
  • Polyphiloprogenitive
  • 19
        
    
    
    20
    
    
    
    21
    '''
    

    Digamos que você queira obter a marcação do primeiro p tag em vez de todo o documento. O que você faz? Você simplesmente passa um seletor apropriado para o nosso webpage objeto. Aqui está um exemplo:

    1
    print(webpage("p").html())
    
    2
    3
    '''
    
    
    4
    Hello world! This is a basic webpage.
    
    
    5
    '''
    

    Agora dê uma olhada no código a seguir, onde primeiro definiremos o HTML para nosso seletor usando o html() método e, em seguida, acessá-lo usando o mesmo html() método.

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage("p").html())
    
    6
    '''
    
    
    7
    Hello world! This is a basic webpage.
    
    
    8
    '''
    
    9
    10
    webpage("p").html("Hello world! I have changed this paragraph.")
    
    11
    12
    print(webpage("p").html())
    
    13
    '''
    
    
    14
    Hello world! I have changed this paragraph.
    
    
    15
    '''
    

    Como você pode ver, foi muito fácil para nós manipular o HTML de tags específicas. Vamos ver o que mais podemos mudar.

    Manipulação de atributos usando PyQuery

    PyQuery tenta espelhar a API jQuery o mais próximo possível. Isso significa que você obtém acesso a um método de atributo chamado attr() o que torna possível obter e definir o valor dos atributos para os nós DOM selecionados.

    Nossa marcação original tinha uma lista ordenada de palavras. Vamos ver se conseguimos o valor de class atributo da lista. Também usaremos o attr() para atribuir um ID à nossa lista não ordenada. Isso exigirá que passemos dois argumentos diferentes para o método. Primeiro será a string Eu iria e o segundo será o ID que queremos definir.

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage("ul").attr('class'))
    
    6
    '''
    
    
    7
    big-words
    
    
    8
    '''
    
    9
    10
    webpage("ul").attr("id", "word-list")
    
    11
    12
    webpage("p").attr("class", "greeting hello-message")
    
    13
    14
    print(webpage.html())
    
    15
    '''
    
    
    16
    
    
    
    17
    
    
    
    18
    A Simple Webpage
    
    
    19
    
    
    
    20
    
    
    
    21
    
    
    
    22
    
    
    
    23
        

    Hello world! This is a basic webpage.

    24
        

    Here is a list of some random words:

    25
        
    26
            
  • Impedimenta
  • 27
            
  • Decompensation
  • 28
            
  • Tergiversation
  • 29
            
  • Transcendentalism
  • 30
            
  • Polyphiloprogenitive
  • 31
        
    
    
    32
    
    
    
    33
    '''
    

    Como você pode ver, eu também usei o attr() método para adicionar um conjunto de classes ao nosso p elementos. Assim como sua contraparte jQuery, o attr() O método em PyQuery também define o valor do atributo para todos os elementos correspondentes em vez do primeiro.

    Como podemos aplicar as classes apenas para o primeiro p elemento? Podemos simplesmente usar o eq() para obter o elemento em um índice específico, conforme mostrado abaixo.

    1
    webpage("p").eq(0).attr("class", "greeting hello-message")
    

    Se você está procurando principalmente manipular classes de seus elementos, você também pode considerar usar o addClass() e removeClass() métodos que irão adicionar ou remover uma classe CSS, respectivamente. Você também pode usar os nomes dos métodos add_class() e remove_class() se você estiver mais confortável em trabalhar com a notação de sublinhado.

    Aqui está um exemplo:

    1
    webpage("p").eq(0).attr("class", "greeting hello-message")
    
    2
    # 

    Hello world! This is a basic webpage.

    3
    4
    webpage("p").eq(0).remove_class("greeting")
    
    5
    # 

    Hello world! This is a basic webpage.

    6
    7
    webpage("p").eq(0).add_class("first-message")
    
    8
    #  

    Hello world! This is a basic webpage.

    Você também pode se livrar de quaisquer atributos atribuídos a um elemento usando o remove_attr() método. Tenha em mente que não há add_attr() método como essa funcionalidade é atendida por attr() em si.

    Manipulando CSS Usando PyQuery

    Além dos atributos, o elemento teria algumas propriedades CSS. Para adicionar ou modificar as propriedades CSS, você pode usar o css() método e especifique as propriedades cujo valor você deseja definir.

    Para o nosso exemplo, selecionaremos a tag em negrito e definiremos sua cor para marrom escuro enquanto aumentamos o font-size para 120%. Também tornaremos a cor da nossa lista não ordenada azul. Aqui está o código necessário para fazer isso:

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    webpage("ul").css("color", "#1E88E5")
    
    6
    webpage("b").css({"font-size": "120%", "color": "#6D4C41"})
    
    7
    8
    print(webpage)
    
    9
    '''
    
    
    10
    
    
    
    11
        
    
    
    12
        
    
    
    13
        A Simple Webpage
    
    
    14
        
    
    
    15
        
    
    
    16
    
    
    
    17
        
    
    
    18
            

    Hello world! This is a basic webpage.

    19
            

    Here is a list of some random words:

    20
            
    21
                
  • Impedimenta
  • 22
                
  • Decompensation
  • 23
                
  • Tergiversation
  • 24
                
  • Transcendentalism
  • 25
                
  • Polyphiloprogenitive
  • 26
            
    
    
    27
        
    
    
    28
    
    
    
    29
    '''
    
    30
    31
    with open('updated_markup.html', 'w') as file:
    
    32
        file.write(webpage.outer_html())
    

    Como você pode ver, o css() O método no PyQuery é semelhante ao do jQuery. Depois de atualizar os estilos, salvamos a nova marcação em um arquivo chamado updated_markup.html. Você também pode fazer o mesmo depois de fazer várias alterações na marcação.

    Criando, removendo e anexando elementos

    Você deve se lembrar que nossos exemplos de documentos HTML contêm uma lista de palavras. Podemos expandir a lista de palavras? Claro que nós podemos. Tudo o que você precisa fazer é usar o append() ou prepend() métodos. o append() O método anexará o valor passado ao nó de chamada. Da mesma forma, o prepend() O método precederá o valor passado ao nó de chamada. Aqui está um exemplo:

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage("ul"))
    
    6
    '''
    
    
    7
    8
        
  • Impedimenta
  • 9
        
  • Decompensation
  • 10
        
  • Tergiversation
  • 11
        
  • Transcendentalism
  • 12
        
  • Polyphiloprogenitive
  • 13
    
    
    
    14
    '''
    
    15
    16
    webpage("ul").append("
  • Myrmecophilous
  • "
    )
    17
    webpage("ul").prepend("
  • Anagnorisis
  • "
    )
    18
    19
    print(webpage("ul"))
    
    20
    '''
    
    
    21
    22
        
  • Anagnorisis
  • 23
        
  • Impedimenta
  • 24
        
  • Decompensation
  • 25
        
  • Tergiversation
  • 26
        
  • Transcendentalism
  • 27
        
  • Polyphiloprogenitive
  • 28
        
  • Myrmecophilous
  • 29
    
    
    
    30
    '''
    

    Outra opção que você tem para anexar e preceder elementos é o uso de append_to() e prepend_to() métodos. o append_to() O método anexará seu nó de chamada ao nó passado. Da mesma forma, o prepend_to() O método precederá seu nó de chamada ao nó passado. No entanto, lembre-se de que você não pode simplesmente chamar esses métodos em uma string. Você terá que envolvê-los em um objeto PyQuery para que a chamada funcione conforme mostrado abaixo:

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage("ul"))
    
    6
    '''
    
    
    7
    8
        
  • Impedimenta
  • 9
        
  • Decompensation
  • 10
        
  • Tergiversation
  • 11
        
  • Transcendentalism
  • 12
        
  • Polyphiloprogenitive
  • 13
    
    
    
    14
    '''
    
    15
    16
    pq("
  • Myrmecophilous
  • "
    ).append_to(webpage("ul"))
    17
    pq("
  • Anagnorisis
  • "
    ).prepend_to(webpage("ul"))
    18
    19
    print(webpage("ul"))
    
    20
    '''
    
    
    21
    22
        
  • Anagnorisis
  • 23
        
  • Impedimenta
  • 24
        
  • Decompensation
  • 25
        
  • Tergiversation
  • 26
        
  • Transcendentalism
  • 27
        
  • Polyphiloprogenitive
  • 28
        
  • Myrmecophilous
  • 29
    
    
    
    30
    '''
    

    Como você pode ver, obtemos exatamente a mesma saída. Você também pode remover nós de seu documento simplesmente chamando o remove() método sobre eles.

    Vamos fazer algo interessante agora. Colocaremos a lista de palavras em ordem alfabética primeiro extraindo-as, depois classificando-as e reinserindo-as. Aqui está o código que usamos para fazer isso:

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage("ul"))
    
    6
    '''
    
    
    7
    8
        
  • Impedimenta
  • 9
        
  • Decompensation
  • 10
        
  • Tergiversation
  • 11
        
  • Transcendentalism
  • 12
        
  • Polyphiloprogenitive
  • 13
    
    
    
    14
    '''
    
    15
    16
    words = webpage("ul").children().text().split(' ')
    
    17
    words = sorted(words)
    
    18
    19
    webpage("ul li").remove()
    
    20
    21
    for word in words:
    
    22
        webpage("ul").append("
  • " + word + "
  • "
    )
    23
    24
    print(webpage("ul"))
    
    25
    '''
    
    
    26
    27
        
  • Decompensation
  • 28
        
  • Impedimenta
  • 29
        
  • Polyphiloprogenitive
  • 30
        
  • Tergiversation
  • 31
        
  • Transcendentalism
  • 32
    
    
    
    33
    '''
    

    Dois métodos úteis que usamos no exemplo acima são children() e text(). O que eles fazem? o children() O método retorna todos os elementos que são filhos diretos do nó de chamada. No nosso caso, isso significa todos os elementos da lista. Depois disso, usamos o text() para acessar o valor de texto do nó.

    Os valores de texto extraídos são classificados e agrupados dentro li tags para anexá-los à nossa lista desordenada agora vazia.

    Encontrando elementos usando PyQuery

    Há uma boa chance de você trabalhar com documentos HTML para extrair alguns dados deles. Agora, antes de extrair esses dados de qualquer elemento, você precisará localizar ou localizar o elemento primeiro.

    Você pode simplesmente usar o find() método e passe um seletor para ele para encontrar elementos que correspondam a esse seletor específico. Este método pesquisa todos os descendentes do nó de chamada.

    Você também pode usar o closest() para procurar elementos caso você esteja interessado em pesquisar os ancestrais desse seletor específico.

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage.find("b").text())
    
    6
    '''
    
    
    7
    world
    
    
    8
    '''
    
    9
    10
    print(webpage.find("i").closest("p").html())
    
    11
    '''
    
    
    12
    Here is a list of some random words:
    
    
    13
    '''
    

    Já cobrimos o children() método na seção anterior. Você também pode acessar todos os irmãos de um elemento usando o siblings() método. Outros métodos semelhantes que você pode usar são os next_all() e prev_all() que lhe dará todos os irmãos que vêm a seguir ou os irmãos que vieram antes, respectivamente. Aqui está um exemplo:

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(filename = 'document.html')
    
    4
    5
    print(webpage.find("li").eq(2).siblings())
    
    6
    '''
    
    
    7
  • Decompensation
  • 8
  • Impedimenta
  • 9
  • Transcendentalism
  • 10
  • Polyphiloprogenitive
  • 11
    '''
    
    12
    13
    print(webpage.find("li").eq(2).prev_all())
    
    14
    '''
    
    
    15
  • Impedimenta
  • 16
  • Decompensation
  • 17
    '''
    
    18
    19
    print(webpage.find("li").eq(2).next_all())
    
    20
    '''
    
    
    21
  • Transcendentalism
  • 22
  • Polyphiloprogenitive
  • 23
    '''
    

    Extraindo conteúdo da página da Web

    Você se lembra quando eu disse no início do tutorial que o PyQuery pode aceitar entrada de várias fontes, como uma string, um arquivo ou até mesmo uma URL?

    Nesta seção, vamos deixar o PyQuery obter sua marcação de uma página sobre Python na WikiPedia. A página da Web contém muitas informações sobre o Python. Vamos tentar extrair um pouco para nosso consumo. Vamos ver se conseguimos todos os h2 títulos de nível para manter as coisas simples.

    Acredite ou não, mas você só precisa de 5 linhas de código para obter o texto do título.

    1
    from pyquery import PyQuery as pq
    
    2
    3
    webpage = pq(url='https://en.wikipedia.org/wiki/Python_(programming_language)')
    
    4
    5
    headings = webpage.find("h2 span.mw-headline")
    
    6
    7
    for heading in headings:
    
    8
        print(pq(heading).text())
    
    9
    '''
    
    
    10
    History
    
    
    11
    Design philosophy and features
    
    
    12
    Syntax and semantics
    
    
    13
    Programming examples
    
    
    14
    Libraries
    
    
    15
    Development environments
    
    
    16
    Implementations
    
    
    17
    Development
    
    
    18
    API documentation generators
    
    
    19
    Naming
    
    
    20
    Popularity
    
    
    21
    Uses
    
    
    22
    Languages influenced by Python
    
    
    23
    See also
    
    
    24
    References
    
    
    25
    Further reading
    
    
    26
    External links
    
    
    27
    '''
    

    Você deve ter notado que eu usei o seletor h2 span.mw-manchete ao invés de usar h2. Isso ocorre porque simplesmente usando h2 estava me dando alguns títulos adicionais que não faziam parte do conteúdo principal. Você também terá que fazer uma análise semelhante das páginas da Web antes de determinar o seletor apropriado a ser usado para extrair as informações.

    Já escrevi um tutorial sobre o módulo Requests em Python onde usamos o módulo para baixar imagens. Uma limitação do exemplo que incluí foi que estávamos codificando o caminho da imagem. Vamos usar a biblioteca PyQuery para extrair os caminhos de imagem de uma página da Web e alimentá-los para o módulo de solicitações para download. Eu estarei usando a página WikiPedia sobre Estados Unidos para este exemplo:

    1
    import requests
    
    2
    from pyquery import PyQuery as pq
    
    3
    4
    webpage = pq(url='https://en.wikipedia.org/wiki/United_States')
    
    5
    6
    images = webpage.find("img.thumbimage")
    
    7
    8
    for image in images:
    
    9
        image_url = "https:" + pq(image).attr('src')
    
    10
    11
        image_name = image_url.split('/')[-1]
    
    12
    13
        req = requests.get(image_url)
    
    14
        req.raise_for_status()
    
    15
    16
        with open(image_name, 'wb') as fd:
    
    17
            fd.write(req.content)
    

    Não queremos baixar imagens dos ícones da interface do usuário, etc. É por isso que usei um seletor mais específico para extrair nossas imagens. Eu obtenho o nome do arquivo de imagem pegando a última parte do caminho da imagem depois de dividi-lo ao longo do / personagem. Aqui estão algumas das imagens que consegui extrair:

    Extração de imagem dos Estados UnidosExtração de imagem dos Estados UnidosExtração de imagem dos Estados Unidos

    Embrulhando-o

    Neste tutorial, você viu como começar a usar PyQuery, uma biblioteca Python que permite fazer consultas jQuery em documentos XML. Você viu como manipular os atributos e estilos CSS dos elementos HTML.

    Você aprendeu como criar e anexar elementos a elementos existentes e inserir novos elementos antes e depois dos elementos. O que você viu neste tutorial é apenas a ponta do iceberg, e há muito mais que esta biblioteca tem a oferecer.

    Para obter informações mais detalhadas sobre como usar esta biblioteca, recomendo a leitura da documentação oficial. Deixe-nos saber suas sugestões nos comentários abaixo.

    Deixe uma resposta