2011-07-29 3 views
4

Je veux extraire des données de la table HTML en utilisant le script Python et l'enregistrer en tant que variables (que je pourrai utiliser ultérieurement dans le même script après les avoir chargées) dans un fichier séparé. Aussi, je veux que le script ignore la première ligne de la table (Composant, Statut, Temps/Erreur). Je préférerais ne pas utiliser de bibliothèques externes.Extraire des données de la table HTML en utilisant Python

La sortie dans un nouveau fichier doit être comme ceci:

SAVE_DOCUMENT_STATUS = "OK" 
SAVE_DOCUMENT_TIME = "0.408" 
GET_DOCUMENT_STATUS = "OK" 
GET_DOCUMENT_TIME = "0.361" 
... 

Et voici l'entrée au script:

<table border=1> 
<tr> 
<td><b>Component</b></td> 
<td><b>Status</b></td> 
<td><b>Time/Error</b></td> 
</tr> 
<tr><td>SAVE_DOCUMENT</td><td>OK</td><td>0.408 s</td></tr> 
<tr><td>GET_DOCUMENT</td><td>OK</td><td>0.361 s</td></tr> 
<tr><td>DVK_SEND</td><td>OK</td><td>0.002 s</td></tr> 
<tr><td>DVK_RECEIVE</td><td>OK</td><td>0.002 s</td></tr> 
<tr><td>GET_USER_INFO</td><td>OK</td><td>0.135 s</td></tr> 
<tr><td>NOTIFICATIONS</td><td>OK</td><td>0.002 s</td></tr> 
<tr><td>ERROR_LOG</td><td>OK</td><td>0.001 s</td></tr> 
<tr><td>SUMMARY_STATUS</td><td>OK</td><td>0.913 s</td></tr> 
</table> 

J'ai essayé de le faire en bash, mais étant donné que je dois comparez les variables * _TIME au temps maximum, puis elle échoue, car ce sont des nombres flottants.

+3

"Encore une chose, je ne veux pas utiliser des bibliothèques externes". Epic Fail Vous devez vraiment utiliser Beautiful Soup. C'est le meilleur pour ce genre de chose. –

+0

Ok, s'il n'y a pas d'autre moyen de sortir, je vais utiliser Beautiful Soup alors :) – Marko

+0

"de HTML" est synonyme de Beautiful Soup. – SingleNegationElimination

Répondre

4

En utilisant lxml:

import lxml.html as lh 

content='''\ 
<table border=1> 
<tr> 
<td><b>Component</b></td> 
<td><b>Status</b></td> 
<td><b>Time/Error</b></td> 
</tr> 
<tr><td>SAVE_DOCUMENT</td><td>OK</td><td>0.408 s</td></tr> 
<tr><td>GET_DOCUMENT</td><td>OK</td><td>0.361 s</td></tr> 
<tr><td>DVK_SEND</td><td>OK</td><td>0.002 s</td></tr> 
<tr><td>DVK_RECEIVE</td><td>OK</td><td>0.002 s</td></tr> 
<tr><td>GET_USER_INFO</td><td>OK</td><td>0.135 s</td></tr> 
<tr><td>NOTIFICATIONS</td><td>OK</td><td>0.002 s</td></tr> 
<tr><td>ERROR_LOG</td><td>OK</td><td>0.001 s</td></tr> 
<tr><td>SUMMARY_STATUS</td><td>OK</td><td>0.913 s</td></tr> 
</table> 
''' 
tree=lh.fromstring(content) 
for key, status, t in zip(*[iter(tree.xpath('//td/text()'))]*3): 
    print('''{k}_STATUS = "{s}" 
{k}_TIME = "{t}"'''.format(k=key,s=status,t=t.rstrip(' s'))) 

cède

