2011-07-29 20 views
4

Pythonスクリプトを使用してHTMLテーブルからデータを抽出し、別のファイルに変数として保存します(同じスクリプトで後で使用することができます)。また、スクリプトでテーブルの最初の行(Component、Status、Time/Error)を無視したい。私は外部ライブラリを使用したくないです。Pythonを使用してHTMLテーブルからデータを抽出する

新しいファイルに出力がそうのようにする必要があります:

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

そしてHERESにスクリプトへの入力:

<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> 

私はbashでそれを実行しようとしましたが、私はする必要があるため* _TIME変数と最大時間を比較すると、浮動小数点数なので失敗します。

+3

"もう一つ、私が外部ライブラリを使用したくありません"。エピック・フェイル。あなたは本当に美しいスープを使用する必要があります。このようなことのためには最高です。 –

+0

他の方法がない場合、私は美味しいスープを使用します:) – Marko

+0

"from HTML"は美味しいスープと同義です。 – SingleNegationElimination

答えて

4

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'))) 

利回り

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は外部ライブラリです、いいえ? @Marko Pythonのバージョンによっては、代わりに[ElementTree](http://docs.python.org/library/xml.etree.elementtree.html)を使うか、 - urgh .... - [xml.dom.minidom ](http://docs.python.org/library/xml.dom.minidom.html) – brandizzi

+1

@brandizzi:コメントで、MarkoはBeautifulSoupを使用する意思を表明しました。私はこれを使って、外部ライブラリを使用する意思を示しました。 – unutbu

+0

ここで私の最終的なコードunutbuのおかげで、私はまだ外部ライブラリを使用しています: 'if(not os.path.exists(Filename)): download = urllib2.urlopen(MonitorURL) data = download。key、status、time for zip(* [iter(tree.xpath( '// td/text()'])には、 )]])* 3): fileObj.writelines( '' '{k} _STATUS = "{s}" \ n' ''形式(k =キー、s =ステータス) fileObj.writelines( '' ' (k = key、t = time.rstrip( 's'))) fileObj.close() '{t} – Marko

2

さて、あなたのHTML文書は、本当にあなたは正規表現を使用することができます(それはかなり稀であるので、私は私の頭を傷つける可能)など、安定した構造がある場合:あなたがしたい

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

グループ以下の正規表現は、値を結果に表示されます。次に、オブジェクトのsub()メソッドを使用します。

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

結果:テキストは(例えばcontentなど)の変数である場合は、単にそれをこのように実行

>>> 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> 

確かに、文字列内のゴミの多くは、まだですが、それ考えを与える:)

もしあなたのHTML文書が安定していないなら、不安定に構造化されたHTMLファイルを処理する仕事のおかげであるかもしれないので、XMLパーサーか、手で。 lxmlを使用して

+0

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

+0

私が与えたHTMLは安定しています:)スクリプトが必要ですこの古いHTMLをNagiosに食べさせます。 – Marko

+0

@TokenMacGuy私は一般的に同意しますが、私は[この回答](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1733489#1733489 )この場合: – brandizzi

関連する問題