🔒 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() # 检查依赖包有没有装
- 创建阅读器时,自动:
- 设置图片保存目录
attachments - 检查依赖库是否安装(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")
程序内部:
- 看文件后缀
- 选对应读取器
- 读文本、表格、图片
- 打包成
ReadResult返回 - 失败就返回错误信息
最终总结(3 句话记住)
- ReadResult 是统一的结果格式
- DocumentReader 是万能文件阅读器
- read() 是入口,自动判断格式、自动读取、自动容错