Python 万能文档阅读器逐行讲解

🔒 You must be logged in as an Administrator or Editor to listen to this audio.

Python 万能文档阅读器逐行讲解

我会逐行、逐段用最简单的大白话讲解这段 Python 代码,不跳步、不讲复杂术语,你能完全看懂它是做什么的。

逐行讲解:文档读取器代码

这段代码的核心功能:写一个万能文件阅读器,能自动读 .docx / .pdf / .html / .txt / .md,统一输出文本、表格、图片,还能告诉你读取成功/失败。


1. 顶部:数据结果类 ReadResult


@dataclass
class ReadResult:
    """文档读取结果"""
    content: str
    content_type_hint: str
    metadata: Dict[str, Any]
    success: bool = True
    error: Optional[str] = None
    attachments: List[Dict[str, Any]] = None  # 用于存储提取的图片等附件信息

大白话讲解

  • @dataclass:Python 自带的简易数据盒子,不用写复杂构造函数。
  • ReadResult读取结果模板,不管读什么文件,最后都装进这个盒子。
  • 字段含义:
    • content:读到的文本内容
    • content_type_hint:内容类型(text/html/markdown)
    • metadata:文件信息(路径、大小、名字)
    • success:是否读取成功
    • error:失败原因
    • attachments:提取的图片、附件

2. 主类:DocumentReader


class DocumentReader:
    """
    统一的多格式文档读取器
    支持格式: .docx .pdf .html .htm .txt .md
    """
  • 这是核心类:一个统一的文件阅读器。
  • 支持 6 种常见格式。

3. 支持哪些格式?


SUPPORTED_EXTENSIONS = {
    '.docx': 'docx',
    '.pdf': 'pdf',
    '.html': 'html',
    '.htm': 'html',
    '.txt': 'text',
    '.md': 'markdown',
}
  • 字典:后缀 → 类型
  • 程序靠它判断:这是什么文件?

4. 初始化函数


def __init__(self, attachments_dir: str = "attachments"):
    self.attachments_dir = attachments_dir  # 图片保存文件夹
    self._check_dependencies()             # 检查依赖包有没有装
  • 创建阅读器时,自动:
    1. 设置图片保存目录 attachments
    2. 检查依赖库是否安装(docx、pdf 等)

5. 检查依赖是否安装


def _check_dependencies(self):
    self._docx_available = False
    self._pdfplumber_available = False
    ...

    try:
        import docx
        self._docx_available = True
    except ImportError:
        logger.warning("python-docx 未安装")
  • 作用:检查库有没有装
  • 没装就提示,不会崩溃
  • 支持自动降级读取(用简单方式读)

6. 工具方法:支持哪些后缀?


@classmethod
def supported_extensions(cls) -> List[str]:
    return list(cls.SUPPORTED_EXTENSIONS.keys())
  • 返回支持的文件后缀列表

7. 判断文件是否支持


def is_supported(self, filepath: str) -> bool:
    ext = os.path.splitext(filepath)[1].lower()
    return ext in self.SUPPORTED_EXTENSIONS
  • 取文件后缀
  • 判断是否在支持列表里

8. 核心方法:read() —— 真正读文件


def read(self, filepath: str) -> ReadResult:

这是整个类最重要的方法:你传一个文件路径,它返回 ReadResult。

步骤 1:文件不存在


if not os.path.exists(filepath):
    return ReadResult(..., success=False, error="文件不存在")

步骤 2:获取文件信息


ext = 后缀
filename = 文件名
filesize = 文件大小
doc_id = 文件名(无后缀)

全部放进 metadata

步骤 3:根据后缀选择读取方式


if ext == '.docx':
    content = self._read_docx(filepath)
elif ext == '.pdf':
    优先用 MinerU 高级解析 → 失败就降级
elif ext in ('.html', '.htm'):
    直接读文本
elif ext == '.md':
    直接读文本
else:
    普通文本读取

步骤 4:成功 → 返回结果


return ReadResult(
    content=内容,
    content_type_hint=类型,
    metadata=信息,
    success=True
)

步骤 5:失败 → 捕获异常


except Exception as e:
    return ReadResult(..., success=False, error=str(e))

9. 读取 .docx 文件


def _read_docx(self, filepath: str) -> str:
  • 段落 + 表格原始顺序读取
  • 表格转成 Markdown 格式
  • 保持文档结构

10. 高级读取 PDF(文本 + 表格 + 图片)


def _read_pdf_advanced(...) -> (str, List[Dict]):

功能:

  • 按页提取文本
  • 提取表格 → 转 Markdown
  • 提取图片 → 保存到 attachments/
  • 返回:文本内容 + 图片列表

11. 超高级 PDF 解析:MinerU


def _read_pdf_mineru(...) -> (str, List[Dict]):
  • 使用 AI 模型解析 PDF
  • 输出高质量 Markdown
  • 自动排版、表格、图片
  • 适合复杂排版 PDF

12. 工具函数:表格转 HTML / Markdown


def _list_to_html_table(...):
def _list_to_md_table(...):
  • 把读取到的表格变成网页表格 / Markdown 表格

13. 读取文本文件(万能读)


def _read_text_file(self, filepath: str) -> str:
  • 尝试多种编码:utf-8、gbk、gb2312…
  • 解决中文乱码问题
  • 兜底:无法解码就用 replace 替换,不崩溃

整体流程总结(超级简单版)

你调用:


reader = DocumentReader()
result = reader.read("文件.pdf")

程序内部:

  1. 看文件后缀
  2. 选对应读取器
  3. 读文本、表格、图片
  4. 打包成 ReadResult 返回
  5. 失败就返回错误信息

最终总结(3 句话记住)

  1. ReadResult 是统一的结果格式
  2. DocumentReader 是万能文件阅读器
  3. read() 是入口,自动判断格式、自动读取、自动容错