使用BeautifulSoup从多个XML列表中提取文本数据

时间:2017-08-26 08:02:31

标签: python xml beautifulsoup

我正在解析大小的xml文件(150mb)。因为beautifulsoup是众所周知的,所以我把它拿起来了。 xml格式如下:

<tag>
  <tag1>
   <texttag>Some text</texttag>
  </tag1>
 </tag>

<tag>
  <tag1>
   <texttag>Some other text</texttag>
  </tag1>
 </tag>

我有两千个这样的元素。 由于根标签不在这里所以我根据每个元素的主标签将其拆分,因为它相同并转换成列表(再次是两千个)。这是怎么回事:

import itertools as it
from bs4 import BeautifulSoup
filename = 'some.xml'
btree = BeautifulSoup(open(filename), "lxml-xml")

with open(filename,'r') as f:
 for key,group in it.groupby(f,lambda line: line.startswith('tag')):
    if not key:
        group = list(group)
        #print(group)
        texttags= btree.find_all("texttag")
        for text in texttags:
          print (text.string)

在运行而不是迭代到下一个元素并显示其文本等时,它会显示第一个元素的文本2000次,而不是显示所有带有提到标记的元素的文本。有人可以帮我纠正吗?

PS:我无法修改XML的结构。另外,我是一个仍然涉足python及其库的业余爱好者。

2 个答案:

答案 0 :(得分:2)

我担心你不能将lxml-xml用于此文档,因为它只会获取第一个标记 但是,您可以使用lxmlhtml.parser

btree = BeautifulSoup(open(filename), "html.parser")
texttags= btree.find_all("texttag")
for text in texttags:
    print(text.string)

或者,如果您必须使用lxml-xml,则可以使用html.parser收集标记,然后构建新的BeautifulSoup对象并将标记附加到根标记。

soup = BeautifulSoup(open(filename), "html.parser")
btree = BeautifulSoup("<root></root>", "lxml-xml")

for tag in soup.find_all('tag'):
    btree.root.append(tag)

答案 1 :(得分:0)

有两个错误。首先,您需要打开(文件名)而不是打开(“文件名”)。在您的代码中,您基本上操作两个文件而不是一个:'some.xml'和'filename'。

其次,在使用BeautifulSoup解析文件后,无需使用open(...)打开文件。整个代码应该是:

<action application="set" data="sip_rh_X-Reason=Destination Number Not in Footprint"/>
<action application="set" data="sip_bye_h_X-Accounting=Some Accounting Data"/>