【问题标题】:How to access remote and encrypted PDF text without writing to local drive [closed]如何在不写入本地驱动器的情况下访问远程和加密的 PDF 文本[关闭]
【发布时间】:2021-07-31 05:55:01
【问题描述】:

我是编码世界的新手,现在已经被这个问题困扰了 3 天,到处寻找答案,所以任何帮助都将不胜感激。我需要从位于 url 的 Pdf 文件中提取少量文本。我使用sessions.get(chart_PDF) 作为定位URL 的驱动程序,其中chart_PDF 是下面的示例URL。

示例网址为https://www.airservicesaustralia.com/aip/pending/dap/PADGN01-166_09SEP2021.pdf

我知道我可以将其写入本地驱动器,但我不想这样做,我希望能够远程执行,因为我只需要其中的几个数字。

我尝试从 url 页面查找密码进行解密,但找不到。我尝试过使用PyPDF2pdfminerpikepdf(可能不太好)。

我只需要检索 PDF 底部附近的两个数字即可用于我的其余代码。请帮助,即使这是一个简单的修复,我对这一切都是新手,需要一些帮助。谢谢。

from io import BytesIO
from pikepdf import Pdf as PDF
from pdfminer import high_level
chart_PDF = https://www.airservicesaustralia.com/aip/pending/dap/PADGN01-166_09SEP2021.pdf
retrieve = s.get(chart_PDF)
content = retrieve.content

response =urllib.request.urlopen(chart_PDF)
p = BytesIO(content)
p.getbuffer()
check = PDFPage.get_pages(p, check_extractable=False)
extract = high_level.extract_text(p)

我明白了:

PDFTextExtractionNotAllowedWarning:位于 ​​0x000001B007ABEC20> 的 PDF <_io.bytesio pdftextextractionnotallowedwarning>

或者,如果我尝试这个:

from pikepdf import Pdf as PDF
from pdfminer.pdfpage import PDFPage
from PyPDF2 import PdfFileReader
new_pdf = PDF.new()
with PDF.open(p) as pdf:
    print(len(pdf.pages))
    page1 = pdf.pages[0]
    if PdfFileReader.getIsEncrypted(pdf):
        print(True)
        PdfFileReader.decrypt(page1, password='')
pdf.close()

我明白了:

第 1987 行,在解密中 返回self._decrypt(密码) 属性错误:_decrypt

21 年 3 月 8 日更新 非常感谢KJ!你真的帮了大忙!

from io import BytesIO
from pdfminer.pdfpage import PDFPage
from pdfminer import high_level

retrieve = s.get(chart_PDF)
content = retrieve.content
bytes = BytesIO(content)
bytes.getbuffer()
PDFPage.get_pages(bytes, check_extractable=False)
extract = high_level.extract_text(bytes, password='') #THIS LINE THROWS ERROR
joined = ''.join(extract)
find_txt = re.findall(r'[(]\d*[-]\d[.]\d[)]', joined)
print(find_txt)
bytes.close()

现在运行良好,我已经能够提取我需要的数字(我基本上已经从 PDF 的括号内提取了所有数字)。我会整理一下,找到我需要的。

奇怪的是,虽然它给了我我需要的东西,但我的 extract = high_level.extract_text(bytes, password='') 行仍然抛出警告:(warning_msg, PDFTextExtractionNotAllowedWarning),这很烦人。不确定这个过程是如何工作的,但它仍然会泄露信息。

我不能使用 try except 或者它会跳过它。解决方法是什么?我怎样才能阻止这个错误的出现?

最终更新

我绕过了警告,现在效果很好。

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    extract = high_level.extract_text(bytes)

为忍受我的无知干杯,你们帮了很多忙。

【问题讨论】:

  • 您无法对远程文件进行操作 - 在从服务器请求它之后,字节就在您的机器中。但是,您可以将字节加载到 in-memory buffer 并在那里对其进行操作。
  • 感谢您的回复。我已经编辑了我的问题以包括我正在尝试使用缓冲区的内容。它绝对是经过编码的。
  • 将 pdf 数据加载到缓冲区后,您需要将其传递给某些东西——也许是您提到要解析的 Python PDF 包之一。通常该函数会声明它接受“类似文件的对象”,这意味着缓冲区是可以接受的。请注意,PDF 不是文本格式,因此无法解码:字节必须由能够理解 PDF 文件格式的东西解析。
  • 非常感谢您的帮助。我会继续努力,如果我得到任何东西,我会告诉你。
  • 我不知道 Mutool是一种在 Python 中使用 Mutool 或类似工具“清理”的方法,这很棒,可以消除我对警告消音器的需求。转换为 HTML 并返回是一个好主意,因为每个单独的图表(如您预测的那样)都显示了我的抽到所需的数字后,在不同的位置。我会给它一个聪明的伙伴,谢谢。

