0

我正在寻找将 PDF 文件中的文本保存到我的数据库中的最有效方法。目前我正在使用带有标准代码的pdfplumber,如下所示:

my_string = ''

with pdfplumber.open(text_file_path) as pdf:
    for page in pdf.pages:
        if page.extract_text():
            my_string += str(page.extract_text().replace('\n', ' ').split(' '))

但是当前的代码是文学性的扼杀我的机器(对于 600 页的 PDF,它需要大约 3 到 6 GB 的 RAM),我的目标是实际将它托管在手机上。

我做了一些测试,似乎阅读 PDF 不是问题,但是保存或存储这些单词是有问题的。我试图创建 dict ,其中每个页面字符串都是一个键/值,但并没有好多少。

也许我应该尝试将每个页面生成 txt 文件,然后从这个 txt 文件中读取字符串?

我将不胜感激任何提示,谢谢!

编辑:

    with pdfplumber.open(text_file_path) as pdf:
        for page in pdf.pages:
            connection = sqlite3.connect('my_db.db')
            cursor = connection.cursor()
            cursor.execute("INSERT INTO temp_text VALUES (?, ?)",
                           (text_file_path, str(page.extract_text()).replace('\n', ' ')))
            connection.commit()
            connection.close()

我将代码更改为那个,它稍微好一点,(现在它需要大约 2.9 GB 的 RAM)但它仍然很多。我能做更多的事情吗?

4

1 回答 1

1

问题是您要长期存储数据,这意味着随着您逐步处理越来越多的数据,您仍然在内存中引用它。这就是数据库旨在防止的:所有有效的数据存储和检索,而无需将其全部存储在 RAM 中。一个使用 PyMongo 的简单示例(对于 iOS 应用程序,您可能会想要使用 SQLite)如下:

import pdfplumbder
import poymongo
import os


def process_file(path, collection):
    '''Process a single file, from a path.'''

    basename = os.path.splitext(os.path.basename(path))[0]
    with pdfplumber.open(path) as pdf:
        for index, page in enumerate(pdf.pages):
            # Don't store any long-term references to the data
            text = page.extract_text()
            data = { 'text': text, 'filename': basename, 'page': index }
            collection.insert_one(data)

def main(paths):
    '''Just a dummy entry point, pass args normally here.'''

    client = pymongo.MongoClient('localhost', 27017)
    database = client['myapp']
    collection = database['pdfs']
    # Sort by filename, then by page.
    collection.create_index([('filename', 1), ('page', 1)])
    for path in paths:
        process_file(path, collection)

    # Do what you want here

如您所见,我们创建了与本地客户端的连接,创建或访问我们正在使用的数据库,并创建一个用于 PDF 存储的集合。然后我们按文件名索引,然后是页码。

然后我们遍历所有路径,并迭代处理它们。我们一次不会存储超过一页的文本,并且每次循环都将数据写入数据库。就性能而言,这可能不是最佳的(尽管引擎可能无论如何都会对其进行优化),但它将最小化所需的内存。

避免使用处理许多 GB 数据的全局状态:您正在强制 Python 在不需要时保留对所有数据的引用。

于 2021-05-06T17:05:32.260 回答