Quel est le moyen le plus efficace d’extraire des informations d’un grand nombre de fichiers xml en python?

StackOverflow https://stackoverflow.com/questions/344559

Question

J'ai un répertoire plein (~ 10 3 , 10 4 ) de fichiers XML à partir duquel je dois extraire le contenu de plusieurs champs. J'ai testé différents analyseurs syntaxiques xml, et comme je n'ai pas besoin de valider le contenu (cher), je pensais simplement utiliser xml.parsers.expat (le plus rapide) pour parcourir les fichiers, un par un, pour en extraire le contenu. Les données.

  1. Existe-t-il un moyen plus efficace? (la correspondance de texte simple ne fonctionne pas)
  2. Dois-je émettre un nouveau ParserCreate () pour chaque nouveau fichier (ou chaîne) ou puis-je réutiliser le même pour chaque fichier?
  3. Des mises en garde?

Merci!

Était-ce utile?

La solution

Le moyen le plus rapide serait de faire correspondre les chaînes (avec, par exemple, des expressions régulières) au lieu d'analyser XML. Selon vos XML, cela pourrait fonctionner.

Mais la chose la plus importante est la suivante: au lieu de réfléchir à plusieurs options, il suffit de les implémenter et de les synchroniser sur un petit ensemble. Cela prendra à peu près le même temps et vous donnera des chiffres réels qui vous font avancer.

EDIT:

  • Les fichiers se trouvent-ils sur un lecteur local ou sur un lecteur réseau? Les E / S réseau vont vous tuer ici.
  • Le problème parallélise trivialement: vous pouvez répartir le travail entre plusieurs ordinateurs (ou plusieurs processus sur un ordinateur multicœur).

Autres conseils

En règle générale, je suggérerais d'utiliser iterparse d'ElementTree. ou, pour plus de rapidité, son pendant de lxml . Essayez également d’utiliser le Traitement (intégré à la version 2.6) pour la parallélisation.

L'important dans iterparse est que vous obteniez les structures d'élément (sous-) au fur et à mesure de leur analyse.

import xml.etree.cElementTree as ET
xml_it = ET.iterparse("some.xml")
event, elem = xml_it.next()

événement sera toujours la chaîne "fin" dans ce cas, mais vous pouvez également initialiser l'analyseur pour vous informer également des nouveaux éléments au fur et à mesure de leur analyse. Vous n'avez aucune garantie que tous les éléments enfants auront été analysés à ce moment-là, mais les attributs sont là, si cela ne vous intéresse que.

Vous pouvez également arrêter de lire les éléments de l'itérateur plus tôt, c'est-à-dire avant que le document entier n'ait été traité.

Si les fichiers sont volumineux (le sont-ils?), il existe un idiome courant pour maintenir l'utilisation de la mémoire constante, comme dans un analyseur de flux.

Si vous savez que les fichiers XML sont générés à l'aide du même algorithme, il serait peut-être plus efficace de ne procéder à aucune analyse XML. Par exemple. Si vous savez que les données se trouvent aux lignes 3, 4 et 5, vous pouvez lire le fichier ligne par ligne, puis utiliser des expressions régulières.

Bien sûr, cette approche échouera si les fichiers ne sont pas générés par une machine, s'ils proviennent de différents générateurs ou si le générateur change avec le temps. Cependant, je suis optimiste sur le fait qu’il serait plus efficace.

Que vous recycliez ou non les objets de l'analyseur est en grande partie hors de propos. De nombreux autres objets seront créés. Ainsi, un seul objet analyseur ne compte pas beaucoup.

Une chose que vous n'avez pas indiquée est de savoir si vous lisez le code XML dans un DOM quelconque. Je suppose que vous ne l'êtes probablement pas, mais vous ne l'êtes pas, ne le faites pas. Utilisez plutôt xml.sax. Utiliser SAX au lieu de DOM vous procurera une amélioration significative de vos performances.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top