Apache Tika, Apache Software Foundation’ın belge ayrıştırma aracıdır: Neredeyse her türden bir dosya verirsiniz, size düz metinle birlikte normalize edilmiş bir metadata sözlüğü döner. Proje README’si binin üzerinde desteklenen dosya türü sunduğunu söylüyor. Tika bunu, uzman kütüphaneleri kendi içinde paketleyerek başarır — PDF’ler için PDFBox, Office belgeleri için Apache POI, HTML için jsoup, ODT için bir ODF okuyucu — böylece çalışma anında hiçbir şey indirmeden tek bir büyük jar olarak gelir. Bir veri hattında o, pek gösterişli olmayan ilk adımdır: Arama indeksinin, e-discovery inceleme setinin ya da bir LLM korpusunun önünde duran; dağınık dosya yığınını tek biçimli hale getiren bileşen. Aslında iki işi vardır: Bir bayt akışının ne olduğunu anlamak ve ardından içinden metinle metadata’yı çıkarmak.
Uzun zamandır kurduğum en zahmetsiz araç oldu. Tek bir jar, java -jar tika-app-3.3.2.jar --text file.pdf, config dosyası yok, model ağırlığı yok, kurulum sonrası ekstra adım yok; aynı makinede öğleden sonra diğer Java araçlarını durduran en güncel bir JDK üzerinde de sorunsuz çalıştı. Yine de katalog iddiasını test etmek istemedim; test edilebilir soru daha dar: Girdi sizi yanıltmaya çalıştığında Tika gerçekte ne yapıyor? Bu yüzden, her içerik bloğuna benzersiz bir işaretleyici token koyduğum kontrollü bir fixture seti oluşturdum, aynı mantıksal belgeyi dokuz farklı kapsayıcı formata render ettim ve ardından tümünü yanlış uzantılarla, eksik uzantılarla, tamamen isimsiz dosyalarla, sıfır baytlık dosyalarla ve yarım yazılmış ikili dosyalarla sınadım.
İlginç davranışın asıl yaşandığı yer tespittir. Bir PDF’i .txt olarak yeniden adlandırıp Tika’ya ne olduğunu sordum; application/pdf dedi. Sonra dosya adını tamamen silip ham baytları stdin üzerinden verdim, yine aynı yanıtı aldım. Küme içindeki içeriğe göre algılanabilen beş formatın tamamında bu durum, 20 benzersiz mantıksal koşulun 20’sinde geçerliydi: Her format için üç dosya adı koşulu artı bir dosya adı olmayan akış koşulu. Harness, akış durumunu farklı etiketler altında üç kez çalıştırdı ve 30 başarılı ham yürütme üretti; ancak bu tekrarlar bağımsız kanıt sayılmaz. PDF ve RTF tanınabilir baytlar açığa çıkarır; DOCX kapsayıcısından anlaşılır; HTML ve XML ise markup ya da kök içerikten ayırt edilebilir. Farklı mekanizmalar, aynı faydalı sonuç: bu fixture setinde uzantı içeriğin önüne geçemedi. Sonra metin ailesi tarafı var; Markdown, dosya adı yanlış olduğunda ya da tamamen kaybolduğunda bir anda text/plaine düşüyor. Burada kimliği bütünüyle .md uzantısına bağlıydı.
Sonrasında gelen her sayı için iki sınır var. Apache Tika 3.3.2 sürümünü test ettim — 27 Temmuz 2026 itibarıyla hâlâ en yeni kararlı sürümdü; 4.0.0 hattı Maven Central’da yalnızca alfa ve beta derlemeleri olarak mevcut. Proje, 27 Temmuz 2026’da baktığımda yaklaşık 3.9 bin GitHub yıldızına sahipti ve Apache-2.0 lisanslıydı; ticari açıdan mümkün olan en az sorun çıkaran lisanslardan biri. Ayrıca OCR’ı hiç test etmedim. Ne taranmış bir sayfa, ne de yalnızca görüntü içeren bir PDF. Bu makinede Tesseract ve poppler kurulu değildi, dolayısıyla OCR yolunun önü daha başlamadan kesilmişti. Burada OCR’a dair hiçbir sayı yok; çünkü OCR’a dair hiçbir sayı yok, bu kadar net.
Kutunun üstündeki pazarlamayı okumayı bırakınca Tika aslında nedir?
Yaygın varsayım, Apache Tika’nın bir belge dönüştürücü olduğu yönünde: DOCX verirsiniz, başlıklar ve tablolar yerli yerinde temiz Markdown alırsınız. Oysa Tika bu değildir; bunu erken fark etmek aracı daha iyi gösterir.
Burada test edilen akış üç ilgili aşamadan oluşuyor: bir içerik türü algılayıcısı, baytları doğru ayrıştırıcıya yönlendiren bir dispatcher, ve CLI’nın --text çıktı işleyicisi; bu işleyici düz metin üretirken metadata’yı ayrıca sunuyor. Bu çıktı sözleşmesinde Title nesneleri yok, ListItem yok, yeniden oluşturulmuş tablo ızgarası da yok. Tika başka işleyiciler ve API’ler de sunuyor; XHTML/SAX odaklı çıktı bunlardan biri. Onları test etmedim. Bu yüzden aşağıdaki tüm yapı sonuçları tika-app --text içindir; bu araç setinin hiçbir yerde yapılandırılmış bir event stream’i olmadığı iddiası değildir.
Bu, bir kısıt gibi duyuluyor; tek bir açıdan öyle de. Ama aynı zamanda Tika’nın yanlış sınıflandıracak hiçbir şey bırakmaması anlamına geliyor ki daha gürültülü benzer araçların ters yönde yaptığı takas da tam olarak budur.
Algılama sürecinin kendisi dokümante edilmiş bir sırayı izler: önce imza baytları, sonra XML kök denetimi, ardından dosya adı glob’u, en son da sizin verdiğiniz tür (Tika’nın kendi algılama dokümantasyonu bunu açıkça anlatır). Ancak tür çözüldükten sonra dispatcher, baytları eşleşen gömülü ayrıştırıcıya verir — PDFBox, POI, jsoup, metin ailesi için TextAndCSVParser.
Bu detection-then-parse ayrımı iç işleyişe dair boş bir ayrıntı değildir. Ayrıştırılamayacak kadar bozuk bir dosyanın yine de doğru tiplenebilmesinin nedeni budur; işler bozulmaya başladığında Tika’nın sunduğu en pratik numara da buna dönüşür.
Kurulum: tek jar, tek komut ve seçici davranmayan bir JVM
Kurulum aslında indirmeden ibaret. Maven Central’daki tika-app-3.3.2.jar yaklaşık 67 MB; her ayrıştırıcıyı içine alan büyük bir jar. Sonrası sadece java -jar tika-app-3.3.2.jar --text file.pdf. Config yok, model ağırlığı yok, kurulum sonrası adım yok, gidip dolaşılacak brew install zinciri yok.
JDK tarafı beni şaşırttı. Tüm testi OpenJDK 26.0.1 üzerinde, LTS olmayan en güncel bir derlemede çalıştırdım; --version, --text, --metadata ve --detect komutlarının hepsi uyumluluk şikâyeti olmadan exit 0 döndürdü. Bunu özellikle anmaya değer buluyorum; çünkü aynı hostta, aynı oturumda Apache Nutch’i de denedim ve crawl döngüsü JDK 26’da hiç çalışmadı — yeni JDK’lardaki SecurityManager kaldırımı nedeniyle 21 veya altı bir LTS gerekiyor. Tika buna aldırmadı. JVM araçlarından sırf bu tür bir dert yüzünden uzak duruyorsanız, Tika tam o noktada takılmıyor.
Kurulum tarafında iki dürüst not var. CLI her çağrıda yeni bir JVM başlatıyor; dolayısıyla soğuk başlangıç gerçek. Harness için yaptığım 131 çağrı, çoğu JVM ısınmasına giden yaklaşık bir dakikaya mal oldu. Dosyaları yüksek hacimde işliyorsanız jar’ı shell döngüsüyle çevirmek yerine kütüphane ya da server modunu kullanmak istersiniz. Bir de bağımlılıksız olma hikâyesinin sert bir sınırı var: PDF’in metin katmanını çıkarmak için dış bağımlılık gerekmez, ama OCR için tesseract ve poppler gerekir. Metin katmanlı PDF’ler, DOCX, ODT, RTF, HTML, XML, TXT, Markdown ve CSV; bu araçlar kurulu olmayan bir hostta da sorunsuz ayrıştırıldı. Taranmış belgeler için durum farklı olurdu; bunu da öyleymiş gibi göstermeye çalışmadım.
Bu kontrast, aynı gün test ettiğim kardeş kütüphane unstructured ile daha da belirginleşti; onun elektronik PDF yolu tamamen bloke oldu çünkü PDF modülünü içe aktarmak, strateji dağıtımından önce inference yığınını (torch ve benzerlerini) yüklemeyi gerektiriyor; yani “fast” strateji bile onsuz içe aktarılamıyor. Tika ise aynı PDF’in metin katmanını sade bir java -jar ile ayrıştırdı.
Yalan uzantı testi: dosyaya ne ad verdiğinizi umursamayan mime type algılama

