Python如何从FastAPI接收的spool PDF文件中提取超链接
问题根因说明
- PDF是二进制格式文件,不属于UTF-8编码的文本类文件,直接对PDF字节内容做字符串转换或UTF-8解码必然会出现乱码或报错,该操作无意义,直接保留原始
bytes类型即可使用。 - 你接收的
UploadFile是FastAPI封装的文件对象,本身可以直接读取二进制内容,无需转为本地磁盘文件即可被pdfx识别。
解决方案(两种可选)
方案1:直接使用内存字节流(推荐,无磁盘IO开销,性能更高)
直接调整提取函数兼容字节输入,无需落盘存储文件:
import pdfx from fastapi import FastAPI, File, UploadFile app = FastAPI() # 调整后的提取函数,兼容本地路径和字节两种输入格式 def get_hrefs_from_pdf(pdf_source: str | bytes) -> list: if isinstance(pdf_source, str): from os.path import exists if not exists(pdf_source): raise FileNotFoundError("PDF 文件不存在") pdf = pdfx.PDFx(pdf_source) return pdf.get_references_as_dict().get('url', []) @app.post("/file_upload") async def upload_file(pdf: UploadFile = File(...)): # 直接读取二进制内容,无需做编码转换 pdf_bytes = await pdf.read() extracted_urls = get_hrefs_from_pdf(pdf_bytes) return {"filename": pdf.filename, "extracted_urls": extracted_urls}
方案2:写入临时磁盘文件处理(适合大文件场景,避免内存占用过高)
如果业务需要落盘或者处理超大PDF文件,可通过临时文件实现:
import pdfx import os import tempfile from fastapi import FastAPI, File, UploadFile app = FastAPI() # 原有提取函数无需修改 def getHrefsFromPDF(pdfPath:str)->list: from os.path import exists if not(exists(pdfPath)): raise FileNotFoundError("PDF File not Found") pdf = pdfx.PDFx(pdfPath) return pdf.get_references_as_dict().get('url',[]) @app.post("/file_upload") async def upload_file(pdf: UploadFile = File(...)): # 创建自动清理的临时文件 with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_file: tmp_file.write(await pdf.read()) tmp_path = tmp_file.name try: extracted_urls = getHrefsFromPDF(tmp_path) return {"filename": pdf.filename, "extracted_urls": extracted_urls} finally: # 处理完成后删除临时文件 os.unlink(tmp_path)
内容的提问来源于stack exchange,提问作者Shivam Sahil
相关产品推荐
相关产品推荐

