Everyone's PDF summarizer demo uses a clean, text-based PDF. Then real files show up: an EPUB e-book, a .pptx deck, a folder of scanned JPGs. Each needs a different extractor before you can send anything to an LLM. Here's a practical, format-by-format guide to getting clean text out of messy documents in Python.
The rule of thumb: the summary is only as good as the text you extract. Garbage in, garbage summary.
The general pipeline
detect format → extract text (format-specific) → normalize → chunk → summarize
The only step that changes per format is extraction. Let's cover the four that trip people up.
PDFs (the baseline)
Native PDFs are easy with pypdf:
from pypdf import PdfReader
def from_pdf(path: str) -> str:
reader = PdfReader(path)
return "\n".join((page.extract_text() or "") for page in reader.pages)
If this returns almost nothing, the PDF is scanned — jump to the images section for OCR.
EPUB e-books
EPUB is basically zipped XHTML. Use ebooklib to walk the documents and BeautifulSoup to strip tags:
# pip install EbookLib beautifulsoup4
from ebooklib import epub, ITEM_DOCUMENT
from bs4 import BeautifulSoup
def from_epub(path: str) -> str:
book = epub.read_epub(path)
chapters = []
for item in book.get_items_of_type(ITEM_DOCUMENT):
soup = BeautifulSoup(item.get_content(), "html.parser")
chapters.append(soup.get_text(separator="\n"))
return "\n\n".join(chapters)
Gotcha: books are long. Don't send a whole novel in one call — chunk it and use map-reduce, or summarize chapter by chapter (each XHTML item is usually a chapter).
PowerPoint (.pptx)
The trap with decks is that meaning hides in speaker notes, not just slide text. python-pptx reads both:
# pip install python-pptx
from pptx import Presentation
def from_pptx(path: str) -> str:
prs = Presentation(path)
out = []
for i, slide in enumerate(prs.slides, start=1):
out.append(f"--- Slide {i} ---")
for shape in slide.shapes:
if shape.has_text_frame:
out.append(shape.text_frame.text)
# speaker notes — the part most tools skip
if slide.has_notes_slide:
notes = slide.notes_slide.notes_text_frame.text
if notes.strip():
out.append(f"[Notes] {notes}")
return "\n".join(out)
Note what this won't get: text baked into images or charts on a slide. For those you'd need OCR on a rendered slide image.
Images and scanned pages (OCR)
For JPG/PNG or image-only PDFs, run OCR with Tesseract:
# pip install pytesseract pillow (needs the tesseract binary installed)
import pytesseract
from PIL import Image
def from_image(path: str) -> str:
return pytesseract.image_to_string(Image.open(path))
OCR output is noisy — collapse repeated whitespace and expect the odd misread before you summarize.
Wiring it together
from pathlib import Path
EXTRACTORS = {
".pdf": from_pdf,
".epub": from_epub,
".pptx": from_pptx,
".jpg": from_image,
".jpeg": from_image,
".png": from_image,
}
def extract(path: str) -> str:
ext = Path(path).suffix.lower()
if ext not in EXTRACTORS:
raise ValueError(f"No extractor for {ext}")
text = EXTRACTORS[ext](path)
return " ".join(text.split()) # normalize whitespace
Now extract() feeds the same chunk → summarize step regardless of format. Add your LLM call of choice after this.
Effort vs. payoff
| Format | Library | Main gotcha |
|---|---|---|
| PDF (native) | pypdf | Empty output = scanned, needs OCR |
| EPUB | EbookLib + BeautifulSoup | Very long; chunk by chapter |
| PPTX | python-pptx | Don't forget speaker notes; misses image text |
| Images / scans | pytesseract | Noisy output; install tesseract binary |
When it's not worth maintaining
If format support is core to your product, build and own the extractors above. But if you occasionally need to summarize a random EPUB or deck, maintaining four libraries (plus a Tesseract install) to reinvent a file upload is a lot. A free no-code tool that already accepts all these formats is the pragmatic escape hatch: ChatPDF and NotebookLM handle common docs if you have an account, and PDFSummarizer.net takes 14 formats — PDF, EPUB/FB2/MOBI, PPTX, images and more — with no sign-up. The developer catch: it's a browser tool with no public API, so it can't go in a pipeline. Build the extractors when you need automation; use a ready tool when you don't.
Takeaways
- Extraction, not the LLM, is where document summarization actually breaks.
- Each format needs its own extractor:
pypdf,EbookLib,python-pptx,pytesseract. - For decks, always grab the speaker notes.
- Normalize whitespace before chunking.
- Don't maintain four parsers for an occasional job — that's what no-code tools are for.
What formats have given you the most trouble? Drop your extraction horror stories in the comments.
Tool details were accurate at the time of writing — check current limits before you rely on them.
Top comments (0)