用ElementTree在Python中解析XML的节点值

2 投票
1 回答
2672 浏览
提问于 2025-04-17 22:07

我从一个网页上解析出了以下的XML内容:

<!--
Parts from the iGEM Registry of Standard Biological Parts
-->
<rsbpml>
 <part_list>
  <part>
   <part_id>151</part_id>
   <part_name>BBa_B0034</part_name>
   <part_short_name>B0034</part_short_name>
   <part_short_desc>RBS (Elowitz 1999) -- defines RBS efficiency</part_short_desc>
   <part_type>RBS</part_type>
   <release_status>Released HQ 2013</release_status>
   <sample_status>In stock</sample_status>

现在我想提取一些值。

比如,我想从<part_type>中输出值RBS

我尝试了以下方法:

bb_xml_raw = urllib2.urlopen("http://parts.igem.org/cgi/xml/part.cgi?part=BBa_B0034")
self.parse = ET.parse(bb_xml_raw)
self.root = self.parse.getroot()

for part in self.root.findall('part_list'):
   print part.find('part_type').text

但是没有成功,我得到了这个错误:AttributeError: 'NoneType' object has no attribute 'text'

我哪里做错了呢?

1 个回答

2

试着把

for part in self.root.findall('part_list'):

改成

for part in self.root.find('part_list'):

findall 会返回一个包含所有匹配节点的 列表。所以,第一行会返回所有 part_list 节点的列表。你的 <part_list> 节点没有任何带有 part_type 标签的子节点,所以它返回 None,这就是你遇到错误的原因。

如果你只有一个 part_list 节点,那么 find 会返回这个节点本身,你可以用普通的 for part in 语法来遍历它的所有子节点。

如果你有多个 part_list 标签,那你只需要用一个嵌套的 for 循环:

for part_list in self.root.findall('part_list'):
    for part in part_list: 
         etc.

补充:考虑到这其实是个 XY 问题——如果你真正想要的是一个特定的子路径,你可以一次性做到这一点,像这样:

all_parts = self.root.findall('part_list/part')
print all_parts[0].find('part_type').tag

等等。

撰写回答