2011-07-29 4 views
4

Python 스크립트를 사용하여 HTML 테이블에서 데이터를 추출하여 변수로 저장하고 싶습니다 (변수가있는 경우 동일한 스크립트에서 나중에 사용할 수 있음). 또한 스크립트가 테이블의 첫 번째 행 (구성 요소, 상태, 시간/오류)을 무시하도록합니다. 나는 외부 라이브러리를 사용하지 않는 것을 선호한다. 를 heresPython을 사용하여 HTML 테이블에서 데이터 추출

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

그리고 스크립트에 입력 :

새로운 파일로 출력과 같이해야

<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

다른 방법이 없다면 Beautiful Soup을 사용할 것입니다. – Marko

+0

"from HTML"은 Beautiful Soup와 동의어입니다. – 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.(iter (tree.xpath ('// td/text()') 키, 상태, 시간에 대해 fileObj = open (파일 이름, "w") 트리 = lh.fromstring (데이터) ))]] * 3) : fileObj.writelines ('' '{{}} \ n' ''형식 (k = key, s = status) fileObj.writelines ('' ' (k = key, t = time.rstrip ('s'))) fileObj.close()'{k} _TIME = "{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 파서 또는 더 나은 아직 BeautifulSoup를 고려해야합니다. 손으로. 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

관련 문제