𝗦𝘁𝗼𝗽 𝗣𝗮𝗿𝘀𝗶𝗻𝗴 𝗣𝗗𝗙𝘀 𝗮𝘁 𝗥𝗲𝗻𝗱𝗲𝗿 𝗧𝗶𝗺𝗲
Most developers build PDF extraction tools the wrong way.
They try to guess document structure from the visual output. They render a page to a canvas and look at pixel positions. They use computer vision to find columns or tables.
This approach is backwards.
A PDF already contains the structure you need in the operator stream.
A table is not just a set of pixels. It is a set of path operators like moveTo, lineTo, and rectangle. Zone boundaries are encoded in the CTM stack. You do not need to reconstruct what is already there.
Stop using visual heuristics. Use the source data.
I previously tried using De Casteljau subdivision for bounding boxes. I rejected it during testing.
De Casteljau is a subdivision algorithm. You split curves until the segments are small enough. This works for rendering, but it is bad for bounding boxes.
You have to choose a tolerance. If the tolerance is too loose, the box is wrong. If it is too tight, you waste resources on recursion. There is a better way. An analytical solution using the quadratic formula is exact. It does not recurse. It does not allocate segments.
The same logic applies to zone detection.
Many tools calculate zone boundaries by finding the midpoint between two text groups. This is a visual guess. It is not structural.
If you use midpoints, sub-pixel rounding will place regions in the wrong zones.
The fix is simple. Use the top edge of the bounding box. A region belongs to a zone based on where it starts. Use the actual Y-coordinate of the top edge.
Building a real PDF extractor is harder. You must:
- Read the operator stream instead of just text content.
- Build a CTM stack to track matrix state.
- Classify subpaths geometrically.
- Emit segments with provenance.
This is more work than pixel-based guessing. But it produces deterministic results.
A pixel-based tool gives different results at 100% zoom than it does at 150% zoom. It is pattern-matching visual artifacts, not extracting structure.
If you do not parse the operator stream, you are building a demo. It might work on your test files, but it will fail on real user uploads.
The path through the operator stream is difficult. You must understand the fill and stroke state machines and the PDF specification. But you only have to learn it once. Then it works for every PDF.
Berhenti melakukan parsing PDF semasa waktu paparan: Seni bina yang lebih baik untuk pengekstrakan berstruktur
Jika anda sedang membina aplikasi yang perlu mengekstrak data daripada dokumen PDF, anda mungkin telah melakukan kesilapan ini: anda melakukan parsing PDF tersebut hanya apabila pengguna meminta untuk melihat atau memprosesnya.
Walaupun pendekatan ini nampak mudah pada mulanya, ia tidak akan berskala (scale) dan akan menyebabkan masalah prestasi yang serius apabila jumlah dokumen anda meningkat.
Masalah dengan Parsing Semasa Waktu Paparan (Render-time)
Pendekatan "parsing mengikut permintaan" (on-demand parsing) biasanya melibatkan aliran kerja seperti ini:
- Pengguna memuat naik atau meminta dokumen.
- Aplikasi memuat turun PDF.
- Aplikasi menjalankan perpustakaan parsing (seperti
PyPDF2,pdfminer, atauunstructured). - Data diekstrak ke dalam memori.
- Data diproses atau dipaparkan kepada pengguna.
Walaupun aliran ini nampak logik, ia mempunyai beberapa kelemahan utama:
1. Latensi yang Tinggi
Proses parsing PDF, terutamanya jika ia melibatkan OCR (Optical Character Recognition) untuk PDF imej, adalah sangat berat. Jika anda melakukan ini semasa pengguna sedang menunggu halaman dimuatkan, mereka akan mengalami kelewatan (latency) yang ketara. Pengalaman pengguna (UX) akan terjejas teruk.
2. Penggunaan Sumber yang Intensif
Parsing PDF memerlukan kuasa CPU dan memori yang tinggi. Jika anda mempunyai beratus-ratus permintaan serentak, pelayan anda akan bergelut untuk mengendalikan beban kerja tersebut, yang akhirnya membawa kepada kos infrastruktur yang lebih tinggi.
3. Kod yang Rapuh (Brittle)
PDF adalah format yang sangat kompleks dan tidak konsisten. Jika anda melakukan parsing secara langsung semasa paparan, sebarang kegagalan dalam proses parsing akan menyebabkan keseluruhan permintaan gagal, dan pengguna akan melihat ralat (error) pada skrin.
Penyelesaian: Seni Bina Berasaskan Pra-pemprosesan
Daripada melakukan parsing semasa waktu paparan, anda sepatutnya mengalihkannya ke fasa pra-pemprosesan. Matlamatnya adalah untuk menukar PDF yang tidak berstruktur kepada data berstruktur (seperti JSON) sebelum ia diperlukan oleh pengguna atau sistem lain.
Berikut adalah seni bina yang lebih baik:
Aliran Kerja Cadangan:
- Penerimaan (Ingestion): Dokumen PDF dimuat naik ke dalam storan (contohnya, AWS S3).
- Talian Paip Pemprosesan (Processing Pipeline): Satu tugasan latar belakang (background job) dicetuskan secara asinkronus.
- Parsing & OCR: Gunakan alat seperti
Tesseract,AWS Textract, atauAzure Form Recognizeruntuk mengekstrak teks dan struktur. - Pengekstrakan Berstruktur (Structuring): Gunakan LLM (seperti GPT-4) atau logik heuristik untuk menukar teks mentah kepada format JSON yang bersih.
- Penyimpanan (Storage): Simpan hasil JSON tersebut dalam pangkalan data (contohnya, PostgreSQL atau MongoDB).
- Paparan (Rendering): Apabila pengguna meminta data, aplikasi hanya perlu mengambil JSON yang sudah siap daripada pangkalan data. Ini adalah operasi yang sangat pantas.
Perbandingan: On-Demand vs. Pra-pemprosesan
| Ciri-ciri | Parsing Semasa Waktu Paparan | Parsing Pra-pemprosesan |
|---|---|---|
| Latensi Pengguna | Tinggi (Menunggu proses selesai) | Sangat Rendah (Hanya ambil data) |
| Skalabiliti | Sukar (Beban CPU tinggi semasa permintaan) | Mudah (Boleh dikendalikan secara asinkronus) |
| Kebolehpercayaan | Rendah (Ralat parsing menjejaskan UX) | Tinggi (Data sudah disahkan sebelum digunakan) |
| Kos Infrastruktur | Tidak menentu (Spiky) | Lebih stabil dan boleh diramal |
Kesimpulan
Jangan biarkan proses parsing yang berat menghalang prestasi aplikasi anda. Dengan mengalihkannya daripada waktu paparan kepada saluran paip pra-pemprosesan, anda bukan sahaja meningkatkan kelajuan aplikasi, tetapi juga membina sistem yang lebih teguh dan boleh diskala.
Ingat: Simpan data dalam bentuk yang paling berguna, bukan dalam bentuk yang paling mentah.