从HDFS读取XML文件以使用lxml.etree在Pyspark中进行解析

问题描述 投票:0回答:1

我已经使用lxml.etree用Python编写了一个解析器,现在我试图在Hadoop集群上运行所述解析器。当我在本地运行该函数时,它可以按预期工作,但是当我尝试将其应用于集群上的文件时,我收到以下错误(我正在Pyspark shell中执行以下命令,python3)

xml_pathname = "hdfs://file_path/date_directory/example_one.xml"
xml_tree = etree.parse(xml_pathname)

OSError: Error reading file '/file_path/date_directory/example_one.xml': failed to load external entity 
"/file_path/date_directory/example_one.xml"

在终端中运行hdfs dfs -ls /file_path/date_directory/example_one.xml时可以看到文件。

[我需要帮助的两个领域-

  1. 如何使用Pyspark从集群将XML文件加载到lxml.etree.parse()方法中?
  2. 我如何最好地扩大规模以在Spark上有效运行?我想使用我的Python解析器解析群集上的数百万个XML文件-以下修改工作是否可行,还是有更好的方法来解析并大规模运行解析器?通常,应该如何在spark配置中设置参数以获得最佳结果(大量执行程序,多个驱动程序等)?
#Same as above but with wildcards to parse millions of XML files

xml_pathname = "hdfs://file_path/*/*.xml"
xml_tree = etree.parse(xml_pathname)

从事此工作一段时间后,非常感谢您提供的所有帮助。谢谢大家

xml apache-spark hadoop pyspark lxml
1个回答
0
投票
  1. mapValues()函数被证明是有用的。 Sark配置的XML解析器(例如Pubmed解析器)也提供了有用的样板代码,例如:]
  2. path_rdd = sc.parallelize(path_sample, numSlices=10000) # use only example path
        parse_results_rdd = path_rdd.map(lambda x: Row(file_name=os.path.basename(x), **pp.parse_pubmed_xml(x)))
        pubmed_oa_df = parse_results_rdd.toDF()
        pubmed_oa_df_sel = pubmed_oa_df[['full_title', 'abstract', 'doi',
                                         'file_name', 'pmc', 'pmid',
                                         'publication_year', 'publisher_id',
                                         'journal', 'subjects']]
        pubmed_oa_df_sel.write.parquet(os.path.join(save_dir, 'pubmed_oa_%s.parquet' % date_update_str),
                                       mode='overwrite')
    

https://github.com/titipata/pubmed_parser/blob/master/scripts/pubmed_oa_spark.py

  1. 使用fs.globStatus允许在一个子目录中检索多个XML文件。
© www.soinside.com 2019 - 2024. All rights reserved.