MCPcopy Create free account
hub / github.com/bcefghj/ai-agent-interview-guide / DocumentParser

Class DocumentParser

project-python/app/etl/parser.py:22–74  ·  view source on GitHub ↗

文档解析器:支持纯文本与 PDF(pypdf)。

Source from the content-addressed store, hash-verified

20
21
22class DocumentParser:
23 """文档解析器:支持纯文本与 PDF(pypdf)。"""
24
25 def __init__(self, max_chars: int = 500_000) -> None:
26 self._max_chars = max_chars
27
28 def parse_file(self, path: Path, mime_type: str | None = None) -> ParsedDocument:
29 """从文件路径解析。"""
30 mime = mime_type or "application/octet-stream"
31 suffix = path.suffix.lower()
32 if suffix == ".txt" or mime.startswith("text/"):
33 raw = path.read_text(encoding="utf-8", errors="ignore")
34 return ParsedDocument(text=raw[: self._max_chars], mime_type=mime, meta={})
35
36 if suffix == ".pdf" or mime == "application/pdf":
37 return self._parse_pdf(path.read_bytes(), mime)
38
39 logger.warning("未知类型,按二进制忽略解析 path={}", path)
40 return ParsedDocument(text="", mime_type=mime, meta={"warning": "unsupported"})
41
42 def parse_bytes(self, data: bytes, filename: str, mime_type: str | None) -> ParsedDocument:
43 """从内存字节解析。"""
44 mime = mime_type or "application/octet-stream"
45 lower = filename.lower()
46 if lower.endswith(".txt") or (mime.startswith("text/") and mime != "text/html"):
47 text = data.decode("utf-8", errors="ignore")
48 return ParsedDocument(text=text[: self._max_chars], mime_type=mime, meta={})
49
50 if lower.endswith(".pdf") or mime == "application/pdf":
51 return self._parse_pdf(data, mime)
52
53 return ParsedDocument(text="", mime_type=mime, meta={"warning": "unsupported"})
54
55 def _parse_pdf(self, data: bytes, mime: str) -> ParsedDocument:
56 """使用 pypdf 抽取文本。"""
57 try:
58 from pypdf import PdfReader
59 except ImportError as exc:
60 logger.exception("未安装 pypdf: {}", exc)
61 raise
62
63 import io
64
65 reader = PdfReader(io.BytesIO(data))
66 parts: list[str] = []
67 for page in reader.pages:
68 try:
69 parts.append(page.extract_text() or "")
70 except Exception as exc:
71 logger.warning("单页 PDF 抽取失败: {}", exc)
72
73 text = "\n".join(parts)[: self._max_chars]
74 return ParsedDocument(text=text, mime_type=mime, meta={"pages": str(len(reader.pages))})

Callers 1

__init__Method · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected