#python #xml #beautifulsoup
#python #xml #beautifulsoup
Вопрос:
У меня есть XML-файл с деревом, примерно таким. Root имеет много A, у каждого A есть много B, у каждого B есть много информации:
<root>
<a>
<b>
<info>
<stuff>
...
</stuff>
</info>
<info>
<stuff>
...
</stuff>
</info>
...
</b>
</a>
...
<a>
<b>
<info>
<stuff>
...
</stuff>
</info>
<info>
</info>
...
</b>
</a>
...
</root>
Я извлекаю данные для ввода в базу данных. Каждая запись в БД создается из разных тегов на разной глубине. У меня есть серия циклов for для перехода в узел с наименьшей глубиной, используя BeautifulSoup для анализа xml. Я опустил вставку ORM и DB из кода, потому что это не то место, где находится узкое место.
for fn in glob.glob('/dir/*.xml'):
soup = BeautifulSoup(fn)
all_a = soup.find_all('a')
for a in all_a:
blah = a.something.string
blah2 = a.somethingelse.string
all_b = a.find_all('b')
for b in all_b:
blah3 = b.somethingagain.string
blah4 = b.again.string
all_info = b.find_all('info')
for info in all_info:
blah5 = info.find('name')
blah6 = info.almostdone.string
#this is what gets inserted into db
return (blah, blah2, blah3, blah4, blah5, blah6)
Я перебираю каталог с тысячами XML-файлов с помощью glob. Этот подход продвигается очень медленно. Каждый оператор return будет новой строкой в моей базе данных.
Я подумал, что, возможно, использование понимания списков может ускорить процесс, но это просто очень неаккуратно с множеством глубин XML-объектов.
Есть ли способ сделать это быстрее? Возможно, лучший подход с использованием BeautifulSoup.
Комментарии:
1. lxml будет намного быстрее, чем BeautifulSoup.
2. Я заметил, что вы возвращаетесь из своего самого внутреннего цикла. Означает ли это, что вам нужен только первый тег «info» в первом теге «b» в первом теге «a»? Если это так, то нет причин для
find_all
—find
было бы достаточно.3. @StevenRumbalski Мне нужно получить информацию из каждого тега A и для каждого дочернего элемента этого тега. Если я не вернусь из самого внутреннего цикла, я не получу правильных результатов. Я не мог заставить его работать с just .find. Я получаю ошибку навигации по строке.