SAVE_DOCUMENT_STATUS = "OK" 
SAVE_DOCUMENT_TIME = "0.408" 
GET_DOCUMENT_STATUS = "OK" 
GET_DOCUMENT_TIME = "0.361" 
DVK_SEND_STATUS = "OK" 
DVK_SEND_TIME = "0.002" 
DVK_RECEIVE_STATUS = "OK" 
DVK_RECEIVE_TIME = "0.002" 
GET_USER_INFO_STATUS = "OK" 
GET_USER_INFO_TIME = "0.135" 
NOTIFICATIONS_STATUS = "OK" 
NOTIFICATIONS_TIME = "0.002" 
ERROR_LOG_STATUS = "OK" 
ERROR_LOG_TIME = "0.001" 
SUMMARY_STATUS_STATUS = "OK" 
SUMMARY_STATUS_TIME = "0.913" 
+0

lxml est une bibliothèque externe, non? Selon la version @Marko Python, il peut utiliser [ElementTree] (http://docs.python.org/library/xml.etree.elementtree.html) à la place, ou - urgh .... - [xml.dom.minidom ] (http://docs.python.org/library/xml.dom.minidom.html) – brandizzi

+1

@brandizzi: Dans les commentaires Marko a exprimé une volonté d'utiliser BeautifulSoup. J'ai pris cela pour signifier une volonté d'utiliser n'importe quelle bibliothèque externe. – unutbu

+0

Voici mon code final grâce à unutbu, j'ai toujours utilisé la bibliothèque externe: 'if (pas os.path.exists (Filename)): download = urllib2.urlopen (MonitorURL) data = télécharger.read() fileObj = open (Nom de fichier, "w") tree = lh.fromstring (data) pour clé, statut, heure dans zip (* [iter (tree.xpath ('// td/text()'))] * 3): fileObj.writelines ('' '{k} _STATUS = "{s}" \ n' '. Format (k = clé, s = statut)) fileObj.writelines (' '' {k} _TIME = "{t}" \ n ''.. format (k = clé, t = time.rstrip ('s'))) fichierObj.close() ' – Marko

2

Eh bien, si votre document HTML a vraiment une structure stable (ce qui me fait me gratter la tête, car il est assez rare), vous pouvez utiliser les expressions rationnelles:

>>> import re 
>>> r = re.compile('<tr><td>(.*)</td><td>(.*)</td><td>(.*) s</td></tr>') 

Le regex ci-dessous regroupe les valeurs que vous voulez montrer dans le résultat. Ensuite, vous utilisez la méthode sub() de l'objet. Si le texte est dans une variable (par exemple content) il suffit d'exécuter cette façon:

r.sub(r'\1_STATUS = "\2"\n\1_TIME = \3', content) 

Le résultat:

>>> print r.sub(r'\1_STATUS = "\2"\n\1_TIME = \3', content) 
<table border=1> 
<tr> 
<td><b>Component</b></td> 
<td><b>Status</b></td> 
<td><b>Time/Error</b></td> 
</tr> 
SAVE_DOCUMENT_STATUS = "OK" 
SAVE_DOCUMENT_TIME = 0.408 
GET_DOCUMENT_STATUS = "OK" 
GET_DOCUMENT_TIME = 0.361 
DVK_SEND_STATUS = "OK" 
DVK_SEND_TIME = 0.002 
DVK_RECEIVE_STATUS = "OK" 
DVK_RECEIVE_TIME = 0.002 
GET_USER_INFO_STATUS = "OK" 
GET_USER_INFO_TIME = 0.135 
NOTIFICATIONS_STATUS = "OK" 
NOTIFICATIONS_TIME = 0.002 
ERROR_LOG_STATUS = "OK" 
ERROR_LOG_TIME = 0.001 
SUMMARY_STATUS_STATUS = "OK" 
SUMMARY_STATUS_TIME = 0.913 
</table> 

Bien sûr, il y a beaucoup de déchets dans la chaîne encore, mais donne l'idée :)

Si vos documents HTML ne sont pas si stables, cependant, vous devriez vraiment envisager un analyseur XML ou, mieux encore, BeautifulSoup, car ce serait un sacré boulot de traiter un fichier HTML instable par la main.

+0

-1 http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – SingleNegationElimination

+0

Le HTML que j'ai donné est stable :) Le script est nécessaire pour rendant ce vieux HTML comestible à Nagios. – Marko

+0

@TokenMacGuy bien que je suis d'accord en général, je suis avec [cette réponse] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1733489#1733489) dans ce cas :) – brandizzi

Questions connexes