如何在Flask中读取、保存上传的PDF文件并提取文本内容
Flask上传PDF文件操作解决方案
1 保存文件为空的问题修复
当前保存的PDF为空的核心原因是前端表单未声明文件上传必需的编码格式:
HTML表单默认编码类型为application/x-www-form-urlencoded,仅支持传输文本数据,无法传输二进制文件内容,需要给form标签添加enctype="multipart/form-data"属性,修改后的前端表单代码如下:
<form method='POST' action='/saveData' enctype="multipart/form-data"> <input type='file' name='testReport' multiple> <!-- 加multiple属性支持多文件上传 --> <input type='submit'> </form>
修改后再调用save()方法即可生成正常可读取的PDF文件。
2 无需本地存储 直接操作上传的PDF对象
Flask中request.files拿到的文件是Werkzeug FileStorage类实例,本身支持类文件操作,不需要先存到本地,可以直接读取字节流交给PDF处理库解析,常用的PDF文本提取库有PyPDF2、pdfplumber,示例操作如下:
安装依赖
pip install pypdf2
完整可运行代码示例
from flask import Flask, request import os from PyPDF2 import PdfReader from io import BytesIO from werkzeug.utils import secure_filename # 用于文件名安全校验 app=Flask(__name__) app.config['UPLOAD_FOLDER'] = './uploads' # 配置上传目录,会自动创建 os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) @app.route('/') def index(): return ''' <form method='POST' action='/saveData' enctype="multipart/form-data"> <input type='file' name='testReport' multiple> <input type='submit'> </form> ''' @app.route('/saveData', methods=['POST']) def saveData(): if 'testReport' not in request.files: return '未上传文件' # 多文件上传用getlist遍历所有文件 files = request.files.getlist('testReport') all_text = '' for testReport in files: if testReport.filename == '': continue # 文件名安全处理,防止恶意构造文件名导致的路径穿越漏洞 filename = secure_filename(testReport.filename) # 可选:保存文件到本地 save_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) testReport.save(save_path) # 直接从流读取PDF内容,无需读本地文件 testReport.stream.seek(0) # 重置文件指针到开头(如果之前调用过save()必须加,否则可以省略) pdf = PdfReader(BytesIO(testReport.read())) # 提取所有页文本 for page in pdf.pages: all_text += page.extract_text() + '\n' return f'<h1>文件处理完成,提取文本长度:{len(all_text)}</h1>' if __name__ == '__main__': app.run(debug=True)
3 注意事项
- 务必使用
secure_filename处理用户上传的文件名,避免安全风险 - 可以添加文件后缀校验,仅允许后缀为
.pdf的文件上传,避免处理非法文件 - 若调用
save()方法后再操作流,必须调用testReport.stream.seek(0)重置文件指针到开头,否则读取到的内容为空
内容的提问来源于stack exchange,提问作者Shashank Prasad
相关产品推荐
相关产品推荐