标签: python pdf encryption text decode


【解决方案1】:

整个文件必须通过 RAM 下载到设备,因此可以在最后将 blob 作为 FILE 解析为 一个或多个 %%EOF 和页面 0 的位置(它被转换为 1 或 i)它可以在流中的任何位置。

然后,您可以按照它们的构建顺序导航到其他连续编号的页面。如有任何投诉,请联系 Adob​​e。

但是,如果将其缓存为物理 FILE 对象,则最简单。如果您不想将其保存在磁盘上,请为您的浏览器使用 ram 驱动器

同样,第一页底部的这两个对象可能在任何地方混合到“页面”99 对象的内容中,或者以其他方式。 PDF 中的每个字母在极端情况下可以是文件中任何位置的多个对象。但是一个好的创作编辑器会尝试将它们逐行保存。 (没有像单词或段落这样的 PDF 内容。)

我们可以将文件打印为纯文本,以查看它是如何合成的,尽管(安全)这是允许的。

我尝试从浏览器打印但收效甚微,但我知道这可能取决于浏览器系统和操作系统打印驱动程序。在这里,我使用便携式 Acrobat 将页面打印为文本,因此我们可以从左侧边距看到每个文本块的顺序偏移量,就像 PDF VIEWER 需要重建它们一样。

更新 您说您的目标是 (1380-4.4) 到 ALTERNATE 的右侧,但是 PDF 没有左右或之前或之后的概念,因此我们在此文件中发现变量目标位于已知字符之前的 2 个单独部分中幸运的是是一个完整的单块(替代)。因此,如果捕获仅限于附近的位置,那么纯文本的接近性可能会很好地工作。但是,不能保证 ALTERNATE 始终是单个块。

展示打印机将获得顺序数据流的方式可能不是一个好主意 这是 PDF 查看器解密文件的方式

正如本次所述,单词 ALTERNATE 被定义为文本,但下一项是“B”下的“3”,它是作为矢量路径的文本,它不称为“字符”,尽管它看起来像一个但字体表中的编号字形。我们稍后会看到其中一些数字存储为“文本”,并且对于您的目标,它与同一对象中的类似文本混合在一起。

因此,您需要调用 PDF 解释器,为您提供对所有对象和片段的有意义的翻译,以便您可以提取“正确”的文本。

在复杂文件中“简单”的单行目标最简单的方法是先使用 MuPDF 来整理文件

    mutool clean -gggg -D infile.pdf outfile.pdf

结合

    PDFTOTXT -layout outfile.pdf outfile.txt

或类似于希望逐行导出该文本,以便您可以始终之前立即找到您的目标!或在 ALTERNATE 之后。

N.B Mutool 转换为 HTML 会将目标值放在关键字之后的表条目中,如果行数一致,这将是一种更简单的查找或 grep 方法。

【讨论】:

  • 非常感谢您花时间帮助我。是的,我实际上只需要从该文件中提取 ALTERNATE 右侧的 (1380-4.4) 数字字段。我的程序将选择由用户输入间接决定的 PDF 图表。所以我提取所述数字的方法必须适用于任何图表,好消息是所有 PDF 图表都具有完全相同的布局。您是说它能够以纯文本形式打印,尽管它是安全的,这很好。我一直在努力解决这个问题。
  • 谢谢,很高兴知道它在某处。我计划(一旦我知道如何提取文本)使用 Regex.findall 来提取所有内容。然后我打算把它列成一个列表,这样我就可以通过索引位置来获取它。我知道你是说文件中没有“职位”,我明白了。我只是希望在运行 findall 时空白区域等于什么。您是否知道一些能够获取此文本的代码?你可以看到我上面的尝试失败了。你会建立在我现有的基础上还是从头开始?
  • KJ 非常感谢您的帮助。我尝试了你建议的一切。你完蛋了!我已经更新了我原来的问题。
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2021-02-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-20
相关资源
最近更新 更多