用于将使用循环提取的文本附加到 Python 中的列表的多重处理
Multiprocessing for appending text extracted with a loop to a list in Python
作为一个 Python(和编程)新手,我正在尝试将数千个 PDF 的文本提取到一个文件(或列表,如果更好的话)中。数据将在稍后阶段用于内容分析。我创建了一个工作函数,它遍历目录中的所有 PDF,使用 pdfplumber
提取文本并将其附加到列表中。
我现在想使用多处理来加速否则会非常冗长的过程。但是,我似乎无法弄清楚如何最好地实现使用并行进程附加到列表的循环。下面是尝试使用一些教程中的代码,使用 concurrent.futures
和我的函数:
import pdfplumber
import os
import concurrent.futures
def pdfextractor(file):
text = []
for file in os.listdir("./processing/"):
filename = os.fsdecode(file)
if filename.endswith('.pdf'):
with pdfplumber.open("./processing/" + file) as pdf:
pdf_page = pdf.pages[0]
single_page_text = pdf_page.extract_text()
text.append(str(single_page_text))
if __name__ == "__main__":
executor = concurrent.futures.ProcessPoolExecutor(4)
futures = [executor.submit(pdfextractor, 'file')]
concurrent.futures.wait(futures)
这导致启动多个进程,将相同的 PDF 文本附加到 text
列表。将 ProcessPoolExecutor
更改为 ThreadPoolExecutor
会产生所需的函数输出,但不会增加速度。
经过大量修改,我设法解决了这个问题。这是将 运行 函数所需时间减少一半以上的代码。我将函数一分为二以更好地适应 concurrent.futures
。 extract_pdf
遍历 PDF 的所有页面,提取文本并将其附加到列表中。 extract_all
然后在整个目录上重复此过程。结果是一个嵌套列表。
def extract_pdf(filename, directory):
filename = os.fsdecode(filename)
allpages_text = []
if filename.endswith('.pdf'):
with pdfplumber.open(directory + filename) as pdf:
for page in pdf.pages:
text = page.extract_text()
allpages_text.append(text)
allpages_text = '-'.join(allpages_text)
return allpages_text
def extract_all(directory):
data = []
with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:
futures = {executor.submit(extract_pdf, filename, directory): filename for filename in os.listdir(directory)}
for future in concurrent.futures.as_completed(futures):
try:
result = future.result()
data.append(result)
except Exception as exc:
print("There was an error. {}".format(exc))
return data
if __name__ == '__main__':
directory = './test/'
results = extract_all(directory)
这个网站对我更好地了解 concurrent.futures
模块的情况很有帮助:https://rednafi.github.io/digressions/python/2020/04/21/python-concurrent-futures.html
作为一个 Python(和编程)新手,我正在尝试将数千个 PDF 的文本提取到一个文件(或列表,如果更好的话)中。数据将在稍后阶段用于内容分析。我创建了一个工作函数,它遍历目录中的所有 PDF,使用 pdfplumber
提取文本并将其附加到列表中。
我现在想使用多处理来加速否则会非常冗长的过程。但是,我似乎无法弄清楚如何最好地实现使用并行进程附加到列表的循环。下面是尝试使用一些教程中的代码,使用 concurrent.futures
和我的函数:
import pdfplumber
import os
import concurrent.futures
def pdfextractor(file):
text = []
for file in os.listdir("./processing/"):
filename = os.fsdecode(file)
if filename.endswith('.pdf'):
with pdfplumber.open("./processing/" + file) as pdf:
pdf_page = pdf.pages[0]
single_page_text = pdf_page.extract_text()
text.append(str(single_page_text))
if __name__ == "__main__":
executor = concurrent.futures.ProcessPoolExecutor(4)
futures = [executor.submit(pdfextractor, 'file')]
concurrent.futures.wait(futures)
这导致启动多个进程,将相同的 PDF 文本附加到 text
列表。将 ProcessPoolExecutor
更改为 ThreadPoolExecutor
会产生所需的函数输出,但不会增加速度。
经过大量修改,我设法解决了这个问题。这是将 运行 函数所需时间减少一半以上的代码。我将函数一分为二以更好地适应 concurrent.futures
。 extract_pdf
遍历 PDF 的所有页面,提取文本并将其附加到列表中。 extract_all
然后在整个目录上重复此过程。结果是一个嵌套列表。
def extract_pdf(filename, directory):
filename = os.fsdecode(filename)
allpages_text = []
if filename.endswith('.pdf'):
with pdfplumber.open(directory + filename) as pdf:
for page in pdf.pages:
text = page.extract_text()
allpages_text.append(text)
allpages_text = '-'.join(allpages_text)
return allpages_text
def extract_all(directory):
data = []
with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:
futures = {executor.submit(extract_pdf, filename, directory): filename for filename in os.listdir(directory)}
for future in concurrent.futures.as_completed(futures):
try:
result = future.result()
data.append(result)
except Exception as exc:
print("There was an error. {}".format(exc))
return data
if __name__ == '__main__':
directory = './test/'
results = extract_all(directory)
这个网站对我更好地了解 concurrent.futures
模块的情况很有帮助:https://rednafi.github.io/digressions/python/2020/04/21/python-concurrent-futures.html