Python 使用 lxml 写入包含系统性能数据的 xml 文件

Python using lxml to write an xml file with system performance data

我正在使用 python 模块 lxmlpsutil 来记录一些系统指标,这些指标将放在 XML 文件中并复制到远程服务器进行解析php 并显示给用户。

但是,lxml 在将一些变量、对象等推送到我的 XML 的各个部分时给我带来了一些麻烦。

例如:

import psutil, os, time, sys, platform
from lxml import etree

# This creates <metrics>
root = etree.Element('metrics')

# and <basic>, to display basic information about the server
child1 = etree.SubElement(root, 'basic')

# First system/hostname, so we know what machine this is
etree.SubElement(child1, "name").text = socket.gethostname()

# Then boot time, to get the time the system was booted.
etree.SubElement(child1, "boottime").text = psutil.boot_time()

# and process count, see how many processes are running.
etree.SubElement(child1, "proccount").text = len(psutil.pids()) 

获取系统主机名的行有效。

但是接下来的两行获取启动时间和进程计数错误,其中:

>>> etree.SubElement(child1, "boottime").text = psutil.boot_time()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "lxml.etree.pyx", line 921, in lxml.etree._Element.text.__set__ (src/lxml/lxml.etree.c:41344)
 File "apihelpers.pxi", line 660, in lxml.etree._setNodeText (src/lxml/lxml.etree.c:18894)
 File "apihelpers.pxi", line 1333, in lxml.etree._utf8 (src/lxml/lxml.etree.c:24601)
 TypeError: Argument must be bytes or unicode, got 'float'
>>> etree.SubElement(child1, "proccount").text = len(psutil.pids())
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "lxml.etree.pyx", line 921, in lxml.etree._Element.text.__set__ (src/lxml/lxml.etree.c:41344)
 File "apihelpers.pxi", line 660, in lxml.etree._setNodeText (src/lxml/lxml.etree.c:18894)
 File "apihelpers.pxi", line 1333, in lxml.etree._utf8 (src/lxml/lxml.etree.c:24601)
 TypeError: Argument must be bytes or unicode, got 'int'

所以,这是我的 XML 打印出来的样子:

>>> print(etree.tostring(root, pretty_print=True))
<metrics>
  <basic>
    <name>mercury</name>
    <boottime/>
    <proccount/>
  </basic>
</metrics>

那么,有没有像我需要的那样将浮点数和整数推送到 xml 文本?还是我这样做完全错了?

感谢您提供的任何帮助。

text 字段应该是 unicode 或 str,而不是任何其他类型(boot_timefloatlen() 是 int)。 所以只需将不符合字符串的元素转换为字符串即可:

# First system/hostname, so we know what machine this is
etree.SubElement(child1, "name").text = socket.gethostname() # nothing to do

# Then boot time, to get the time the system was booted.
etree.SubElement(child1, "boottime").text = str(psutil.boot_time())

# and process count, see how many processes are running.
etree.SubElement(child1, "proccount").text = str(len(psutil.pids()))

结果:

b'<metrics>\n  <basic>\n    <name>JOTD64</name>\n    <boottime>1473903558.0</boottime>\n    <proccount>121</proccount>\n  </basic>\n</metrics>\n'

我想库可以进行 isinstance(str,x) 测试或 str 转换,但它不是那样设计的(如果你想显示带有前导零的浮点数,截断小数点.. .). 如果 lib 假设一切都是 str,它运行得更快,大多数时候都是这样。