【问题标题】:How to convert PDF with images which I don't care about to text?如何将带有我不关心的图像的 PDF 转换为文本?
【发布时间】:2021-03-23 17:09:31
【问题描述】:

我正在尝试将 pdf 转换为文本文件。问题是那些pdf包含我不关心的图像(这是我要提取的文件类型(https://www.sia.aviation-civile.gouv.fr/pub/media/store/documents/file/l/f/lf_sup_2020_213_fr.pdf)。请注意,如果我用鼠标复制/粘贴,它工作得很好(除了换行符),所以我猜这是可能的。我在网上找到的大多数答案在只有文本的虚拟 pdf 上工作得很好,但在地图上给出的结果特别糟糕。 比如这样的

from tika import parser # pip install tika
raw = parser.from_file('test2.pdf')
print(raw['content']) 

很适合检索文本,但我有很多这样的垃圾:

埃里

点击率

3

CH

一个

因为地图而出现。

类似这样的东西,通过将 pdf 转换为图像然后读取图像来工作,面临同样的问题(我在 stackoverflow 上的一个非常相似的线程上找到它,但没有答案):

import pytesseract as pt
from PIL import Image
import sys 

def convert(name):
    pages = convert_from_path(name, dpi=200)
    for idx,page in enumerate(pages):
        page.save('page'+str(idx)+'.jpg', 'JPEG')
        quote = Image.open('page'+str(idx)+'.jpg')
        text = pt.image_to_string(quote, lang="fra")
        file_ex = open('page'+str(idx)+'.text',"w")
        file_ex.write(text)
        file_ex.close()



if __name__ == '__main__':
    convert(sys.argv[1])

最后,我尝试先删除图像,然后使用上述解决方案之一,但效果不佳:

from tika import parser # pip install tika
from PyPDF2 import PdfFileWriter, PdfFileReader

# Remove the images
inputStream = open("lf_sup_2020_213_fr.pdf", "rb")
outputStream = open("test3.pdf", "wb")

 
src = PdfFileReader(inputStream)
output = PdfFileWriter()
 

[output.addPage(src.getPage(i)) for i in range(src.getNumPages())]
output.removeImages()
 

output.write(outputStream)
outputStream.close()

# Read from pdf without images
raw = parser.from_file('test2.pdf')
print(raw['content'])

你知道如何解决这个问题吗?它可以是任何语言。 谢谢

【问题讨论】:

    标签: pdf text converters pdftotext


    【解决方案1】:

    您可以尝试的一种方法是使用能够解析 PDF 中的文本字符的工具包,然后使用对象属性尝试删除不需要的地图标签,同时保留所需的文本字符。

    例如,LEADTOOLS PDF toolkit 中的ParsePages 方法(这是我为该工具包的供应商工作而熟悉的方法)可用于从 PDF 中获取文本:

    using (PDFDocument document = new PDFDocument(pdfFileName))
    {
       PDFParsePagesOptions options = PDFParsePagesOptions.All;
       document.ParsePages(options, 1, -1);
    
       using (StreamWriter writer = File.CreateText(txtFileName))
       {
          IList<PDFObject> objects = document.Pages[0].Objects;
          writer.WriteLine("Objects: {0}", objects.Count);
          foreach (PDFObject obj in objects)
          {
             if (obj.TextProperties.IsEndOfLine)
                writer.WriteLine(obj.Code);
             else
                writer.Write(obj.Code);
          }
          writer.WriteLine("---------------------");
       }
    }
    

    这将获取 PDF 中第一页的所有文本,以及您提到的不需要的结果。以下是摘录:

    Objects: 3918
    5
    91L
    F5
    4
    1 LF
    N
    OY
    L2
    1AM
    TService
    8
    26
    1de l’Information 
    0
    B09SUP AIP 213/20 
    7 
    Aéronautique
     
    Date de publication : 05 NOV 
    e-mail  : sia.qualite@aviation-civile.gouv.fr 
    Internet  : www.sia.aviation-civile.gouv.fr 
    141
     
    17˚
    82
    N20 
    9Objet : Création de 4 zones réglementées temporaires (ZRT) pour l’exercice VOLOPS en région de Chambéry 
    En vigueur : Du mercredi 25 Novembre 2020 au vendredi 04 décembre 2020 
    

    更多代码可用于检查每个已解析字符的属性:

    writer.WriteLine("  ObjectType: {0}", obj.ObjectType.ToString());
    writer.WriteLine("  Bounds: {0}, {1}, {2}, {3}", obj.Bounds.Left, obj.Bounds.Top, obj.Bounds.Right, obj.Bounds.Bottom);
    writer.WriteLine("  TextProperties.FontHeight: {0}", obj.TextProperties.FontHeight.ToString());
    writer.WriteLine("  TextProperties.FontIndex: {0}", obj.TextProperties.FontIndex.ToString());
    writer.WriteLine("  Code: {0}", obj.Code);
    writer.WriteLine("------");
    

    这将给出每个字符的属性:

      Objects: 3918
      ObjectType: Text
      Bounds: -60.952693939209, 1017.25231933594, -51.8431816101074, 1023.71826171875
      TextProperties.FontHeight: 7.10454273223877
      TextProperties.FontIndex: 48
      Code: 5
    ------
    

    使用这些属性,可以使用它们的属性过滤掉不需要的文本。例如,我注意到大部分不需要的文本的 FontHeight 约为 7 个 PDF 单位,因此可能会更改第一个代码以避免提取任何小于 7.25 个 PDF 单位的文本:

    foreach (PDFObject obj in objects)
    {
       if (obj.TextProperties.FontHeight > 7.25)
       {
          if (obj.TextProperties.IsEndOfLine)
             writer.WriteLine(obj.Code);
          else
             writer.Write(obj.Code);
       }
    }
    

    提取的输出会给出更好的结果,摘录如下:

    Objects: 3918
    Service
    de l’Information 
    SUP AIP 213/20 
     
    Aéronautique
    Date de publication : 05 NOV 
    e-mail  : sia.qualite@aviation-civile.gouv.fr 
    Internet  : www.sia.aviation-civile.gouv.fr 
     
    Objet : Création de 4 zones réglementées temporaires (ZRT) pour l’exercice VOLOPS en région de Chambéry 
    En vigueur : Du mercredi 25 Novembre 2020 au vendredi 04 décembre 2020 
     
    Lieu : FIR : Marseille LFMM - AD : Chambéry Aix-Les-Bains LFLB, Chambéry Challes les Eaux LFLE 
     
    ZRT LE SIRE, MOTTE CASTRALE, ALLEVARD 
    *
    C
    D
    E
    

    最后,您必须尝试提出一个好的标准来过滤掉不需要的文本,而不删除您需要保留的文本,使用这种方法。

    【讨论】:

      猜你喜欢
      • 2019-12-08
      • 2018-05-06
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 2015-06-01
      • 2011-11-13
      相关资源
      最近更新 更多