如何在 Apache Spark scala 中读取 PDF 文件和 xml 文件?

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

我的读取文本文件的示例代码是

val text = sc.hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text], sc.defaultMinPartitions)
    var rddwithPath = text.asInstanceOf[HadoopRDD[LongWritable, Text]].mapPartitionsWithInputSplit { (inputSplit, iterator) ⇒
      val file = inputSplit.asInstanceOf[FileSplit]
      iterator.map { tpl ⇒ (file.getPath.toString, tpl._2.toString) }
    }.reduceByKey((a,b) => a)

这样我如何使用PDF和Xml文件

scala apache-spark rdd
4个回答
9
投票

PDF 和 XML 可以使用 Tika 进行解析:

查看 Apache Tika - 内容分析工具包 enter image description here 看看 - https://tika.apache.org/1.9/api/org/apache/tika/parser/xml/
- http://tika.apache.org/0.7/api/org/apache/tika/parser/pdf/PDFParser.html
- https://tika.apache.org/1.9/api/org/apache/tika/parser/AutoDetectParser.html
以下是 Spark 与 Tika 集成的示例:

import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import org.apache.spark.input.PortableDataStream
import org.apache.tika.metadata._
import org.apache.tika.parser._
import org.apache.tika.sax.WriteOutContentHandler
import java.io._

object TikaFileParser {

  def tikaFunc (a: (String, PortableDataStream)) = {

    val file : File = new File(a._1.drop(5))
    val myparser : AutoDetectParser = new AutoDetectParser()
    val stream : InputStream = new FileInputStream(file)
    val handler : WriteOutContentHandler = new WriteOutContentHandler(-1)
    val metadata : Metadata = new Metadata()
    val context : ParseContext = new ParseContext()

    myparser.parse(stream, handler, metadata, context)

    stream.close

    println(handler.toString())
    println("------------------------------------------------")
  }


  def main(args: Array[String]) {

    val filesPath = "/home/user/documents/*"
    val conf = new SparkConf().setAppName("TikaFileParser")
    val sc = new SparkContext(conf)
    val fileData = sc.binaryFiles(filesPath)
    fileData.foreach( x => tikaFunc(x))
  }
}

4
投票

PDF 可以在 pyspark 中解析如下:

如果 PDF 存储在 HDFS 中,则使用 sc.binaryFiles() 因为 PDF 是以二进制格式存储的。 然后二进制内容可以发送到pdfminer进行解析。

import pdfminer
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument

def return_device_content(cont):
    fp = io.BytesIO(cont)
    parser = PDFParser(fp)
    document = PDFDocument(parser)

filesPath="/user/root/*.pdf"
fileData = sc.binaryFiles(filesPath)
file_content = fileData.map(lambda content : content[1])
file_content1 = file_content.map(return_device_content)

可以使用 pdfminer 提供的功能来完成进一步的解析。


1
投票

您可以简单地将spark-shell与tika结合使用,并根据您的用例以顺序方式或分布式方式运行以下代码

spark-shell --jars tika-app-1.8.jar
val binRDD = sc.binaryFiles("/data/")
val textRDD = binRDD.map(file => {new org.apache.tika.Tika().parseToString(file._2.open( ))})
textRDD.saveAsTextFile("/output/")
System.exit(0)

0
投票

您可以使用 PDF DataSource for Apache Spark 将 PDF 文件读取到 DataFrame。它支持数字和扫描的 PDF 文件。

以下是在 Scala 中读取 PDF 文件的代码示例:

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("Spark PDF Example")
  .master("local[*]")
  .config("spark.jars.packages", "com.stabrise:spark-pdf_2.12:0.1.7")
  .getOrCreate()
   
val df = spark.read.format("pdf")
  .option("imageType", "BINARY")
  .option("resolution", "200")
  .option("pagePerPartition", "2")
  .option("reader", "pdfBox")
  .load("path to the pdf file(s)")

df.show()

输出 DataFrame 包含以下列:

  • path:文件路径
  • page_number:文档的页码
  • text:从PDF页面的文本层提取文本
  • 图像:页面的图像表示
  • document:从渲染图像中 OCR 提取的文本(调用 Tesseract OCR)
  • partition_number:分区号
© www.soinside.com 2019 - 2024. All rights reserved.