【问题标题】:How do you loop through multiple elements in a xml using beautiful soup4你如何使用漂亮的soup4循环遍历xml中的多个元素
【发布时间】:2022-01-11 08:28:03
【问题描述】:

我想做的是从 xml 对象中提取元素并列出各个属性 (现实世界的例子,我将手机中的短信文本备份为 xml,并希望将它们重写为 csv)

我一直在网上寻求帮助,发现了美味的汤。它似乎完全符合我的要求。使用在线示例,我可以从第一个元素中提取信息。但我终其一生都无法弄清楚如何超越小组中的第一个标签。据我所知,下面的代码应该给我:

5555555555 - 2019 年 8 月 30 日晚上 11:10:09

6666666666 - 2019 年 8 月 30 日晚上 11:10:09

7777777777 - 2019 年 9 月 1 日上午 7:50:09

但是我得到了以下错误

allsms = soup.findall('sms') TypeError: 'NoneType' 对象不可调用

我觉得我错过了一步。谁能帮我找出我做错了什么

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>

 <sms address="555555555" type="1" subject="null" body="hello world" t sub_id="-1" readable_date="Aug 30, 2019 11:10:09 PM" contact_name="Mr. X" />
 <sms address="6666666666" type="2" subject="null" body="world says hello" sub_id="-1" readable_date="Aug 30, 2019 11:10:09 PM" contact_name="Mrs. Y" /> 
 <sms address="7777777777" type="1" subject="null" body="relatable fact: carrots are not all orange" sub_id="-1" readable_date="Sep 01, 2019 07:50:09 AM" contact_name="Mr. Z" />  

################
from bs4 import BeautifulSoup
with open('texts.xml', 'r') as f:
data = f.read()

soup = BeautifulSoup(data, "xml")
allsms = soup.findall('sms')
for i in allsms:
sms=soup.find('sms')
address=sms.get('address')
realDate=sms.get('readable_date')
print(address + ' - ' + realDate)

【问题讨论】:

  • sms=soup.find('sms') 始终是第一个 sms 元素,因为您一遍又一遍地查询原始汤对象......您想在循环内引用 i(或者更好。 .. 将i 重命名为sms,然后删除您的sms=soup.find('sms') 行...
  • 是 find_all 或 findAll 但不是 findall
  • @diggusbickus findAll 已被弃用 ages...只是没有被删除,因为它目前可能会破坏太多东西...所以是的.. . 我推荐find_all
  • @Jon Clements - 谢谢,成功了!
  • 这是什么t --> body="hello world" t sub_id="-1" 。它使 XML 无效

标签: python xml beautifulsoup


【解决方案1】:

删除第一个sms元素中多余的t,用root包装xml并使用python内置的xml lib

import xml.etree.ElementTree as ET

xml = '''<r>
   <sms address="555555555" type="1" subject="null" body="hello world" sub_id="-1" readable_date="Aug 30, 2019 11:10:09 PM" contact_name="Mr. X" />
   <sms address="6666666666" type="2" subject="null" body="world says hello" sub_id="-1" readable_date="Aug 30, 2019 11:10:09 PM" contact_name="Mrs. Y" />
   <sms address="7777777777" type="1" subject="null" body="relatable fact: carrots are not all orange" sub_id="-1" readable_date="Sep 01, 2019 07:50:09 AM" contact_name="Mr. Z" />
</r>'''

root = ET.fromstring(xml)
for sms in root.findall('sms'):
  print(f'{sms.attrib["address"]} {sms.attrib["readable_date"]}')

输出

555555555 Aug 30, 2019 11:10:09 PM
6666666666 Aug 30, 2019 11:10:09 PM
7777777777 Sep 01, 2019 07:50:09 AM

【讨论】:

    猜你喜欢
    • 2012-11-23
    • 2012-05-14
    • 2022-06-11
    • 1970-01-01
    • 2010-11-16
    • 2017-12-12
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    相关资源
    最近更新 更多