You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速从PDF提取文本的Python函数 批量处理数万份法院判决PDF

首先澄清几个认知误区

  • 你对numba的猜测完全正确:numba的@njit装饰器只支持纯Python数值运算和极少量内置操作,你调用的wget、pdftotext、文件IO都不在它的支持范围内,这类工具本来就是为数值计算场景设计的,完全不适合当前任务,直接放弃这个方向即可。
  • 你理解的「向量化加速」适用场景错了:Pandas/Numpy的向量化是为了规避Python循环的开销,加速纯内存CPU密集型的数值计算,而你的任务90%以上的耗时都在**网络下载PDF(网络IO)、磁盘读写文件(磁盘IO)**上,这部分瓶颈根本不是Python循环的开销,所以再怎么折腾向量化也不会有效果。
  • 你之前直接传Series给Link2Text报错的原因很简单:这个函数本身只接受单个URL字符串作为输入,你传一整个Series进去,wget根本没法处理序列输入,自然报错。df['URLs'].item是方法,你没加括号调用,所以传了个函数对象进去才会报decode的错,就算你加了括号,.item()也只能取单个元素,还是处理不了批量URL。

正确的优化方案:用并发处理IO密集型任务

IO密集型任务的核心优化逻辑是:不让CPU在等待网络/磁盘响应的时候闲置,同时发起多个下载、解析请求,就能大幅提升整体速度。这里推荐用concurrent.futures.ThreadPoolExecutor多线程实现,代码改动极小,速度能提升数倍到数十倍(取决于你的网络带宽)。

优化后代码示例

import os
import pandas as pd
import pdftotext
import wget
import threading
from concurrent.futures import ThreadPoolExecutor

# 原函数仅需调整临时文件名,避免多线程写入冲突
def Link2Text(Link):
    # 用线程ID生成唯一临时文件名,不会和其他线程冲突
    temp_file = f"Temporary_Opinion_{threading.get_ident()}.pdf"
    OpinionPDF = wget.download(Link, temp_file)
    with open(OpinionPDF, "rb") as f:
        pdf = pdftotext.PDF(f)
    OpinionText = "\n\n".join(pdf)
    if os.path.exists(temp_file):
        os.remove(temp_file)
    return OpinionText

# 你的示例数据
df = pd.DataFrame({'OpinionText': [""], 'URLs': ["https://cases.justia.com/federal/appellate-courts/ca6/20-6226/20-6226-2021-09-17.pdf?ts=1631908842"]})
df = pd.concat([df]*50, ignore_index=True)

# 多线程调用,max_workers可根据你的网络情况调整,一般设为10-30即可
max_workers = 20
with ThreadPoolExecutor(max_workers=max_workers) as executor:
    df['OpinionText'] = list(executor.map(Link2Text, df['URLs'].tolist()))

额外优化提示

  • 可以把max_workers调整到你网络能承受的上限,带宽足够的话设为50也可以,速度会更快。
  • 处理数万份PDF时建议加失败重试机制,避免因为个别网络请求失败导致整个任务中断。

内容的提问来源于stack exchange,提问作者bbernicker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:18:00