作为一名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可获得所需的函数输出,但不会提高速度。
发布于 2020-10-28 21:47:53
经过大量的修修补补,我终于弄明白了这一点。下面的代码将运行函数所需的时间减少了一半以上。我将我的函数一分为二,以便更好地适应concurrent.futures。extract_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
https://stackoverflow.com/questions/64552662
复制相似问题