Дублирование одной строки при создании кадра данных pandas из вложенного файла xml - PullRequest
0 голосов
/ 28 марта 2020

У меня есть сильно вложенный XML файл, который я пытаюсь преобразовать в CSV - где я хотел бы извлечь все возможные элементы из файла XML.

При попытке использовать создать pandas фрейм данных из вложенного xml файла в качестве основы для моего решения, моя проблема заключается в том, что мой фрейм данных будет содержать только ту же строку (содержащую последний URL (из многих) файла xml) который повторяется снова и снова.

My XML (обрезается, чтобы показать один расширенный элемент):

<?xml version='1.0' encoding='UTF-8'?>
<REPORT>
    <ELEMENT1>
    ...
    </ELEMENT1>
    <ELEMENT2>
    ...
    </ELEMENT2>
    <ELEMENT3>
    ...
    </ELEMENT3>
    <ELEMENT4>
    ...
    </ELEMENT4>
    <RESULTS>
        <APPLICATION>
            <ID>123456</ID>
            <NAME>https://www.example.com/subsite/</NAME>
            <LIST>
                <LEVEL>
                    <UNIQUE_ID>123abc</UNIQUE_ID>
                    <ID>6666666</ID>
                    <URL>https://www.example.com/subsite/</URL>
                    <STATUS>ACTIVE</STATUS>
                    <TIME>14 Mar 2020 04:47AM GMT+0200</TIME>
                    <TIMES_DETECTED>9</TIMES_DETECTED>
                    <PAYLOADS>
                        <PAYLOAD>
                            <NUM>1</NUM>
                            <REQUEST>
                                <METHOD>POST</METHOD>
                                <URL>https://www.example.com/subsite/</URL>
                                <HEADERS>
                                    <HEADER>
                                        <key>Host</key>
                                        <value>randomdata</value>
                                    </HEADER>
                                    <HEADER>
                                        <key>Content-Type</key>
                                        <value>randomdata</value>
                                    </HEADER>
                                </HEADERS>
                            </REQUEST>
                            <RESPONSE>
                                <CONTENTS base64="true">randomdata</CONTENTS>
                            </RESPONSE>
                        </PAYLOAD>
                    </PAYLOADS>
                    <IGNORED>false</IGNORED>
                </LEVEL>
            </LIST>
            <BURP_ISSUES_LIST/>
            <BUGCROWD_SUBMISSIONS_LIST/>
            <SENSITIVE_CONTENT_LIST/>
            <INFORMATION_GATHERED_LIST>
                <INFORMATION_GATHERED>
                    <UNIQUE_ID>835ogk</UNIQUE_ID>
                    <ID>9459856</ID>
                    <TIME>14 Mar 2020 04:47AM GMT+0200</TIME>
                    <DATA base64="true">randomdata</DATA>
                </INFORMATION_GATHERED>
                <INFORMATION_GATHERED>
                    <UNIQUE_ID>475hgv</UNIQUE_ID>
                    <ID>4569852</ID>
                    <TIME>14 Mar 2020 04:47AM GMT+0200</TIME>
                    <DATA base64="true">randomdata</DATA>
                </INFORMATION_GATHERED>
                <INFORMATION_GATHERED>
                    <UNIQUE_ID>849ikg</UNIQUE_ID>
                    <ID>326614</ID>
                    <TIME>14 Mar 2020 04:47AM GMT+0200</TIME>
                    <DATA base64="true">randomdata</DATA>
                </INFORMATION_GATHERED>
            </INFORMATION_GATHERED_LIST>
        </APPLICATION>
        <APPLICATION2>
        </APPLICATION2>
    </RESULTS>
    <ELEMENT5>
    ...
    </ELEMENT5>
</REPORT>

Мой код ниже:

from lxml import etree as et
import pandas as pd

file_input = 'D:\file.xml'
file_output = 'D:\file.csv'
trees = et.parse(file_input)

d = []
for reportdata in trees.xpath('//REPORT/RESULTS/APPLICATION/LIST/LEVEL/URL'):   
    inner = {}
    for elem in reportdata.xpath('//*'):       
        try:
            if len(elem.text.strip()) > 0:     
                inner[elem.tag] = elem.text
        except:
            pass
    d.append(inner)

df = pd.DataFrame(d)

df.to_csv(file_output, sep="|", index = None)

Результатом этого кода является то, что датафрейм содержит 2000 одинаковых строк.

Я попытался заменить следующую строку:

for reportdata in trees.xpath('//REPORT/RESULTS/APPLICATION/LIST/LEVEL/URL'): 

на:

for reportdata in trees.xpath('//REPORT'): 

однако Я получил только одну строку в моем фрейме данных, и я также заменил ее на:

for reportdata in trees.xpath('//*'): 

, однако здесь скрипт выполняется около 5 часов и снова возвращает около 100 000 строк точно такой же строки.

В идеале я хотел бы вытащить все возможные элементы данных из файла XML. Пожалуйста, можно мне посоветовать, как я могу исправить свой код. Спасибо

...