2015-04-23 85 views
1

好吧,我有這個HTML文件,其中包含許多div標籤和表標籤。 div標籤包含與其他div標籤部分相關的id,但在每個div標籤部分之後是包含我需要的數據的表格部分。我希望能夠獲取這個HTML文件並創建數組,列表,字典等...某種結構,以便我可以輕鬆搜索相關信息並從中提取我需要的信息。如何使用python從非結構化的HTML中創建結構化陣列

HTML文件中whats的示例。

<DIV class="info">  <A name="bc968f9fa2db71455f50e0c13ce50e871fS7f0e" 
id="bc968f9fa2db71455f50e0c13ce50e871fS7f0e"> 
     <B>WORKSPACE_WEBAPP</B>&nbsp;(WORKSPACE_WEBAPP)<BR/>  <B>Object ID: 
</B>&nbsp;&nbsp;bc968f9fa2db71455f50e0c13ce50e871fS7f0e<BR/>  <B>Last 
Modified Date : </B>&nbsp;&nbsp;26-Sep-13 10:41:13<BR/> 
     <B>Properties:</B><BR/>  </DIV> 

    <TABLE class="properties">  <TR class="header"><TH>Property 
Name</TH><TH>Property Value</TH></TR> 
        <TR><TD>serverName</TD><TD>FoundationServices0</TD></TR> 
        <TR><TD>context</TD><TD>workspace</TD></TR> 
        <TR><TD>isCompact</TD><TD>false</TD></TR> 
        <TR><TD>AppServer</TD><TD>WebLogic 10</TD></TR> 
        <TR><TD>port</TD><TD>28080</TD></TR> 
        <TR><TD>maintVersion</TD><TD>11.1.2.2.0.66</TD></TR> 
        <TR><TD>version</TD><TD>11.1.2.0</TD></TR> 
        <TR><TD>SSL_Port</TD><TD>28443</TD></TR> 
        <TR><TD>instance_home</TD><TD>/essdev1/app/oracle/Middleware/user_projects/epmsystem1</TD></TR> 
        <TR><TD>configureBPMUIStaticContent</TD><TD>true</TD></TR> 
        <TR><TD>validationContext</TD><TD>workspace/status</TD></TR>   </TABLE> 

所以我希望能夠爲這些div部分創建一個數組,並且還包含該表中的區域以及該數組中的屬性。我無法將自己的頭圍繞在最好的方式去做。我知道答案可能包含使用BeautifulSoup解析標籤。由於沒有其他方式將表格部分與div部分關聯起來,我相信我必須一次加載一行文件並以此方式處理文件,除非有更簡單的方法?任何想法都會非常有幫助。

+1

你看了一下[在Python中解析HTML](http://stackoverflow.com/questions/11709079/parsing-html-python)? – Huey

+0

是的,我讀過這個和許多其他的python HTML解析指南。我想我最大的問題是如何控制閱讀div標籤部分,然後閱讀它的關聯表部分,然後移動到下一個div標籤部分和表部分,直到整個文件被解析。 – todd1215

+1

您可以在閱讀後刪除div標籤,然後查找下一個標籤,直到找不到更多標籤爲止? – Huey

回答

1

首先,我要重申你的問題。該示例顯示了一個div標籤,其中包含一個A標籤。 A標籤有一個您想用作查找下表的關鍵的ID。 div標記後面跟着table。表中的每一行都包含一個與前一個A中標識的對象關聯的名稱 - 值對。

您有一個頁面充滿了多個div標籤,每個標籤都在我上一段中描述。

你想產生一些數據結構來方便地訪問表數據並將其與命名對象相關聯嗎?

我有這個權利嗎?

正如你所預言的那樣,答案是使用BeautifulSoup。我們將創建一個字典,以id屬性爲關鍵字。字典中的每個值本身都是一個字典,由表中的「屬性名稱」鍵入。

from bs4 import BeautifulSoup 
from pprint import pprint 

result = {} 
soup = BeautifulSoup(page) 
divs = soup.find_all("div", {"class":"info"}) 
for div in divs: 
    name = div.find("a")["id"] 
    table = div.find_next("table", {"class":"properties"}) 
    rows = table.find_all("tr", {"class":None}) 
    rowd = {} 
    for row in rows: 
     cells = row.find_all("td") 
     rowd[cells[0].text] = cells[1].text 
    result[name] = rowd 
pprint (result) 

或者,如果你喜歡字典內涵(像我一樣):

result = { 
    div.find("a")["id"]: { 
     cells[0].text : cells[1].text 
     for row in table.find_all("tr", {"class":None}) 
     for cells in [row.find_all("td")] 
    } 
    for div in soup.find_all("div", {"class":"info"}) 
    for table in [div.find_next("table", {"class":"properties"})] 
} 

pprint(result) 

當你的榜樣數據指出,這一收益率:

{'bc968f9fa2db71455f50e0c13ce50e871fS7f0e': {u'AppServer': u'WebLogic 10', 
              u'SSL_Port': u'28443', 
              u'configureBPMUIStaticContent': u'true', 
              u'context': u'workspace', 
              u'instance_home': u'/essdev1/app/oracle/Middleware/user_projects/epmsystem1', 
              u'isCompact': u'false', 
              u'maintVersion': u'11.1.2.2.0.66', 
              u'port': u'28080', 
              u'serverName': u'FoundationServices0', 
              u'validationContext': u'workspace/status', 
              u'version': u'11.1.2.0'}} 

要使用的數據結構,只需按照字典。例如:

print result["bc968f9fa2db71455f50e0c13ce50e871fS7f0e"]["serverName"] 
+0

很優雅。這正是我想要做的。你對我的解釋重新陳述是現貨。 – todd1215

+0

這行看起來不正確。我得到一個錯誤。 name = div.find(「a」)[「id」] – todd1215

2

使用BeautifulSoup

,基本解決方案是使用加入美化分裂。基本思路是轉換它在文本單獨感興趣的部分

from bs4 import BeautifulSoup 
soup = BeautifulSoup(''.join(text)) 
for i in soup.prettify().split('<!--Persontype-->')[1].split('<strong>'): 
print '<strong>' + ''.join(i) 



text= ''' 
<div class="clearfix"> 
    <!--# of ppl associated with place--> 
     This is some kind of buzzword:<br /> 
    <br /> 
    <!--Persontype--> 
     <strong>Hey</strong> All   <br /> 
Something text here   <br /> 
About Something 
     <br /> 
Mobile Version  <br /> 
     <br /> 
     <strong>MObile</strong> Nokia   <br /> 
Try to implement here   <br /> 
Simple 
      <br /> 
hey Thanks  <br /> 


O/P is :