如何使用 python 从非结构化 HTML 创建结构化数组

How to create structured array out of unstructured HTML using python

好的,所以我有这个 HTML 文件,其中包含许多 div 标签和 table 标签的数据。 div 标签包含与其他 div 标签部分相关的 ID,但在每个 div 标签部分之后是包含我需要的数据的 table 部分。我希望能够使用这个 HTML 文件并创建数组、列表、字典等...某种结构,以便我可以轻松搜索相关信息并从中提取我需要的内容。

HTML 文件中的示例。

<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 部分创建一个数组,并且还包含 table 中的区域以及该数组中的属性。我只是想不出最好的方法是什么。我知道答案可能包含使用 BeautifulSoup 来解析标签。由于没有其他方法将 table 部分与 div 部分相关联,我相信我必须一次加载一行文件并以这种方式处理它,除非有更简单的方法?任何想法都会很有帮助。

使用BeautifulSoup

基本解决方案是使用 joinprettifysplit。基本思想是 convert 它在 textseparate interest 的部分

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 :

首先,我需要重申你的问题。该示例显示了一个 div 标签,其中包含一个 A 标签。 A 标签有一个 ID,您希望将其用作查找以下 table 的键。 div 标记后跟 table。 table 的每一行都包含一个与前面 A.

中标识的对象关联的名称-值对

您的页面充满了多个 div 标签,每个标签都在我的上一段中进行了描述。

您想生成一些数据结构来方便地访问 table 数据并将其与命名对象相关联吗?

我说得对吗?

正如您所预言的那样,答案是使用 BeautifulSoup。我们将创建一个字典,以 id 属性为键。字典中的每个值本身就是一个字典,由 table.

中的 "Property Name" 键控
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"]