Python-如何使用Python编写的lxml实现高性能XML解析?

Python-如何使用Python编写的lxml实现高性能XML解析?

灵芸 发布于 2016-11-30 字数 52 浏览 1326 回复 5

如果使用由Python编写的lxml实现高性能XML解析?

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

瑾兮 2017-07-30 5 楼

python有三种方法解析XML,SAX,DOM,以及ElementTree
1.SAX (simple API for XML )

pyhton 标准库包含SAX解析器,SAX是一种典型的极为快速的工具,在解析XML时,不会占用大量内存。但是这是基于回调机制的,因此在某些数据中,它会调用某些方法进行传递。这意味着必须为数据指定句柄,以维持自己的状态,这是非常困难的。

2.DOM(Document Object Model)

与SAX比较,DOM典型的缺点是比较慢,消耗更多的内存,因为DOM会将整个XML数读入内存中,并为树中的第一个节点建立一个对象。使用DOM的好处是你不需要对状态进行追踪,因为每一个节点都知道谁是它的父节点,谁是子节点。但是DOM用起来有些麻烦。

3.ElementTree(元素树)

 ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

想挽留 2017-05-11 4 楼

提高性能的其他方法

除了使用 lxml 内部 的特定方法外,还可以通过库以外的方法提高执行速度。其中一些方法只需要修改一下代码;而另一些方法则需要重新考虑如何处理大型数据。

Psyco

Psyco 模块常常被忽略,但是它可以通过较少的工作提高 Python 应用程序的速度。一个纯 Python 程序的典型性能收益是普通程序的 2 至 4 倍,但是 lxml 使用 C 语言完成了大部分工作,因此它们之间的差别非常小。当我在启用 Psyco 的情况下运行 清单 4 时,运行时间仅仅减少了 3 秒(43.9 秒对 47.3 秒)。Psyco 需要很大的内存开销,如果机器进入交换,它甚至会抵销 Python 获得的任何性能。

如果由 lxml 驱动的应用程序包含频繁执行的核心纯 Python 代码(可能是对文本节点执行的大量字符串操作),那么仅对这些方法启用 Psyco 可能会有好处。有关 Psyco 的更多信息,参见 参考资料。

线程化

相反,如果应用程序主要依赖内部的、C 驱动的 lxml 特性,那么可能适合将它作为多处理环境下的线程化应用程序运行。关于如何启动线程有很多限制 — 对 XSLT 而言尤其如此。要了解更多内容,可参考 lxml 文档中有关线程的 FAQ 部分。

拆分解决

如果可以将特别大的文档分解为单个的、可分析的子树,那么就可以在子树级别上分解文档(使用 lxml 的快速序列化),并将工作分布到位于多台计算机中的这些文件。对于执行 CPU 密集型的脱机任务,使用随需应变的虚拟服务器正成为一种日益流行的解决方案。

适合大型 XML 任务的一般策略

对于 GB 级或以上的 XML 数据,可以考虑以下的原则(已通过测试和 lxml 文档的验证):

使用迭代解析策略,渐进式地处理大型文档。
如果需要随机地搜索整个文档,那么使用索引式 XML 数据库。
只选择需要的数据。如果只对特定的节点感兴趣,使用按名字选择的方法。如果需要谓词语法,那么尝试可用的 XPath 类和方法。
考虑手头的任务和开发人员的舒适程度。如果不需要考虑速度的话,lxml 的对象化或 Amara 等对象模型对于 Python 开发人员来说可能更自然。cElementTree 在只需要进行解析时才会体现出速度优势。
花些时间做些非常简单的基准测试。在处理数百万条记录时,细微的差别就会累积起来,但是并不能总是很明显地看出哪种方法最有效。

参考资料:使用由 Python 编写的 lxml 实现高性能 XML 解析

瑾兮 2017-04-09 3 楼

可以告诉你最快的是 自己写字符串处理 或者正则
给你个例子 python写的找不到了 这个是php的 有两个版本 正在是用中的代码

 function &parse_xml_iter(&$data, $root_str)
{
$root_len = strlen($root_str) + 2;
$root_lene = $root_len + 1;
$records = array();
$lp = 0;
$sn = 0;
while (true){
$ps = strpos($data, "<$root_str>", $lp);
if (false === $ps) break;
$data_s = $ps + $root_len;
$pe = strpos($data, "</$root_str>", $data_s);
if (false === $pe) break;
$record = substr($data, $data_s, $pe - $data_s);
$item = array();
$flp = 0;
$sn += 1;
while (true){
$fs = strpos($record, '<', $flp);
if (false === $fs) break;
$fss = $fs+1;
$fe = strpos($record, '>', $fss);
if (false === $fe) break;
$fns = $fe - $fss;
$fname = substr($record, $fss, $fns);
if (empty($fname)) break;
$fbs = $fs + 2 + $fns;
$fb = strpos($record, "</$fname>", $fbs);
if (substr($fname, -2) == ' /'){
$fname = substr($fname, 0, -2);
$fb = $fbs + 1;
$fds = 0;
$fdata = '';
}
else{
if (false === $fb) break;
$fds = $fb - $fbs;
$fdata = substr($record, $fbs, $fds);
}
if($fds >= 12 && strpos($fdata, '<![CDATA[') !== false && strpos($fdata, ']]>') !== false)
$fdata = substr($fdata, 9, $fds - 12);
$item[$fname] = $fdata;
$flp = $fb + 3 + $fns;
}
$item['sn'] = $sn;
if ($sn == 1) $item['isfirst'] = '1';

$records[] = $item;
$lp = $pe + $root_lene;
}
return $records;
}

清晨说ぺ晚安 2017-01-24 2 楼

lxml 是一种使用 Python 编写的库,可以迅速、灵活地处理 XML。它支持 XML Path Language (XPath) 和 Extensible Stylesheet Language Transformation (XSLT),并且实现了常见的 ElementTree API。本文主要关注 lxml 的易用性,以及它在处理大型 XML 数据时提供的高性能配置文件。

具体的可以看如下地址的介绍使用由 Python 编写的 lxml 实现高性能 XML 解析

夜无邪 2016-12-07 1 楼

pyquery也可以