2012-07-24 2 views
0

J'ai un fichier qui contient le type suivant et de la structure des données:éléments Extraire et groupe/tags avec BeautifulSoup

<data> 
    <from>A</from> 
    <to>B</to> 
    <data> 
     <name>EXAMPLE ONE</name> 
     <info> 
      <some_data>1</some_data> 
      <more_data>2</more_data> 
     </info> 
     <random> 
      <some_tag> 
      </foobar> 
      <foo> 
       <bar /> 
      </foo> 
     </random> 
    </data> 
    <data> 
     <name>EXAMPLE TWO</name> 
     <info> 
      <some_data>3</some_data> 
      <more_data>4</more_data> 
     </info> 
     <random> 
      <some_tag> 
      </foobar> 
      <foo> 
       <bar /> 
      </foo> 
     </random> 
    </data> 
</data> 
<data> 
    <from>C</from> 
    <to>D</to> 
    <data> 
     <name>EXAMPLE</name> 
     <info> 
      <some_data>1</some_data> 
      <more_data>2</more_data> 
     </info> 
     <random> 
      <some_tag> 
      </foobar> 
      <foo> 
       <bar /> 
      </foo> 
     </random> 
    </data> 
</data> 

Les données se poursuit dans cette structure exacte dans le fichier à l'exception des plus intérieure <data>...</data> Les balises pouvant être répétées n fois, la structure de données commence toujours par une balise <data>, puis se poursuit par les balises <from>...</from> et <to>...</to>. Ce que je veux faire est d'extraire toutes les données entre les plus <data> étiquettes extérieures avec les <to> et <from> comme description des blocs de données. Bien sûr, je souhaite également séparer les balises les plus internes les unes des autres et enregistrer ces données de manière à ce qu'il soit clair que les données les plus externes sont liées aux données parentes.

Je n'ai pas une idée précise de la façon dont je veux enregistrer les données afin que tous les exemples sont appréciés!

Je suis en train de tester ceci avec le module Python BeautifulSoup et j'ai cherché et lu beaucoup d'exemples ici mais je n'ai rien trouvé qui puisse me diriger dans la bonne direction.

Merci!

Répondre

0

Le fait que vous doublez le nom de l'étiquette <data> en tant que conteneur de vos enregistrements ainsi que d'un élément à l'intérieur crée des problèmes. BeautifulSoup est pardonner de tels problèmes et voici un moyen que vous pouvez utiliser au cas où vous ne pouvez pas revenir en arrière et modifier la structure XML.

Affectez les données à une variable. Cela peut être lu dans le fichier texte, bien sûr:

data = '''<data> 
    <from>A</from> 
    <to>B</to> 
    <data> 
     <name>EXAMPLE ONE</name> 
     <info> 
      <some_data>1</some_data> 
      <more_data>2</more_data> 
     </info> 
     <random> 
      <some_tag> 
      </foobar> 
      <foo> 
       <bar /> 
      </foo> 
     </random> 
    </data> 
    <data> 
     <name>EXAMPLE TWO</name> 
     <info> 
      <some_data>3</some_data> 
      <more_data>4</more_data> 
     </info> 
     <random> 
      <some_tag> 
      </foobar> 
      <foo> 
       <bar /> 
      </foo> 
     </random> 
    </data> 
</data> 
<data> 
    <from>C</from> 
    <to>D</to> 
    <data> 
     <name>EXAMPLE</name> 
     <info> 
      <some_data>1</some_data> 
      <more_data>2</more_data> 
     </info> 
     <random> 
      <some_tag> 
      </foobar> 
      <foo> 
       <bar /> 
      </foo> 
     </random> 
    </data> 
</data>''' 

traiter les données:

from BeautifulSoup import BeautifulSoup 
from pprint import pprint 

store = {} 
key =() 

soup = BeautifulSoup(data) 

recs = soup.findAll('data') 

for rec in recs: 
    if rec.find('from'): 
     key = (rec.find('from').text, 
       rec.find('to').text) 
    else: 
     item = {} 
     item['name'] = rec.find('name').text 
     item['some_data'] = rec.find('info').find('some_data').text 
     item['more_data'] = rec.find('info').find('more_data').text 
     if store.has_key(key): 
      store[key].append(item) 
     else: 
      store[key] = [ item ] 

pprint(store) 

Et le résultat avec ces données factices:

{(u'A', u'B'): [{'more_data': u'2', 
       'name': u'EXAMPLE ONE', 
       'some_data': u'1'}, 
       {'more_data': u'4', 
       'name': u'EXAMPLE TWO', 
       'some_data': u'3'}], 
(u'C', u'D'): [{'more_data': u'2', 'name': u'EXAMPLE', 'some_data': u'1'}]} 
+0

Great! C'est presque ça, je voudrais aussi extraire tous les blocs de données internes possibles dans le parent. J'ai mis à jour le code d'exemple pour le rendre plus clair! – Mike

+0

@Mike: J'ai mis à jour le code pour prendre en compte vos données d'entrée éditées. S'il vous plaît noter qu'il serait idéal de revenir à l'origine et de créer un arbre XML bien formé. J'ai ajouté un moyen de stocker chaque bloc dans un dictionnaire que vous pouvez ensuite examiner d'une manière qui devrait être assez simple maintenant. – gauden

+0

Fantastique, résolu! Merci! – Mike

Questions connexes