这是我的芝加哥XML文件: 路线名称=“红色”>
<route name = "red">
<train>
<rn>830</rn>
<destSt>30089</destSt>
<destNm>95th/Dan Ryan</destNm>
<trDr>5</trDr>
<nextStaId>41000</nextStaId>
<nextStpId>30194</nextStpId>
<nextStaNm>Cermak-Chinatown</nextStaNm>
<prdt>20180117 22:41:16</prdt>
<arrT>20180117 22:42:16</arrT>
<isApp>1</isApp>
<isDly>0</isDly>
<flags/>
<lat>41.85532</lat>
<lon>-87.63133</lon>
<heading>176</heading>
<route name="blue">
<train>
<rn>134</rn>
<destSt>30077</destSt>
<destNm>Forest Park</destNm>
<trDr>5</trDr>
<nextStaId>40570</nextStaId>
<nextStpId>30112</nextStpId>
<nextStaNm>California</nextStaNm>
<prdt>20180117 22:40:47</prdt>
<arrT>20180117 22:42:47</arrT>
<isApp>0</isApp>
<isDly>0</isDly>
<flags/>
<lat>41.92528</lat>
<lon>-87.70238</lon>
<heading>122</heading>
</train>
我能够使用.find函数来提取列车的第一个列车编号和更多信息,但现在我想为'route = blue提取一列火车的标签(以及该特定火车的日期) '段落......我怎么能这样做?我遇到麻烦,因为每个标签都是一样的。
我提取第一个标签的当前代码如下:
train = XML.find('rn')
print(train) #just a gist of the code
任何解决方案?我正在使用BeautifulSoup4
答案 0 :(得分:0)
我不得不稍微更改你的xml因为它没有很好地形成,但假设xml看起来像这样:
<data>
<route name="red">
<train>
<rn>830</rn>
<destSt>30089</destSt>
<destNm>95th/Dan Ryan</destNm>
<trDr>5</trDr>
<nextStaId>41000</nextStaId>
<nextStpId>30194</nextStpId>
<nextStaNm>Cermak-Chinatown</nextStaNm>
<prdt>20180117 22:41:16</prdt>
<arrT>20180117 22:42:16</arrT>
<isApp>1</isApp>
<isDly>0</isDly>
<flags/>
<lat>41.85532</lat>
<lon>-87.63133</lon>
<heading>176</heading>
</train>
</route>
<route name="blue">
<train>
<rn>134</rn>
<destSt>30077</destSt>
<destNm>Forest Park</destNm>
<trDr>5</trDr>
<nextStaId>40570</nextStaId>
<nextStpId>30112</nextStpId>
<nextStaNm>California</nextStaNm>
<prdt>20180117 22:40:47</prdt>
<arrT>20180117 22:42:47</arrT>
<isApp>0</isApp>
<isDly>0</isDly>
<flags/>
<lat>41.92528</lat>
<lon>-87.70238</lon>
<heading>122</heading>
</train>
</route>
</data>
以下代码获取蓝色或红色的列车编号:
soup = bs4.BeautifulSoup(xml, 'xml')
soup.select_one('route[name="blue"] train rn').get_text()
soup.select_one('route[name="red"] train rn').get_text()
select
和select_one
函数允许css选择器(甚至在xml中)选择数据。要过滤标记的属性,请使用tagname[attrname="attrvalue"]
。
如果要将xml转换为python数据结构,可以使用以下内容:
from typing import *
import bs4
def xml_to_py(soup: bs4.BeautifulSoup) -> Dict[str, Dict[int, Dict[str, str]]]:
data = {}
for route in soup.select('route'):
route_data = data[route.get('name')] = {}
for train in route.select('train'):
train_number = int(train.select_one('rn').get_text())
train_data = {
tag.name: tag.get_text()
for tag in
train.select('*')
}
route_data[train_number] = train_data
return data
使用上面xml的bs4.BeautifulSoup
实例调用,会产生这个词典:
{
'blue': {
134: {
'arrT': '20180117 22:42:47',
'destNm': 'Forest Park',
'destSt': '30077',
'flags': '',
'heading': '122',
'isApp': '0',
'isDly': '0',
'lat': '41.92528',
'lon': '-87.70238',
'nextStaId': '40570',
'nextStaNm': 'California',
'nextStpId': '30112',
'prdt': '20180117 22:40:47',
'rn': '134',
'trDr': '5'
}
},
'red': {
830: {
'arrT': '20180117 22:42:16',
'destNm': '95th/Dan Ryan',
'destSt': '30089',
'flags': '',
'heading': '176',
'isApp': '1',
'isDly': '0',
'lat': '41.85532',
'lon': '-87.63133',
'nextStaId': '41000',
'nextStaNm': 'Cermak-Chinatown',
'nextStpId': '30194',
'prdt': '20180117 22:41:16',
'rn': '830',
'trDr': '5'
}
}
}