【问题标题】:Beautiful soup nesting loops美丽的汤嵌套循环
【发布时间】:2021-04-21 13:11:02
【问题描述】:

我的 XML 有类似这样的嵌套结构:

<xml>
<top>
<main_record attr1="val1" attr2 = "val2" attr3="val3">
    <sub_record attrx="valx" attry="valy" />
</main_record>
<main_record attr1="val4" attr2 = "val5" attr3="val6">
    <sub_record attrx="valx2" attry="valy2" />
</main_record>
<main_record attr1="val7" attr2 = "val8" attr3="val9">
    <sub_record attrx="valx3" attry="valy3" />
</main_record>
</top>
</xml>

我正在尝试使用漂亮的汤来提取每个“main_record”及其“sub_record”属性的数据,以便我可以在 CSV 文件中的行中使用它。

我可以得到一个循环来打印文件中的所有 attr1、attr2 和 attr3 值,但是当我尝试在里面添加一个子循环来获取 attrx 和 attry 时,它不能正常工作。

from bs4 import BeautifulSoup

f = open("C:\\tracker.log", "r")
x = f.read()

soup = BeautifulSoup(x, 'html.parser')

for entity in soup.find_all('main_record'):
    print(entity.get('attr1'))
    print(entity.get('attr2'))
    print(entity.get('attr3'))
    for positions in soup.find('sub_record'):
        print(positions.get('attrx'))
        print(positions.get('attry'))

任何帮助/指针表示赞赏。

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    第二个for循环使用entity.find_all

    查看以下代码:

    for entity in soup.find_all('main_record'):
        print(entity.get('attr1'))
        print(entity.get('attr2'))
        print(entity.get('attr3'))
        for positions in entity.find_all('sub_record'):
            print(positions.get('attrx'))
            print(positions.get('attry'))
    

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      for index,entity in enumerate(soup.find_all('main_record')):
          attr1 = entity.get('attr1')
          attr2 = entity.get('attr2')
          attr3 = entity.get('attr3')
          attrx = entity.find('sub_record').get('attrx')
          attry = entity.find('sub_record').get('attry')
          print(f'{index}) attr1 is {attr1}, attr2 is {attr2}, attr3 is {attr3}, attrx is {attrx}, attry is {attry}')
      

      输出:

      0) attr1 is val1, attr2 is val2,attr3 is val3,attrx is valx,attry is valy
      1) attr1 is val4, attr2 is val5,attr3 is val6,attrx is valx2,attry is valy2
      2) attr1 is val7, attr2 is val8,attr3 is val9,attrx is valx3,attry is valy3
      

      【讨论】:

        【解决方案3】:

        您可以转换为 json/dictionary,然后让 pandas 将其展平。你需要pip install xmltodict

        给定:

        xml_file.xml = '''
        <xml>
        <top>
        <main_record attr1="val1" attr2 = "val2" attr3="val3">
            <sub_record attrx="valx" attry="valy" />
        </main_record>
        <main_record attr1="val4" attr2 = "val5" attr3="val6">
            <sub_record attrx="valx2" attry="valy2" />
        </main_record>
        <main_record attr1="val7" attr2 = "val8" attr3="val9">
            <sub_record attrx="valx3" attry="valy3" />
        </main_record>
        </top>
        </xml>'''
        

        代码:

        import xmltodict
        import pandas as pd
        
        with open("xml_file.xml") as xml_file:
            data_dict = xmltodict.parse(xml_file.read())
        
        df = pd.json_normalize(data_dict, record_path=['xml','top', 'main_record'])
        

        输出:

        print(df)
          @attr1 @attr2 @attr3 sub_record.@attrx sub_record.@attry
        0   val1   val2   val3              valx              valy
        1   val4   val5   val6             valx2             valy2
        2   val7   val8   val9             valx3             valy3
        

        如果你想摆脱'@',只需将它们替换为''

        df.columns = [x.replace('@','') for x in df.columns]
        
        print(df)
          attr1 attr2 attr3 sub_record.attrx sub_record.attry
        0  val1  val2  val3             valx             valy
        1  val4  val5  val6            valx2            valy2
        2  val7  val8  val9            valx3            valy3
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-16
          • 1970-01-01
          • 2019-04-21
          • 2018-03-12
          • 2018-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多