Skip to main content
 首页 » 编程设计

python之lxml.Element 对象的 Spark Python RDD

2025年02月15日27davidwang456

我想对一组 XML 文档进行一些交互式探索。我正在尝试使用 lxml 解析文档并使用它的 find、findall 和 xpath 方法进行查询。但是,当我尝试创建 Element 对象的 RDD 时,PySpark 阻塞了:

from lxml import etree 
from lxml.etree import XMLSyntaxError 
def get_root(xml): 
  xml_bytes = bytes(bytearray(xml, encoding = 'utf-8')) 
  try: 
    return [etree.XML(xml_bytes)] 
  except XMLSyntaxError: 
    return [] 
 
docs = [ 
    "<doc><tag name='hoo'>hah</tag><tag name='wah'>zoo</tag></doc>" 
  , "<doc><tag name='hoo'>yah</tag><tag name='wah'>woo</tag></doc>" 
] 
roots = [get_root(x)[0] for x in docs] 
roots 
  [<Element doc at 0x3b2280>, <Element doc at 0x3b2140>] 
docs_rdd = sc.parallelize(docs) 
roots_rdd = docs_rdd.flatMap(lambda d: get_root(d)) 
roots_rdd.count() 
  2 
roots_rdd.first() 
  Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "lxml.etree.pyx", line 1033, in lxml.etree._Element.__repr__ (src/lxml/lxml.etree.c:42268) 
    File "lxml.etree.pyx", line 881, in lxml.etree._Element.tag.__get__ (src/lxml/lxml.etree.c:40855) 
    File "apihelpers.pxi", line 15, in lxml.etree._assertValidNode  (src/lxml/lxml.etree.c:12875) 
  AssertionError: invalid Element proxy at 62728864 

有人可以帮助我了解这里发生了什么吗?

Python 2.7.x 或 3.5.x,Spark 1.6.x,lxml 安装有 pip 或 pip3。

提前致谢!

请您参考如下方法:

lxml 对象不可序列化,不能在执行器和驱动程序之间传递或打乱。完全无需使用 Spark 即可轻松重现:

from lxml import etree 
import pickle 
 
pickle.loads(pickle.dumps(etree.XML("<doc>foo</doc>"))) 
AssertionError                            Traceback (most recent call last) 
... 
AssertionError: invalid Element proxy at ... 

您仍然可以使用 lxml 来解析和获取可序列化的 Python 对象:

from operator import attrgetter 
 
docs_rdd.flatMap(get_root).flatMap(lambda x: x).map(attrgetter("text")).collect() 
['hah', 'zoo', 'yah', 'woo']