使用BeautifulSoup提取和分组元素/标签

时间:2012-07-24 10:28:41

标签: python beautifulsoup

我有一个包含以下类型和数据结构的文件:

<data>
    <from>A</from>
    <to>B</to>
    <data>
        <name>EXAMPLE ONE</name>
        <info>
            <some_data>1</some_data>
            <more_data>2</more_data>
        </info>
        <random>
            <some_tag>
            </foobar>
            <foo>
                <bar />
           </foo>
        </random>
    </data>
    <data>
        <name>EXAMPLE TWO</name>
        <info>
            <some_data>3</some_data>
            <more_data>4</more_data>
        </info>
        <random>
            <some_tag>
            </foobar>
            <foo>
                <bar />
           </foo>
        </random>
   </data>
</data>
<data>
    <from>C</from>
    <to>D</to>
    <data>
        <name>EXAMPLE</name>
        <info>
            <some_data>1</some_data>
            <more_data>2</more_data>
        </info>
        <random>
            <some_tag>
            </foobar>
            <foo>
                <bar />
           </foo>
        </random>
    </data>
 </data>

数据在文件中的这个确切结构中继续存在,但最内部的<data>...</data>标记除外,这些标记可以重复n次,数据结构始终以<data>标记开头,然后继续使用<from>...</from><to>...</to>代码。

我想要做的是使用<data><to>作为数据块的描述,提取最外<from>个标签之间的所有数据。我当然也希望将最内层的<data>标签彼此分开并以某种方式保存这些数据,以便明确最外层的数据与父数据相关。

我不知道如何保存数据,所以感谢任何例子!

我正在使用Python模块BeautifulSoup对此进行测试,并在此处搜索并阅读了大量示例,但未找到任何可以指向正确方向的内容。

谢谢!

1 个答案:

答案 0 :(得分:0)

事实上,您将标记名<data>加倍作为记录的容器以及内部元素会产生问题。 BeautifulSoup对此类问题感到宽容,如果您无法返回并更改XML结构,则可能需要使用此方法。

将数据分配给变量。当然,这可以从文本文件中读取:

data = '''<data>
    <from>A</from>
    <to>B</to>
    <data>
        <name>EXAMPLE ONE</name>
        <info>
            <some_data>1</some_data>
            <more_data>2</more_data>
        </info>
        <random>
            <some_tag>
            </foobar>
            <foo>
                <bar />
           </foo>
        </random>
    </data>
    <data>
        <name>EXAMPLE TWO</name>
        <info>
            <some_data>3</some_data>
            <more_data>4</more_data>
        </info>
        <random>
            <some_tag>
            </foobar>
            <foo>
                <bar />
           </foo>
        </random>
   </data>
</data>
<data>
    <from>C</from>
    <to>D</to>
    <data>
        <name>EXAMPLE</name>
        <info>
            <some_data>1</some_data>
            <more_data>2</more_data>
        </info>
        <random>
            <some_tag>
            </foobar>
            <foo>
                <bar />
           </foo>
        </random>
    </data>
 </data>'''

处理数据:

from BeautifulSoup import BeautifulSoup
from pprint import pprint

store = {}
key = ()

soup = BeautifulSoup(data)

recs = soup.findAll('data')

for rec in recs:
    if rec.find('from'):
        key = (rec.find('from').text, 
               rec.find('to').text)
    else:
        item = {}
        item['name'] = rec.find('name').text
        item['some_data'] = rec.find('info').find('some_data').text
        item['more_data'] = rec.find('info').find('more_data').text
        if store.has_key(key):
            store[key].append(item)
        else:
            store[key] = [ item ]

pprint(store)

这个虚拟数据的结果:

{(u'A', u'B'): [{'more_data': u'2',
                 'name': u'EXAMPLE ONE',
                 'some_data': u'1'},
                {'more_data': u'4',
                 'name': u'EXAMPLE TWO',
                 'some_data': u'3'}],
 (u'C', u'D'): [{'more_data': u'2', 'name': u'EXAMPLE', 'some_data': u'1'}]}