Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Dificuldade para ler xml com ElementTree

Boa tarde a todos e todas,

Estou tentando desenvolver um código para monitorar determinadas palavras-chave no Diário Oficial. Estava achando o código muito lento, por isso estou tentando, ao invés de ler direto do html através de um request, buscar os arquivos xml existentes no portal de Dados do Gov Federal.

Estou usando a lib ElementTree

Ocorre que não estou conseguindo acessar as tags, e não consegui entender por que.

O arquivo xml que estou tentando ler é o que segue:

<xml><article id="14955328" name="TERMO DE HOMOLOGACAO TP-018.2019" idOficio="5896241" pubName="DO3" artType="Aviso de Homologação e Adjudicação" pubDate="19/06/2020" artClass="00048:00021:00045:00000:00000:00000:00000:00000:00000:00000:00079:00000" artCategory="Prefeituras/Estado de Rondônia/Prefeitura Municipal de Porto Velho" artSize="12" artNotes="" numberPage="236" pdfPage="http://pesquisa.in.gov.br/imprensa/jsp/visualiza/index.jsp?data=19/06/2020&jornal=530&pagina=236" editionNumber="116" highlightType="" highlightPriority="" highlight="" highlightimage="" highlightimagename="" idMateria="12715683">
  <body>
    <Identifica><![CDATA[ AVISO DE ADJUDICAÇÃO E HOMOLOGAÇÃO]]></Identifica>
    <Data><![CDATA[ Porto Velho-RO, 18 de junho 2020]]></Data>
    <Ementa />
    <Titulo />
    <SubTitulo />
    <Texto><![CDATA[<p class="identifica">AVISO DE ADJUDICAÇÃO E HOMOLOGAÇÃO</p><p class="identifica">TOMADA DE PRECOS Nº 18/2019</p><p>O Superintendente Municipal de Licitacoes SML/PVH, no uso das atribuicoes legais que lhe sao conferidas pela Lei Complementar n. 654, de 06.03.2017, publicada no DOM n. 5.405, de 06.03.2017, em atendimento ao que preceitua o disposto no Inciso VI do art. 43 da Lei n. 8666/93;</p><p>Considerando a licitacao na modalidade TOMADA DE PRECOS N. 018/2019/CPL-OBRAS/SML/PVH. PROCESSO N. 08.0327/2019. TIPO MENOR PRECO GLOBAL. OBJETO: CONTRATACAO DE EMPRESA ESPECIALIZADA PARA PRESTACAO DE SERVICOS REFORMA DA UNIDADE DE SAUDE DA FAMILIA (USF) ERNANDES INDIO, em conformidade com o Projeto Basico, composto de Planilha Orcamentaria e Cronograma Fisico-Financeiro, partes integrantes deste Edital, para atender as necessidades da Secretaria Municipal de Saude-SEMUSA.</p><p>Considerando o Parecer Juridico n. 220/SPACC/PGM/2020, fls. 1330-1334, cujo entendimento foi que o procedimento licitatorio acima descrito atendeu as disposicoes da Lei n. 8.666/93, em razao pela qual a Administracao Municipal:, resolve:</p><p>ADJUDICAR E HOMOLOGAR, a licitacao em favor da empresa GARRA COMERCIO E CONSTRUCOES LTDA, CNPJ N. 34.726.745/0001-54 no VALOR TOTAL DE R$ 194.681,72 (cento e noventa e quatro mil seiscentos e oitenta e um reais e setenta centavos).</p><p class="data">Porto Velho-RO, 18 de junho 2020</p><p class="assina">GUILHERME MARCEL GAIOTTO JAQUINI</p>]]></Texto>
  </body>
  <Midias />
</article></xml>

Meu código é o que segue:

import xml.etree.ElementTree as ET

tree = ET.parse(arquivo.xml')
root = tree.getroot()

tree.find('Identifica').text

Ele retorna

AttributeError: 'NoneType' object has no attribute 'text'

Ele não encontra as tags que estão dentro de body

Se eu chamo a função para retornar toda a árvore:

for child in root:
    print(child.tag, child.attrib)

Ele retorna somente os attr que estão dentro de article:

article {'id': '14955328', 'name': 'TERMO DE HOMOLOGACAO TP-018.2019', 'idOficio': '5896241', 'pubName': 'DO3', 'artType': 'Aviso de Homologação e Adjudicação', 'pubDate': '19/06/2020', 'artClass': '00048:00021:00045:00000:00000:00000:00000:00000:00000:00000:00079:00000', 'artCategory': 'Prefeituras/Estado de Rondônia/Prefeitura Municipal de Porto Velho', 'artSize': '12', 'artNotes': '', 'numberPage': '236', 'pdfPage': 'http://pesquisa.in.gov.br/imprensa/jsp/visualiza/index.jsp?data=19/06/2020&jornal=530&pagina=236', 'editionNumber': '116', 'highlightType': '', 'highlightPriority': '', 'highlight': '', 'highlightimage': '', 'highlightimagename': '', 'idMateria': '12715683'}

Tenho a impressão que estou esquecendo de uma coisa muito simples, mas não consigo entender o que é.

Alguém poderia me ajudar?

Um abraço a todos e todas!

2 respostas
solução!

Oi Marcelo, como vai?

Peço perdão pela demora em obter um retorno.

Antes de propor uma solução, vamos observar como está organizada a árvore de elementos do seu arquivo xml.

  • Temos uma tag xml
  • Dentro da tag xml temos a tag article
  • Dentro tag article temos a tag body
  • Dentro da tag body temos várias tags, como por exemplo: Identifica, Data, Ementa, Título...
  • Também temos dentro da tag article a tag mídias

Fiz uma representação em imagem, veja:

image

Tendo como base essa árvore de elementos, para acessar a tag identifica, temos que percorrer a árvore de elementos até chegar onde queremos.

E para fazer isso, podemos ir adentrando tag a tag: primeiro encontramos a tag article, que podemos dizer que representa uma espécie de elemento pai das outras tags. E após isso, vamos para a tag body. Veja como fica em código:

import xml.etree.ElementTree as ET

tree = ET.parse('arquivo.xml')
root = tree.getroot()

tag_article = root.find("article")
tag_body = tag_article.find("body")

Agora, já podemos encontrar a tag identifica, pois ela está dentro da tag body:

tag_identifica = tag_body.find('Identifica').text

Resultado: AVISO DE ADJUDICAÇÃO E HOMOLOGAÇÃO

Código completo:

import xml.etree.ElementTree as ET

tree = ET.parse('arquivo.xml')
root = tree.getroot()

tag_article = root.find("article")
tag_body = tag_article.find("body")
tag_identifica = tag_body.find('Identifica').text
print(tag_identifica)

A partir disso você conseguirá acessar as outras tags do seu documento, tendo sempre em vista a ideia de percorrer a árvore de elementos.

Qualquer dúvida estou por aqui.

Abraços e bons estudos!

Obrigado Nadia, sua explicação foi muito útil.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software