PDF’yi parse etmek mi istiyorsunuz?
(eliot-jones.com)- PDF ayrıştırma, net bir sıra ve yapı temelinde çalışmalıdır; ancak gerçek dosyalar çoğu zaman bu kurala uymaz
- cross-reference (xref) işaretçileri ve ofsetlerin bulunması sırasında çeşitli hatalar ve tutarsızlıklar ortaya çıkar
- Pratikte birçok sorun, PDF başlığından önceki gereksiz veriler ya da işaretçi ve ofsetlerin yanlış konumlanması nedeniyle oluşur
- PDF xref tablosunun kendisinin belirsiz veya hatalı biçimlendirilmiş olduğu pek çok durum da vardır
- Bu yüzden başlıca görüntüleyiciler, standart dışı PDF dosyalarını da destekleyen ek mantıklar uygular
PDF ayrıştırmaya ideal yaklaşım
- PDF ayrıştırma teorik olarak belirli adımlarla ilerler
- Dosyanın başlangıcında sürüm başlığı yorumunu bulur
- cross-reference (xref) işaretçisini bulur
- Tüm nesne ofsetlerini toplar
- trailer sözlüğünü bularak genel katalog yapısına erişir
PDF nesnelerine giriş
- PDF nesneleri, sayı, string, sözlük gibi çeşitli PDF öğelerini sarmalayıp saklayan birimlerdir
- Her nesne,
obj/endobjişaretleri arasında bulunur - Nesneler, dolaylı referans (indirect reference, ör.
16 0 R) yöntemiyle birbirine bağlanır - Dosya içindeki nesne bölümlenmesi serbesttir; ancak bazı nesne türleri mutlaka dolaylı referans olmalıdır
cross-reference ofsetlerini bulma
- PDF yapısında, nesne konumları için bir indeks görevi gören cross-reference (xref) tablosu bulunur
- Dosyanın sonunda
startxrefifadesiyle belirli bir bayt konumu işaretçi olarak belirtilir - Bu işaretçi xref konumunu gösterir; ancak spesifikasyon ile gerçek dosyalar arasında farklar vardır. Örneğin
%EOFişaretinin aslında son satırda olması gerekirken, gerçek PDF’lerde son 1.024 bayt içindeki herhangi bir yerde olabilir - Gerçek dosyalarda işaretçi biçim hataları (
startrefvb.), satır sonu eksikliği gibi çeşitli varyasyonlar görülür
nesne ofsetlerini bulma
- xref tablosunda sırasıyla
xref, nesne başlangıç numarası ve nesne sayısı yer alır; her nesnenin ofseti/oluşturma numarası/durumu (nveyaf) bir satıra yazılır - Birden fazla xref tablosu olabilir ya da bunlar
/Prevgirdisi üzerinden birbirine bağlanabilir
trailer sözlüğünün konumunu arama
startxrefişaretinin üst tarafında trailer sözlüğü bulunur ve kök nesneyi bulmak için gerekli temel meta verileri içerir- Kök nesne temel alınarak tüm yapının yorumlanmasına başlanabilir
Gerçek dünya: beklenmedik sorunlar
-
PDF spesifikasyonuna uymayan çok sayıda dosya bulunduğundan, genel amaçlı ayrıştırıcılarla bunları işlemek zordur
-
cross-reference işaretçisi aramasında sık görülen başarısızlık durumları
- İşaretçi dosya sonunda veya son 1.024 bayt içinde değildir
- Yazım hataları (
startrefvb.) - İstisnai biçimler
-
3.977 gerçek PDF örneği üzerinde yapılan incelemede, yaklaşık %0,5’inde xref bildirimi hatası bulundu
PDF içeriği sıfır olmayan bir ofsette başlıyor
- Başlıktan önce gereksiz veri (junk) varsa, tüm bayt ofsetleri kayar ve
startxrefkonumu bozulur - Ofsetler başlığın konumuna göre yeniden hesaplanmalı ve her iki konum da kontrol edilmelidir
- Bu durum tüm hataların yaklaşık %50’sini oluşturur
xref işaretçisi xref tablosunun ortasını gösteriyor
- Belirtilen ofset bazen xref tablosunun tam ortasına da denk gelebilir
- 3.977 örnekten yaklaşık 5’inde görülmüştür
İşaretçi xref’in yakınında
- Çoğu zaman işaretçi tam doğru değildir; ancak xref’in hemen öncesi veya sonrasındaki boşluk ya da satır sonu karakteri farkı kadar kaymıştır
İşaretçi doğru ama xref ofseti yanlış
- xref tablosuna yazılmış ofsetlerin kendisi de hatalı olabilir
- Bazı nesneler doğruyken geri kalanlar ofset hatası içerebilir
İlk işaretçi normal ama önceki ofset (/Prev) sorunlu
- PDF düzenlenirken oluşan
/Previşaretçisinde hatalı değerlerin (ör.0) saklandığı çok sayıda örnek vardır
xref tablosu anormal biçimde
- Satır sonu olmadan
xrefile sayıların bitişmesi, bildirilen nesne sayısından fazla giriş bulunması veya tablonun ortasında çöp veri yer alması gibi farklı durumlar görülebilir - Bu tür örnekler PdfPig gibi projelerde issue olarak sıkça raporlanmıştır
Sonuç
- Spesifikasyona göre PDF ayrıştırma standart bir sırayla yapılmalıdır; ancak gerçek dosyaların çoğu böyle olmadığından ayrıştırma sırasında çeşitli sorunlar ortaya çıkar
- Gerçek kullanımda PDF görüntüleyicileri, standart dışı PDF desteğini genişleten özellikleri temel olarak içerir
- Bu özet, PDF spesifikasyonunun (toplam 1300 sayfanın 22 sayfasına karşılık gelen) yalnızca küçük bir ayrıştırma bölümünü ele aldı
5 yorum
Bu özet içeriği, PDF spesifikasyonunun (toplam 1300 sayfanın 22 sayfası) yalnızca küçük bir kısmının parse edilmesini ele alıyordu <- ... 1300 sayfa gerçekten korkutucu derecede büyük...
Vay..
PDF, dürüst olmak gerekirse, insanların oluşturduğu biçimi mümkün olduğunca koruyan, insanların okuması için uygun bir format; makinelerle ise uyumu berbat.
Katılıyorum. Aslında okunmasının ne kadar kolay olduğundan da emin değilim.. Fazla ağır ve kullanışsız.
Hacker News görüşü
Cevap açık
Gerçekte ise benim adım Geoff ve özgeçmiş parser’larının yarısı adımı ayrı ayrı "Geo" ve "ff" olarak algılıyor
Bunun nedeni metnin PDF içine yerleştirilme biçimi ve farklı kaynak uygulamalarda sürekli görülen bir sorun olması
PDF parse etmek ile PDF içeriğini parse etmek tamamen farklı şeyler
PDF dosyasını parse etmek zaten başlı başına zahmetli ama PDF’nin kendisi temelde "belirli bir konuma bir şey bas" mantığıyla çalıştığı için, iyi tanımlanmış sınır kutuları içindeki metinden farklı olarak bir kelimeyi çıkarmak için hangi karakterlerin birlikte olduğunu tahmin etmek gerekiyor
Özgeçmiş parser’larına yardımcı olmak istiyorsanız erişilebilirlik ağacına (Accessibility tree) bakmak mantıklı olabilir
Her PDF renderer erişilebilir PDF üretmiyor ama erişilebilir PDF en azından isim gibi şeylerin daha doğru okunmasına yardımcı olabilir
"ff" sorunu muhtemelen özgeçmiş analizcisinin ASCII dışı karakterleri (ör. ff ligatürü) işleyememesinden kaynaklanıyor
PDF renderer’ı ligatür üretmeyecek şekilde ayarlamak mümkün ama bu kez metin çirkin görünebilir
Burada "should" kelimesinden çok şey bekleniyor gibi geliyor
PDF kullanımı pratikte epey düşmanca olduğunda insanlar bu kadarını düşünmüyor gibi
Özgeçmişi PDF olarak göndermenin amacı zaten aradaki aracıların kolayca değiştirememesi; ayrıca "düzenleme" de görüntü üstüne kutu çizip kapatma ya da tabloları CSV yerine PDF yapıp analiz edilmesini zorlaştırma gibi pek çok nedenle yapılıyor
Bu yaklaşımın gerçekten iyi çalıştığı durumlar var; bazı uygulamalar bunu kullanıyor
Yine de iki gösterimin (gövde/metadata) pratikte birebir örtüşmemesi sorunu kalıyor
El yazısı taramaları veya diğer taranmış belgelerde ne olacak; tarayıcılar ve sıradan ev bilgisayarları kusursuz OCR desteği sunmuyorsa ne yapılacak sorusu var
Muhtemelen sorun
ff’nin ligatür olarak render edilmesinden kaynaklanıyorTensorlake’in kurucusuyum
Geliştiriciler için bir belge parsing API’si yaptım
PDF parsing’de Computer Vision yaklaşımının sahada gerçekten işe yaramasının nedeni bu
Dosya içindeki metadata’ya güvenmek, çok çeşitli PDF kaynaklarında ölçeklenebilir değil
Bu yüzden PDF’yi görüntüye çevirip önce layout algılama modeli uyguluyor, ardından metin ve tablo tanıma gibi uzmanlaşmış modeller çalıştırıp parçaları birleştirerek doğruluğun kritik olduğu alanlarda bile kullanılabilir sonuçlar elde ediyoruz
Bu yaklaşım ilk bakışta biraz komik görünse de aslında en gerçekçi çözüm gibi
PDF özünde insanların okuyacağı bir düzeni ifade etmek için tasarlanmış bir format; bilgisayarların okuması için değil, güzel görünen bir gösterime odaklı
Bu yüzden insanın okuma biçimini taklit eden bir yaklaşım mantıklı geliyor
Yine de 30 yılı aşkın sürede PDF’ye makinece okunabilirliğin tam anlamıyla eklenememiş olması üzücü
Bunu mümkün kılacak teşvik ne eksikti diye merak ediyorum
Bu konuda fikri olan varsa duymak isterim
Biraz komik gerçekten
PDF’yi yazdırıp tarayıp e-postayla göndermekle dalga geçiyoruz ama PDF parsing’de fiilen aynı şeyi yapıyoruz
Böyle bir yaklaşıma ihtiyaç duyulması sinir bozucu bir gerçek
Dünya HTML’i böyle parse etmiyor
Nutrient.io’nun kurucu ortaklarından biriyim, 10 yılı aşkın süredir PDF ile uğraşıyorum
Tıpkı web tarayıcıları gibi PDF görüntüleyicilerin de çok geniş çeşitlilikte PDF’leri kabul etmesi gerekiyor
PDF çok eski olduğu için dosya üreticileri genelde yalnızca kendi kullandıkları görüntüleyicide düzgün görünmesini sağlayacak şekilde rastgele oynamalar yapıyor
Bu nedenle şirketimiz bir yapay zeka belge işleme SDK’sı geliştirdi (REST API; PDF veriyorsunuz, yapılandırılmış veriyi JSON olarak döndürüyor)
Sadece görsel yöntemlere değil, yapısal ön işleme/son işleme deneyimine de dayandığımız için saf görsel tabanlı yaklaşımlara göre hem performans hem maliyet açısından daha iyi sonuç veriyoruz
PDF işleme derdiyle doğrudan uğraşmak istemiyor ve asıl işinize odaklanmak istiyorsanız yardımcı olabiliriz
https://www.nutrient.io/sdk/ai-document-processing
Madem burada PDF iç yapısı uzmanları var, bir sorum var
Neden
mupdf-gl(varsayılan masaüstü Linux bağlamında) diğer tüm programlardan çok daha hızlı diye merak ediyorumBüyük PDF’lerde arama hızı bariz şekilde üstün; diğer görüntüleyiciler neden bu kadar hızlı olamıyor diye hep düşünmüşümdür
Bu konuda içgörüsü olan varsa duymak isterim
Sonuçta parsing işini, PDF’yi görüntüye render ederken kullanılan yazılıma outsource etmiş oluyorsunuz
Uzun zamandır düzen odaklı belge iletişiminden uzaklaşmamız gerektiğini düşünüyorum
Yani profesyonelce hazırlanmış sayfa düzeninin kendisi aslında eski bir geleneğe daha yakın ve içeriğin gerçekten anlaşılmasıyla neredeyse hiç ilgili değil
Örneğin çeşitli düzenleyici kurumlara yapılan başvurular son derece kalın belgeler ve düzen kurallarına uymak için Microsoft Word içinde uzun zaman harcanıyor
Bu düzen güvencesi için belgeler DOCX veya PDF olarak teslim ediliyor ama bu formatlar programların içeriği otomatik çıkarıp işlemesi için çok elverişsiz
LLM’ler bu dosyaları okuyabiliyor ama basit makine dostu dosyalara (text, markdown, XML, JSON vb.) kıyasla hesaplama maliyeti çok daha yüksek
Alternatif olarak baştan "önce makine", "önce içerik" yaklaşımıyla basit bir formatı (JSON, XML, HTML tabanlı vb.) standartlaştırma ihtimalini düşünüyorum
İçinde yalnızca asgari yapı ve görsel gömme bilgisi olur; insan okuyacağı zaman görüntüleyici uygulama bunu hoş bir görünüme dönüştürür
Makine işlemesi çok daha kolay olur
Zaten HTML/tarayıcı, EPUB gibi benzer formatlar var ama artık klasik yaklaşımın yerini alacak bir şeye ihtiyaç olduğunu düşünüyorum
Umarım LLM devrimi bizi bu yöne iter ve pahalı PDF parsing gelecekte sadece eski bir boru hattı olarak kalır
Henüz bir DOCX parser’ı yazmadım ama DOCX XML tabanlı, ayrıca açıkça layout belirtilmedikçe her şey mutlak koordinatlara dökülmüyor; bu yüzden JPEG 0 puan, PDF 15 puan, markdown 100 puansa DOCX yaklaşık 80 puanlık bir kolaylık seviyesinde değil midir diye tahmin ediyorum
Bunun harika bir özet olduğunu düşünüyorum; ayrıca ilginç bulduğum ek bir nokta var
Incremental-save zinciri: ilk
startxrefofseti tamam ama Acrobat art arda düzenlemeler yaptıkça eklediği/Prevbağlantıları çoğu zaman bir sonraki xref’e birkaç bayt kısa işaret ediyorÇoğu görüntüleyici (
PDF.js, MuPDF, hatta Adobe Reader) bu durumda tüm dosyada kaba kuvvetleobjtoken’ını arayıp yeni tabloyu yeniden kuruyor; spesifikasyona sıkı bağlı parser’lar ise patlıyorSahada farklı uygulamalar tarafından tekrar tekrar düzenlenmiş belgeleri işlemek istiyorsanız bu tür recovery path zorunlu
Önceki referanslardan biri ya da zincirdeki bir halka, dosya dışındaki bir ofsete, 0 ofsetine ya da yanlış bir değere işaret ediyor olabiliyor
Bu yazıyı yazmamın nedeni, kendi projem PdfPig’de ilk parsing mantığını elden geçiriyor olmamdı
Başta Java PDFBox kodunu port etmiştim ama daha hızlı ve daha sade bir şeye çevirmek istedim
Yeni mantık, tek bir xref tablosu/stream kaçırırsa tüm dosyayı tarıyor ve recovery path’te yalnızca ilgili ofsetlere güveniyor
Ama bu önceye göre belirgin şekilde daha yavaş oldu ve değişikliğin gerçekten doğru olup olmadığından emin değilim
10 bin dosyalık bir test setiyle türlü edge case’leri tarıyorum
https://github.com/UglyToad/PdfPig/pull/1102
İyi çalışan varsayımlarınız ve düzgün bir PDF object parser’ınız varsa kolay gibi görünebilir ama gerçekte kesinlikle öyle değil
Bu durum resmen PDF cehennemi
PDF bir spesifikasyon değil, toplumsal bir uzlaşı, adeta bir "vibe"
Debelendikçe daha derine batıyorsunuz ve artık hepimiz Tanrı’nın görüş alanından uzakta bir bataklıkta yaşıyor gibiyiz
Buna güldüm
"PDF parse etmek istiyor musun" sorusuna cevabım kesin bir hayır
Nedeni ana yazıda gayet iyi açıklanmış
Keşke bankam belgeleri daha okunabilir bir formatta verse ama o zamana kadar yapacak bir şey yok
Ben o hatayı bir kez yaptım, bir daha asla yapmam
PDF parser yazmış biri olarak PDF’nin gerçekten tuhaf bir format olduğunu düşünüyorum
Bunun nedeni muhtemelen hem binary hem text karışımı olan doğuştan tasarımı
Biraz kayık xref ofsetleri gibi tuhaflıkların da LF/CR satır sonu dönüşümlerindeki bug’lardan kaynaklandığını tahmin ediyorum
Yazıda değinilmeyen şeylerden biri de modern PDF’lerin (
v1.5+) çoğunlukla düz metin xref tablosu yerine bir "xref stream" içermesiv1.6+ile object’lerin kendisi de object stream içine konabiliyorSorunsuz görünürken bir anda istediğiniz object’in bir stream’in içinde olduğunu, o stream’in kendisinin PNG sıkıştırmasının türevi bir şey kullandığını ya da ofsetin flate sıkıştırılmış bir xref stream’in içinde yer aldığını görebiliyorsunuz; o noktada işler can sıkıcılaşıyor
Üstelik birden fazla belge sürümü iç içe geçmiş durumda olduğu için nereden sonrasının güncel olduğunu anlamak da karmaşık
PDF 1.7 belgelerini bulmak kolay ama daha 2 yıl öncesine kadar PDF 2.0 spesifikasyonu ücret duvarının arkasındaydı
PDF, streaming düşünülerek tasarlanmış bir format değil
Sondaki trailer dictionary nedeniyle dosyanın tamamı yüklenmeden parse etmek zorlaşıyor
Yine de "streaming yapılabilir PDF" diye bir şey var; gerekli bilgi baş kısımda yer alıyorsa ilk sayfa hemen render edilebiliyor (geri kalanı olmayabilir)
PDF dünyasından biraz uzak kaldım, o yüzden bunu hesaba katın
Dipte footer olsa bile web sitesi Range Request destekliyorsa ve
Content-Lengthbaşlığını düzgün veriyorsa PDF de streaming ile kullanılabilirBir streaming reader, önce
HEADisteği yapar, sonra dosyanın son birkaç yüz baytını isteyip pointer ve tabloyu bulur, ardından kalan kısımları almaya devam ederGerçek zamanlı üretilen PDF’ler için uygun değil ama epey eski web sunucularında bile 1-2 ek RTT genelde yeterli olur
Ne yazık ki dosya başına Range tabanlı parser’larla ilgilenen pek örnek yok ama teknik olarak imkânsız değil
Evet,
Linearized PDFdenen bir format var; tüm dosya inmeden ilk sayfanın hızlı gösterilebilmesi için tasarlanmışÖzetimde bunun çok fazla ek açıklama gerektirdiği için bu kısmı atladım
Python öğrenirken ilk denediğim projelerden biri PDF parser yazmaktı
DnD kampanyası için haritaları otomatik çıkarmayı hedefliyordum ama sonuç tam bir fiyaskoydu (gülüyor)
Bir zamanlar TIFF reader yazmıştım
TIFF de yazması kolay ama okuması zor olduğu için kötü şöhretlidir
PDF de aynı sınıfa giriyor gibi görünüyor