Sekiz formatın her biri doğru uzantıyla, bilerek yanlış bir uzantıyla ya da uzantısız olarak sunuldu; buna bir de stdin üzerinden dosya adı olmayan akış eklendi. Bu 32 benzersiz mantıksal koşul demek. Orijinal harness, aynı akış baytlarını her dosya adı etiketi altında bir kez daha çalıştırdı ve 48 ham yürütme üretti; ancak stdin’de dosya adı olmadığı için bu üç akış satırı tek bir koşula indirgenir.
| Fixture | Gerçek tür | Yeniden adlandırıldı | Doğru uzantı | Yalan uzantı | Uzantısız | Ham akış, dosya adı yok |
|---|---|---|---|---|---|---|
application/pdf | .txt | ✅ | ✅ | ✅ | ✅ | |
| DOCX | OOXML wordprocessingml | .jpg | ✅ | ✅ | ✅ | ✅ |
| RTF | application/rtf | .html | ✅ | ✅ | ✅ | ✅ |
| HTML | text/html | .csv | ✅ | ✅ | ✅ | ✅ |
| XML | application/xml | .txt | ✅ | ✅ | ✅ | ✅ |
| Düz metin | text/plain | .pdf | ✅ | ✅ | ✅ | ✅ |
| Markdown | text/markdown | .pdf | ✅ | ❌ text/plain | ❌ text/plain | ❌ text/plain |
| CSV | text/csv | .txt | ✅ | ❌ text/plain | ❌ text/plain | ❌ text/plain |
(İçinde dosya adı olmadığı için akış sütunu üç uzantı koşulunun tamamını tek bir noktada toplar; glob’un okuyacağı bir şey yoktur.)
İçeriğe göre algılanabilen beş format — PDF, DOCX, RTF, HTML ve XML — 20 benzersiz koşulun 20’sinde doğru türe ulaştı (tekrarlanan akış çalıştırmaları dahil 30 ham harness yürütmesinin 30’unda da). report.txt adlı bir PDF yine PDF olarak algılandı. photo.jpg adlı bir DOCX yine DOCX kaldı. Hiçbirinin dosya adına ihtiyacı yoktu. Bu, beşinin de sabit bayt imzaları kullandığı anlamına gelmez: PDF ve RTF tanınabilir başlıklara sahiptir, DOCX ZIP tabanlı bir kapsayıcıdır, HTML/XML ise markup veya kök içerikten anlaşılır. Bu fixture setinde yalan uzantı kazanamadı.
Sonra metin ailesi rejimi geliyor. Markdown ancak .md uzantısı mevcut ve okunabilir olduğunda text/markdown olarak çözüldü. Uzantısını değiştirin, kaldırın ya da akış olarak gönderin; bu testte text/plaine düştü. CSV de bu özellikle küçük ızgarada aynı davrandı: text/csv yalnızca .csv glob’undan geldi. Benzersiz koşulları sayınca, Markdown ve CSV kendi özgün türlerine dört koşulun yalnızca birinde ulaştı; düz metin zaten text/plain olduğu için bir yerden “çökmekten” söz edecek bir şey yoktu. Ham 48 çalıştırmalı harness yine de tekrar edilebilirlik kaydı olarak kullanışlı, fakat daha büyük bir payda gibi değerlendirilmemeli.
Burada Tika lehine çalışan önemli bir ayrıntı var: yalan uzantı da kazanamıyor. .pdf olarak yeniden adlandırdığım Markdown fixture’ı application/pdf değil, text/plain olarak döndü. Tika yalana inanmadı; sadece gerçeği doğrulayamadı. Parent tipe düşmek, yanlış bir şeyi güvenle iddia etmekten çok daha iyi bir başarısızlıktır; text/markdownın text/plainın belgelenmiş bir alt türü olması da bu geri dönüşü keyfî olmaktan çıkarır.
CSV tarafında bir uyarı var. Tika’da istatistiksel bir CSV algılayıcısı bulunuyor ve ayrıştırma sırasında — X-TIKA:Parsed-By zincirinde TextAndCSVParser göründüğüne göre doğrulandı — benim küçük 2 sütun x 3 satırlık ızgaram text/csv yerine text/plain olarak çözüldü. Bu, bilerek minimal tutulmuş tek bir gözlem. Daha büyük ya da tırnaklı bir CSV algılayıcıyı tetikleyebilir. CSV içerik algılaması bozuk demiyorum; bu ızgarada text/csv sonucunu uzantının ürettiğini söylüyorum.
Bunun gerçek bir upload hattında neden önemi var?
Somut senaryo bir upload yönlendiricisidir. Diyelim ki kullanıcı yüklemelerini türüne göre ayırıyorsunuz: PDF’ler fatura ayrıştırıcısına, elektronik tablolar defter içe aktarıcıya, geri kalan her şey metin indeksine. Uzantıya güvenirseniz, notes.txt adlı bir PDF yanlış dala düşer — ve bu aslında iyi niyetli senaryo; kötü niyetli versiyon ise dostça bir uzantı taşıyan polyglot dosyadır.
Burada test edilen ikili ve markup fixture’larında, dosya adı kaybolmuş olsa bile Tika içeriğe göre yönlendirdi; bu, bir blob store ya da HTTP body handler dosya adını düşürmüşse faydalıdır. Ancak bu sonuç Tika’nın uzun kuyruk vakalarını, belirsiz dosyaları ya da polyglot’ları kapsamaz. Test edilen metin ailesi fixture’ları farklı davrandı: Hattınız dosya adlarını soyduğunda Markdown ve CSV text/plain olarak geldi, dolayısıyla onların belirli medya tiplerine göre yazılmış kurallar tetiklenmedi. İçerik algısının dosya adını yeniden üretmesini beklemek yerine, orijinal adı yardımcı metadata olarak saklayın.
Ekilen içerik sağ çıktı. --text yapıyı dümdüz etti.
İkinci eksen fidelity; o da net biçimde ikiye ayrılıyor. Bir kanonik belgeyi (başlıklar, iki gövde paragrafı, madde işaretli bir liste, numaralı bir liste, kapanış paragrafı) HTML, Markdown, düz metin, DOCX, PDF, RTF, ODT ve XML’e render ettim; ayrıca bir tablo belgesini HTML, Markdown, text, DOCX, CSV ve XML’e çevirdim. Toplam on dört taşıyıcı render. Her blok benzersiz bir token taşıyor — zztitle1, zzitem3, zztblcell_beta ve benzerleri — bu yüzden “sağ kaldı” ile “kayboldu” ayrımı, yoruma değil doğrudan alt dize kontrolüne dayanıyor.
İşaretleyici token hatırlama oranı on dört renderin tamamında 1.000 çıktı. Eklenen tek bir token bile kaybolmadı: etiketli her tablo hücresi, her liste öğesi ve her başlık çıktıdaydı. Her taşıyıcı için ısınma sonrası yapılan üç yerel tekrar, bayt düzeyinde aynı --text çıktısını verdi. Bu oracle, etiketlenmemiş karakterler, sıralama, boşluk, Unicode normalizasyonu, tekrarlanan içerik, bağlantılar, başlıklar, dipnotlar ya da gömülü nesneler hakkında hiçbir şey söylemez. Bu bir blok varlık kontrolüdür; eksiksiz belge sadakatinin kanıtı değil.
Düz metin çıktısı kaynak yapının büyük bölümünü bırakır.
HTML tablo belgesinin --textten çıkan hali şöyle:
Tool Throughput
zztblcell_alpha 120
zztblcell_beta 95
Sekmeyle ayrılmış satırlar. Başlık satırı başlık olarak işaretlenmiyor. Izgara yok, sekme dışında hücre sınırı yok, bunun bir zamanlar <table> olduğunu anlamanın yolu yok. DOCX tablosu da aynı şekilde düzleşiyor.
Listeler daha nüanslıdır ve kaynakta gerçekten ne olduğuna göre ayrılır:
| Kaynakta madde işaretinin ne olduğu | Taşıyıcılar | --text ne döndürür |
|---|---|---|
Bir literal karakter — bu render’lar - işaretini gerçek metin olarak yazdı | düz metin, Markdown, RTF, ODT, PDF | - korunur, çünkü Tika karakterleri aynen geçirir |
Gerçek yapı — bir HTML <li>, bir DOCX List Bullet stili | HTML, DOCX | işaret tamamen kaybolur ve yalnızca öğe metni kalır: HTML’de sekmeyle girintili, DOCX’te sade bir satır |
Tika, metin olarak almadığı bir işaretleyiciyi yeniden render etmez. Aynı içerik, ama farklı görünümlü çıktı.
Markdown örneği bunu net biçimde gösterir. Tika’ya pipe tablosu içeren bir .md dosyası verin; pipes olduğu gibi geri gelir. Bu, yapıyı koruyormuş gibi görünür. Aslında öyle değildir. Tika onu metin olarak ayrıştırmış ve baytları geri vermiştir. O tabloyu anlayan bir şey olmadı.
Dolayısıyla ölçülen sözleşme daha dardır: ekilen tüm işaretleyiciler hayatta kaldı; ancak --text yazı tiplerini ya da yeniden oluşturulabilir bir tablo ızgarasını korumadı. Buna ayrıştırıcı kusuru demek, noktayı kaçırmak olur. Düz çıkarım, element sınıflandırma problemini bilerek atlar; fakat aynı nedenle bu tür elementlere ihtiyaç duyan bir aşağı akış tüketicisini de tatmin edemez. Tiplenmiş bloklara ya da yeniden oluşturulmuş tablolara ihtiyacınız varsa, --text yığının bir parçasıdır; yığının tamamı değildir. Diğer Tika işleyicileri daha fazla yapı sunabilir, fakat bu çalışmanın dışındaydılar.
Buradaki her fidelity sayısı için standart uyarı geçerli: Bunlar tek bir makinede, tek sürümde, tek JDK üzerinde oluşturulmuş kontrollü sentetik fixture’lardan geliyor. Etiketli blokların çıktıda bulunduğunu gösterirler; dağınık gerçek dünya korpusunda karakter karakter korunmayı ya da doğruluğu ispatlamazlar.
Metadata: normalize edilmiş ve uydurmaya hevesi olmayan bir çıktı

