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

如何在StreamLit中使用PyPDFLoader处理上传的PDF并保留页码?

问题:Streamlit上传PDF使用PyPDFLoader报错且需保留页码信息

我基于StreamLit构建PDF文档读取Web应用,使用langchain.document_loaders.PyPDFLoader加载上传的PDF时触发如下错误:

TypeError: stat: path should be string, bytes, os.PathLike or integer, not list

错误堆栈信息:

File "/opt/homebrew/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 552, in _run_script
    exec(code, module.__dict__)
File "/Users/shuhulhandoo/MetaGeeks/PDF-URL_QA/app.py", line 133, in <module>
    main()
File "/Users/shuhulhandoo/MetaGeeks/PDF-URL_QA/app.py", line 75, in main
    loader = PyPDFLoader(pdf)
             ^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/langchain/document_loaders/pdf.py", line 92, in __init__
    super().__init__(file_path)
File "/opt/homebrew/lib/python3.11/site-packages/langchain/document_loaders/pdf.py", line 42, in __init__
    if not os.path.isfile(self.file_path) and self._is_valid_url(self.file_path):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen genericpath>", line 30, in isfile

我的上传代码逻辑:

import streamlit as st
from langchain.document_loaders import PyPDFLoader

uploaded_file = st.file_uploader("Upload PDF", type="pdf")
if uploader_file is not None:
    loader = PyPDFLoader(uploaded_file)

我需要保留页码等文档源信息,之前尝试用PyPDF2的PdfReader逐页提取文本,但会丢失页码信息,求解决办法。


解决方案

核心问题原因

PyPDFLoader仅接受文件路径字符串作为参数,但Streamlit的st.file_uploader返回的是UploadedFile类文件对象,并非本地文件路径,直接传入会触发类型错误。

方法1:临时保存上传文件再加载

将上传的UploadedFile保存到本地临时文件,再用PyPDFLoader加载该文件路径,既能满足参数要求,又能保留页码元数据:

import streamlit as st
from langchain.document_loaders import PyPDFLoader
import tempfile
import os

uploaded_file = st.file_uploader("Upload PDF", type="pdf")

if uploaded_file is not None:
    # 创建临时PDF文件,写入上传内容
    with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
        tmp_file.write(uploaded_file.getbuffer())
        tmp_file_path = tmp_file.name
    
    # 加载临时文件并提取带页码的内容
    loader = PyPDFLoader(tmp_file_path)
    document_pages = loader.load()
    
    # 验证页码信息:每个Document对象的metadata包含page_number
    for page in document_pages:
        st.subheader(f"页码: {page.metadata['page_number']}")
        st.write(page.page_content[:500])  # 显示每页前500字符
    
    # 清理临时文件,避免磁盘占用
    os.unlink(tmp_file_path)

方法2:使用支持类文件对象的PyPDFium2Loader(无需临时文件)

LangChain的PyPDFium2Loader支持直接传入UploadedFile对象,无需保存临时文件,需先安装依赖:

pip install pypdfium2

代码示例:

import streamlit as st
from langchain.document_loaders import PyPDFium2Loader

uploaded_file = st.file_uploader("Upload PDF", type="pdf")

if uploaded_file is not None:
    loader = PyPDFium2Loader(uploaded_file)
    document_pages = loader.load()
    
    # 遍历并展示带页码的内容
    for page in document_pages:
        st.subheader(f"页码: {page.metadata['page_number']}")
        st.write(page.page_content[:500])

两种方法生成的Document对象都会在metadata字段中包含page_number,满足保留页码信息的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:07:02