2016-06-09 34 views
0

我想从多个结构相似的XML标签中提取信息。我循环每个孩子将其附加到字典。有没有办法避免每个标签的for循环(如我的MWE中的sn和count)。有效的方式来循环标签与美丽的汤

from bs4 import BeautifulSoup as bs 
import pandas as pd 

xml = """ 
    <info> 
    <tag> 
     <sn>9-542</sn> 
     <count>14</count> 
    </tag> 
    <tag> 
     <sn>3-425</sn> 
     <count>16</count> 
    </tag> 
    </info> 
    """ 

bs_obj = bs(xml, "lxml") 
info = bs_obj.find_all('tag') 


d = {} 

# I want to avoid these multiple for-loops 
d['sn'] = [i.sn.text for i in info] 
d['count'] = [i.count.text for i in info] 

pd.DataFrame(d) 
+2

是否需要xml BeautifulSoup?您正在使用xml。你可以使用xpath和xml。 BeautifulSoup本身不支持XPath表达式。 lxml有一个BeautifulSoup兼容模式,它会尝试解析破碎的HTML。你为什么使用BeautifulSoup?它将会像tree.xpath(“/ tag/sn”)一样 - 找到标签“tag”的所有子标签,标签的名称是“sn” – user565447

回答

1

请考虑以下方法。
有2只为这个解决方案的缘故循环被动态的(唯一需要改变,如果你想另一个标签是needed_tags列表):

from collections import defaultdict 

d = defaultdict(list) 

needed_tags = ['sn', 'count'] 
for i in info: 
    for tag in needed_tags: 
     d[tag].append(getattr(i, tag).text) 

print(d) 
>> defaultdict(<class 'list'>, {'count': ['14', '16'], 'sn': ['9-542', '3-425']}) 

对于您的具体例子,这可以简化为:

from collections import defaultdict 

d = defaultdict(list) 

for i in info: 
    d['sn'].append(i.sn.text) 
    d['count'].append(i.count.text) 

print(d) 
>> defaultdict(<class 'list'>, {'count': ['14', '16'], 'sn': ['9-542', '3-425']})