Yazar, başlık ve oluşturulma tarihi gibi bilinen değerleri metadata katmanı olan her taşıyıcıya gömdüm ve sonra ne döndüğüne baktım.
| Taşıyıcı | author → dc:creator | title → dc:title | created → dcterms:created |
|---|---|---|---|
HTML (<meta name=author>, <title>) | ✅ | ✅ | gömülü değil |
| DOCX (core properties) | ✅ | ✅ | ✅ tam 2021-03-15T09:30:00Z |
| PDF (info dict) | ✅ | ✅ | mevcut, ama oluşturucunun kendi zaman damgasıydı — puanlanmadı |
ODT (meta.xml) | ✅ | ✅ | ✅ tam 2021-03-15T09:30:00Z |
| TXT / MD / CSV / RTF / XML | metadata katmanı yok | — | — |
Yazar ve başlık, metadata taşıyan 4’te 4 taşıyıcıda geri alındı ve işin güzel yanı şu: bunlar normalize ediliyor. Bir HTML <meta name="author">, bir DOCX core property, bir PDF /Author girdisi ve bir ODT dc:creator öğesi, hepsi aynı dc:creator anahtarı altında geliyor. Dört farklı tüketici yazmıyorsunuz; bir tane yazıyorsunuz.
created kısmı ise dürüst bir sallantı noktası. DOCX ve ODT, gömdüğüm 2021 zaman damgasını tam olarak geri verdi. PDF bir oluşturulma tarihi döndürdü, fakat bu benim gömmek istediğim değer değil; build sırasında generator kütüphanesinin bastığı tarihti — bu yüzden onu geri alınmış değil, mevcut olarak puanlıyorum. Metadata katmanı olmayan formatlar ise hiçbir şey göstermedi; bu da doğru cevap. Tika, gövde metninden yazar tahmin etmiyor.
Bilerek bozunca ve ortaya çıkan sınıflandırma taktiği
Dört düşmanca girdi: sıfır baytlık dosya, gövdesi kesilmiş geçerli PDF başlığı, yarıda bırakılmış DOCX ZIP’i ve BOM ile encoding beyanı olmayan çok baytlı karakterler içeren UTF-8 dosyası. Bunlar Tika eşiklerini değil, yerel fixture biçimlerini temsil ediyor.
Oluşturulmuş fixture’lar, ham JSON, jar checksum’u ve ortam manifesti burada herkese açık olarak bağlanmış değil; dolayısıyla dışarıdan biri tam paydaları birebir yeniden üretemez. Tabloları üçüncü tarafça doğrulanabilir kanıt değil, raporlanan gözlemler olarak değerlendirin.
| Girdi | --text / --json | Verdiği hata | --detect |
|---|---|---|---|
| 0 baytlık dosya | exit 1, boş stdout | ZeroByteFileException: InputStream must have > 0 bytes | exit 0 → dosya adı varsa text/plain, stream’den application/octet-stream |
| Yarım bırakılmış PDF | exit 1, boş stdout | TikaException: TIKA-198: Illegal IOException from PDFParser | exit 0 → application/pdf |
| Yarım bırakılmış DOCX | exit 1, boş stdout | POI FATAL: "XML document structures must start and end within the same entity" | exit 0 → OOXML türü |
| UTF-8, BOM yok, deklarasyon yok | exit 0 | hiçbir şey | exit 0 → text/plain, charset UTF-8 |
Çıkarma işlemi yüksek sesle başarısız olur ve bu başarısızlıkların dış görünüşü aynıdır. Sıfır baytlık dosya, yarım bırakılmış PDF ve yarım bırakılmış DOCX; her biri exception, exit 1 ve boş stdout üretti. CLI bu hatayı temiz bir boş sonuca yutmuyor. Bu durumlarda süreç güvenli — takılma yok, segfault yok — ama çağıran tarafın boş string yerine exit durumunu ve stderr’i kontrol etmesi gerekir.
Algılama, ayrıştırmadan bağımsızdır. Her iki yarım bırakılmış ikilide de --detect, sağlam baş kısımdan beklenen türü exit 0 ile döndürdü; ardından ayrıştırıcı bozuk gövdede başarısız oldu. Dolayısıyla bir hatalı parse’tan önce ya da sonra detection’ı ayrı bir triage sinyali olarak kullanabilirsiniz. Detect-first’in iyi bir varsayılan olup olmaması dağıtım moduna bağlıdır: bu test detect-first’i parse-only ile kıyaslamadı ve iki taze CLI JVM’i yüksek hacimde yanlış bir takas olabilir.
Charset algılama çalışıyor. BOM’suz ve deklarasyonsuz UTF-8 dosyası UTF-8 olarak çözüldü ve 日本語テスト aynen geldi. Metadata sözlüklerine bakanlar için küçük bir not: saf ASCII fixture’larım charset=ISO-8859-1 döndürüyor; bu, ASCII baytlar üzerinde UTF-8 ile ayırt edilemez. Bu bir hata değil, beraberlik.
Tika ve unstructured yan yana: aynı dosya türleri, farklı işler
İkisi de aynı araştırma oturumunda kullanıldı; ama bu, simetrik bir benchmark değil, çıktı sözleşmeleri taksonomisi. Araçlar farklı sonuçlar üzerinden değerlendirildi.
İlgili inceleme: Unstructured incelemesi.
| Apache Tika | unstructured | |
|---|---|---|
| Ne üzerinde ölçüldü | içerik sadakati: bir şey kayboldu mu? | öğe sınıflandırma sadakati: her blok doğru türde mi? |
| Sonuç | on dört render boyunca tüm eklenmiş işaretleyiciler mevcut | ayrı sınıflandırma testinde, düz metin tablo Table için 0.000 recall verdi ve fiil içeren bir başlık narrative text olarak sınıflandı |
| Dönen yazılı öğeler | yok — yapı geri gelmedi | Title, NarrativeText, ListItem, Table — Tika’nın yapmayı reddettiği şey tam olarak bu |
| OCR | makinemde bloklandı, tesseract eksikti | makinemde bloklandı, tesseract eksikti |
Düz, işaretleyici koruyan çıktı ile yazılı öğeler ve gözlemlenen sınıflandırma hataları. Aşağı akış tüketicisinin neye ihtiyacı varsa ona göre seçin. Arama indeksi ya da LLM context window ise düz metin yeterli olabilir. Ama tüketici öğe türüne göre çalışıyorsa, Tika’nın --text yolu bu sözleşmeyi sağlayamaz.
İkisinin de taranmış belge sayısı yok.
Artılar ve eksiler
Artılar
- Beş içerik algılanabilir fixture’daki 20/20 benzersiz koşulun tamamında içerik türü yalan dosya adlarını umursamadı; tekrarlanan akış yürütmeleri de aynı sonucu verdi.
- 14 taşıyıcı renderin tamamında her eklenmiş işaretleyici sağ kaldı; etiketli tablo hücreleri ve liste öğeleri dahil.
- Üç yerel tekrar içinde yeniden üretilebilir: bu ortamda her taşıyıcı bayt düzeyinde aynı metni verdi.
- Metadata formatlar arasında normalize edildi — kaynak formattan bağımsız olarak
dc:creator/dc:title/dcterms:created; metadata taşıyan 4/4 taşıyıcıda geri alındı. - Test ettiğim formatlar için gerçekten bağımlılıksız: PDF metin katmanı, DOCX, ODT, RTF, HTML tek bir jar ile ve dış binary olmadan ayrıştırıldı.
- OpenJDK 26 üzerinde temiz çalışıyor — yalnızca LTS şartı yok.
- Yarım bırakılmış ikililerde detection doğru kalıyor (exit 0); ayrıştırma başarısız olduğunda güvenilir bir triage sinyali veriyor.
- Apache-2.0, olgun, aktif olarak bakımı yapılıyor.
Eksiler
- Markdown ve CSV kimliği bütünüyle dosya adına bağlı; uzantısı olmayan ya da yanlış olan 18 signaturesız hücrenin 10’u dosya adı kaybolunca
text/plaine düştü. --textöğe türleri döndürmüyor; tablo ızgaraları sekmeyle birleştirilmiş satırlara dönüyor ve yapısal liste işaretleri kayboluyor.- Boş ve bozuk girdilerde yakalanmamış hata atıyor; iki durum yalnızca extraction çağrısına bakınca aynı görünüyor.
- CLI modunda 67 MB’lık jar ve her çağrıda JVM soğuk başlangıcı.
- OCR ve taranmış görüntü PDF’leri burada tamamen test edilmedi — tesseract ve poppler yoktu, dolayısıyla bu yol hakkında hiçbir iddia yok.
- Buradaki tüm sayılar tek makinede, tek sürümde sentetik ground truth. Gerçek korpus doğruluğu, şifreli dosyalar, gömülü/özyinelemeli belgeler ve ölçeklenebilir throughput ölçülmedi.
Kim kullanmalı, kim kullanmamalı?
Girdiğiniz şey zaten elinizde olan dosyalar ve çıktınızın makinenin indeksleyebileceği metin artı metadata olması gerektiğinde Tika uygundur. Arama indeksleme, e-discovery, arşiv işleme, bir korpusu LLM’e besleme, upload hattının içerik türü doğrulama katmanını kurma. Tika, daha akıllı bir şeyin önünde bir ilk aşama triage ve normalizasyon adımı olarak faydalıdır: test edilen türleri tespit edin, düz metni çıkarın ve hattınızın kaybetmeyi göze alamadığı içerikler için açık kontrollerle ileri aktarın.
Şunu istiyorsanız onu pas geçin — ya da daha doğrusu --textte durmayın: tiplenmiş öğeler, yeniden oluşturulmuş tablolar ya da belge yerleşimi gerekiyorsa. Belgeleriniz taranmışsa da pas geçin; en azından tesseract kurup kendi sonuçlarınıza bakana kadar, çünkü benim elimde yok. Yüksek hacimli işlerde CLI yerine kütüphane ya da server modunu, temsili belgeler üzerinde benchmark edin. Bu küçük dosya harness’inde süreç başlangıcı görünürdü; ancak throughput ve kaynak maliyeti ölçülmedi.
İnsanların çoğunu yakalayan nokta şu: depolama katmanınız dosya adlarını soyuyorsa ve Markdown ya da CSV ile çalışıyorsanız, Tika’nın bunları düz metinden ayırmasını beklemeyin. Orijinal adı saklayın.
Alternatifler ve Thunderbit’in konumu
Önce adil çerçeve: Buradaki dürüst karşılaştırma kalite değil, girdi üzerine. Tika, dosyaları ayrıştırmak için ücretsiz, Apache-2.0 lisanslı, kendi kendine barındırılabilen bir araç setidir. Diskinizde ya da bucket’ınızda duran dosyalar için. Sayfa çekmez, JavaScript çalıştırmaz, anti-bot ile uğraşmaz ve öyleymiş gibi davranmaz.
Yönetilen bir web extraction servisi — bizim Thunderbit çözümümüz de dahil — tam bu sınırda mimariye girebilir: canlı sayfaları çeker, Tika ise zaten sahip olduğunuz dosyaları ayrıştırır. Bu makale, bu servisleri Tika’ya karşı benchmark etmedi; aynı girdi için birbirlerinin yerine geçmezler.
Temiz ayrım şu: Elinizde zaten olan belgeler için Tika, gidip almanız gereken web sayfaları için yönetilen bir extraction API. Pek çok hat ikisini de kullanır — web tarafında tarama ve extraction, geri dönen PDF ve DOCX eklerinde ise Tika.
Daha geniş açık kaynak alanı içinde kıyas yapıyorsanız, tam açık kaynak scraper karşılaştırmasını, GitHub’daki en yararlı scraping projeleri derlemesini, tarayıcı destekli Markdown yaklaşımını ele alan uygulamalı bir Crawl4AI incelemesini ve daha geniş bir scraping araçları özetini yazdım. Kodsuz yol için, AI kullanarak site nasıl scrape edilir rehberi de var.
Web Veri Çıkarma için Thunderbit’i Deneyin
Karar
Apache Tika’yı kullanmalı mısınız? Evet — eğer işiniz heterojen dosyaları düz metne ve normalize metadata’ya çevirmekse ve kendi hattınızın kaybetmeyi göze alamadığı alanları ya da işaretleri doğruluyorsanız.
Bu çalışmanın en güçlü yanı detektördü. Beş içerik algılanabilir fixture için, dosya adı olmayan akışlar dahil, 20 benzersiz koşulun 20’sinde beklenen türü döndürdü. Ekinmiş her işaretleyici on dört render boyunca korundu ve çıktı üç yerel tekrar boyunca bayt bayt aynı kaldı. Faydalı kanıt. Yine de sentetik kanıt. Bunu bu JDK üzerinde, test edilen OCR dışı yollar için hiçbir dış binary olmadan, tek bir jar ile yapmak dağıtımı hoş bir şekilde sıkıcı tuttu.
Ama doğru boyutlandırın. Verdiğiniz her tablo sekmeyle birleştirilmiş satırlara dönüyor. Her yapısal liste işaretleyicisi kayboluyor. Markdown ve CSV, dosya adı gider gitmez kimliğini yitiriyor. Boş dosyalar ve bozuk dosyalar aynı tipte hata veriyor; bunları ayırmak için ayrı bir detect çağrısına ihtiyacınız olacak. Ve pek çok Tika kullanıcısının en çok önem verdiği OCR konusunda elimde sunacak bir şey yok: çalıştıramadım ve tahmin de etmeyeceğim.
Bu sınırların içinde Tika, alışılmadık ölçüde güvenilir, gösterişsiz bir iş çıkarıyor. Kutunun üstündeki etikete değil, baytlara bakıyor. Sadece baytların hangi şekle girdiğini sormayın.
Web Veri Çıkarma için Thunderbit’i Deneyin Get Started Free
SSS
Apache Tika, dosya uzantısı yanlışsa türü doğru algılar mı?
Burada test edilen beş içerik algılanabilir fixture için evet. PDF, DOCX, RTF, HTML ve XML; yanıltıcı uzantılar, uzantısızlık ve dosya adı olmayan akışlar dahil olmak üzere 20 benzersiz mantıksal koşulun tamamında beklenen medya türüne çözüldü (tekrarlanan akış çalıştırmalarıyla 30 ham koşul). .txt olarak adlandırılmış bir PDF yine de application/pdf olarak algılandı. Markdown ve küçük CSV fixture’ı ise dosya adı bilgisine bağlıydı ve bu bilgi eksik ya da yanlış olduğunda text/plaine düştü.
Tika tabloları ve belge yapısını korur mu?
Burada test edilen --text modunda hayır. Tablo ızgaraları, hücre ya da başlık semantiği olmadan sekmeyle birleştirilmiş satırlara döndü; yapısal liste işaretleri (<li>, DOCX List Bullet stili) kayboldu. Ekilen tüm işaretleyiciler 14 taşıyıcı renderin tamamında korundu, fakat bu eksiksiz içerik sadakatini kanıtlamaz ve --text öğe türü vermez. Tiplenmiş öğeler ya da yeniden oluşturulmuş tablolar için başka bir Tika çıktı işleyicisini test edin veya yanına başka bir araç kullanın.
Apache Tika taranmış PDF’lerde OCR yapabilir mi? Tika, Tesseract üzerinden OCR’ı destekler; ama ben test etmedim ve buradaki sonuçların hiçbiri buna dair bir iddia değildir. Test hostumda Tesseract ve poppler yoktu, dolayısıyla tüm OCR ve taranmış görüntü yolları daha başlamadan bloke oldu. Bu testte OCR’a dair hiçbir sayı yok. OCR sizin kullanım senaryonuzsa tesseract kurun ve kendiniz benchmark edin — Tika’nın bu kısmını burada doğrulanmamış kabul edin.
Tika boş ya da bozuk dosyalarda ne yapar?
Sessizce geçiştirmek yerine gürültülü şekilde başarısız olur. 0 baytlık dosya ZeroByteFileException fırlatır; yarım bırakılmış PDF, PDFParser’dan gelen bir TikaException üretir; yarım bırakılmış DOCX ise bir POI XML hatası verir. Üçü de exit 1 ve boş stdout ile çıkar; yani extraction çağrısına tek başına bakınca boş ve bozuk dosyalar ayırt edilemez. Ancak detection sağlam kalır — --detect, her iki yarım bırakılmış ikilide de doğru türle exit 0 döndürdü; bu da parse etmeye vakit harcamadan önce güvenilir bir triage adımı yapar.
Tika testi neleri kapsamıyor? Dört şeyi açıkça kapsamıyor. OCR ve taranmış görüntüler (bloklandı, test edilmedi). Gerçek korpus doğruluğu — tüm sonuçlar, kirli gerçek belgelerde doğruluk yerine bilinen etiketlere karşı sadakati ölçen, eklenmiş işaretleyici token’lara sahip kontrollü sentetik fixture’lar. Kaynak maliyeti, throughput ve tepe bellek tüketimi; bunları ölçmedim. Ve “bin dosya türü” iddiasının uzun kuyruğu: tam kataloğun tamamını değil, dokuz temsilî ve bağımlılıksız formatı test ettim. Buradaki her şey Tika 3.3.2, OpenJDK 26.0.1, macOS arm64 ve tek makine üzerinde.


