【问题标题】:VERY BAD XML trying to parse with Python非常糟糕的 XML 试图用 Python 解析
【发布时间】:2023-04-01 02:08:01
【问题描述】:

我在购买域名后尝试使用 python 解析 xml 输出。到目前为止,我有:

#!/usr/bin/python

import sys
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup

file = sys.argv[1]
xml = open(file).read()
soup = BeautifulStoneSoup(xml)
response = soup.find('ApiResponse')

print response

我正在使用的 XML 输出格式非常错误,肯定需要清理。

ok: [162.243.95.241] => {"cache_control": "private", "changed": false, "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ApiResponse Status=\"OK\" xmlns=\"http://api.namecheap.com/xml.response\">\r\n  <Errors />\r\n  <Warnings />\r\n  <RequestedCommand>namecheap.domains.create</RequestedCommand>\r\n  <CommandResponse Type=\"namecheap.domains.create\">\r\n    <DomainCreateResult Domain=\"123er321test.com\" Registered=\"true\" ChargedAmount=\"8.1800\" DomainID=\"33404\" OrderID=\"414562\" TransactionID=\"679462\" WhoisguardEnable=\"false\" FreePositiveSSL=\"false\" NonRealTimeDomain=\"false\" />\r\n  </CommandResponse>\r\n  <Server>WEB1-SANDBOX1</Server>\r\n  <GMTTimeDifference>--5:00</GMTTimeDifference>\r\n  <ExecutionTime>9.008</ExecutionTime>\r\n</ApiResponse>", "content_length": "647", "content_location": "https://api.sandbox.namecheap.com/xml.response", "content_type": "text/xml; charset=utf-8", "date": "Thu, 21 Nov 2013 03:23:51 GMT", "item": "", "redirected": false, "server": "Microsoft-IIS/7.0", "status": 200, "x_aspnet_version": "4.0.30319", "x_powered_by": "ASP.NET"}

这里又是pastebin 上的“xml”。

我正在尝试查找ApiResponse Status,即ERROROK

【问题讨论】:

  • '=>' 之后的所有内容都是 JSON,尝试使用 JSON 解析器提取 xml 属性,然后您需要 XML 解析器来破解它。
  • 这还是this question吗? - 如果是这样,没有必要有两个问题要求相同的事情......
  • 我想明白这一点后,我打算自己回答这个问题,因为我意识到我需要做的是编写一个 Ansible 模块,这就是我提出这个问题的原因。

标签: python xml beautifulsoup


【解决方案1】:

那里的 XML 绝对没有问题。

问题在于 XML 嵌入在 JSON 中,而 JSON 本身嵌入在某种我无法立即识别的对象中。 (我的怀疑是你刚刚从你用来发出请求的任何框架中丢弃了某种对象的repr,这是一件愚蠢的事情……)

因此,无论它是什么格式,都以适当的方式解析顶级事物。 (如果您不知道它来自哪里,看起来您可以轻松地执行.partition('=&gt;')[-1]。)然后使用json.loads 解析JSON。然后得到结果dict的['content'],也就是XML,可以用BeautifulSoup解析。然后你就完成了。

换句话说:

>>> thingy = r''' ok: [162.243.95.241] => {"cache_control": "private", "changed": false, "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ApiResponse Status=\"OK\" xmlns=\"http://api.namecheap.com/xml.response\">\r\n  <Errors />\r\n  <Warnings />\r\n  <RequestedCommand>namecheap.domains.create</RequestedCommand>\r\n  <CommandResponse Type=\"namecheap.domains.create\">\r\n    <DomainCreateResult Domain=\"123er321test.com\" Registered=\"true\" ChargedAmount=\"8.1800\" DomainID=\"33404\" OrderID=\"414562\" TransactionID=\"679462\" WhoisguardEnable=\"false\" FreePositiveSSL=\"false\" NonRealTimeDomain=\"false\" />\r\n  </CommandResponse>\r\n  <Server>WEB1-SANDBOX1</Server>\r\n  <GMTTimeDifference>--5:00</GMTTimeDifference>\r\n  <ExecutionTime>9.008</ExecutionTime>\r\n</ApiResponse>", "content_length": "647", "content_location": "https://api.sandbox.namecheap.com/xml.response", "content_type": "text/xml; charset=utf-8", "date": "Thu, 21 Nov 2013 03:23:51 GMT", "item": "", "redirected": false, "server": "Microsoft-IIS/7.0", "status": 200, "x_aspnet_version": "4.0.30319", "x_powered_by": "ASP.NET"}'''
>>> j = thingy.partition('=>')[-1]
>>> obj = json.loads(j)
>>> xml = obj['content']
>>> soup = BeautifulSoup(xml)
>>> soup
<?xml version="1.0" encoding="utf-8"?>
<apiresponse status="OK" xmlns="http://api.namecheap.com/xml.response">
<errors></errors>
<warnings></warnings>
<requestedcommand>namecheap.domains.create</requestedcommand>
<commandresponse type="namecheap.domains.create">
<domaincreateresult chargedamount="8.1800" domain="123er321test.com" domainid="33404" freepositivessl="false" nonrealtimedomain="false" orderid="414562" registered="true" transactionid="679462" whoisguardenable="false"></domaincreateresult>
</commandresponse>
<server>WEB1-SANDBOX1</server>
<gmttimedifference>--5:00</gmttimedifference>
<executiontime>9.008</executiontime>
</apiresponse>
>>> soup.find('apiresponse')['status']
'OK'

【讨论】:

  • 谢谢@abarnert!这确实做到了,但我需要用thingy.partition 替换第二行中的z.partition。巨大的帮助!
  • @DavidNeudorfer:对不起,是的,我先把它放在一个名为z 的变量中,然后把它放在thingy 中,因为这样看起来更易读,然后复制并粘贴了错误的行。固定。
猜你喜欢
  • 2012-05-06
  • 1970-01-01
  • 2017-01-25
  • 2018-06-27
  • 2010-09-16
  • 1970-01-01
  • 2015-04-08
  • 2021-03-11
  • 1970-01-01
相关资源
最近更新 更多