Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce sisteminizde Node.js (LTS sürümü 22.x veya üzeri önerilir) kurulu olmalıdır. PDF işleme süreçlerinde yüksek performans almak için "pdf-parse" ve dosya yönetimi için "fs" (file system) modüllerini kullanacağız. Projenizi oluşturmak için aşağıdaki adımları izleyin.
mkdir pdf-parser-service
cd pdf-parser-service
npm init -y
npm install pdf-parse
Bu komutlar, projenizin temel dizinini oluşturur ve gerekli kütüphaneleri yükler. "pdf-parse", PDF dosyalarını metin katmanına dönüştürmek için oldukça hızlı ve hafif bir çözümdür.
PDF Dosyalarını Okuma ve Metin Ayrıştırma
PDF dosyalarından veri çekmenin ilk adımı, ikili (binary) veriyi okunabilir metin formatına çevirmektir. "pdf-parse" kütüphanesi, PDF yapısını çözümleyerek bize metin içeriğini bir nesne içerisinde sunar. Aşağıdaki kod bloğu, temel bir PDF okuma işlemini göstermektedir.
const fs = require('fs');
const pdf = require('pdf-parse');
async function extractText(filePath) {
const dataBuffer = fs.readFileSync(filePath);
const data = await pdf(dataBuffer);
return data.text;
}
extractText('fatura.pdf').then(text => {
console.log(text);
}).catch(err => {
console.error('Hata oluştu:', err);
});
Bu kodda, fs.readFileSync ile dosya belleğe yüklenir ve pdf() fonksiyonu ile ayrıştırılır. Sonuç olarak dönen data.text değişkeni, PDF içindeki tüm metinsel içeriği barındırır.
Veri Ayrıştırma ve Düzenli İfadeler (Regex) Kullanımı
PDF'den gelen ham metin genellikle düzensizdir. Bu metin içerisinden spesifik verileri (tarih, fatura numarası, toplam tutar) çekmek için Düzenli İfadeler (Regex) kullanırız. Regex, metin desenlerini eşleştirmek için kullanılan güçlü bir araçtır.
function parseInvoiceData(text) {
const invoiceNoMatch = text.match(/Fatura No: (\d+)/);
const totalAmountMatch = text.match(/Toplam: (\d+\.\d{2})/);
return {
faturaNo: invoiceNoMatch ? invoiceNoMatch[1] : null,
toplamTutar: totalAmountMatch ? parseFloat(totalAmountMatch[1]) : 0
};
}
const rawText = "Fatura No: 123456789 - Toplam: 1500.50";
console.log(parseInvoiceData(rawText));
Bu örnekte, metin içerisinde "Fatura No:" ve "Toplam:" anahtar kelimelerini arayarak yanlarındaki değerleri yakalıyoruz. Regex desenlerinizi PDF'inizin formatına göre özelleştirmeniz gerektiğini unutmayın.
PDF İşleme Kütüphanelerinin Karşılaştırılması
Node.js ekosisteminde PDF işleme için farklı kütüphaneler mevcuttur. İhtiyacınıza en uygun olanı seçmek için aşağıdaki tabloyu inceleyebilirsiniz.
| Kütüphane | Avantajı | Dezavantajı |
|---|---|---|
| pdf-parse | Hızlı, basit, hafif | Karmaşık tablolarda zorlanır |
| pdf2json | JSON çıktısı verir | Daha fazla bellek tüketir |
| pdf-lib | PDF oluşturma ve düzenleme | Metin okuma için ek kütüphane gerekir |
Güvenlik ve Hata Yönetimi
PDF dosyaları dışarıdan gelen veriler olduğu için güvenlik riski taşır. Özellikle "denial of service" (DoS) saldırılarına karşı büyük dosyaların işlenmesini sınırlamalı ve dosya türü kontrolleri yapmalısınız.
Kritik Uyarı: Üretim ortamında kullanıcıdan gelen PDF dosyalarını doğrudan işlemeyin. Dosya boyutunu kontrol edin, MIME tipini doğrulayın ve dosyaları izole bir ortamda (sandbox) işleyin. Ayrıca, kodunuzda oluşabilecek hataları try-catch blokları ile sarmalayarak uygulamanızın çökmesini engelleyin.
const path = require('path');
function validateFile(file) {
const allowedExtensions = ['.pdf'];
const ext = path.extname(file.name);
if (!allowedExtensions.includes(ext)) {
throw new Error('Geçersiz dosya formatı.');
}
}
Bu fonksiyon, işleme başlamadan önce dosyanın PDF olup olmadığını kontrol eder. Güvenli bir servis için dosya boyutu kontrolü (örn. max 5MB) eklemek de oldukça önemlidir.
Servis Yapısının Kurulması (Express.js ile)
PDF ayrıştırma işlemini bir API servisine dönüştürmek için Express.js kullanabiliriz. Bu sayede dosyayı bir endpoint üzerinden gönderip, ayrıştırılmış veriyi JSON olarak alabilirsiniz.
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
app.post('/parse', upload.single('pdf'), async (req, res) => {
try {
const text = await extractText(req.file.path);
const data = parseInvoiceData(text);
res.json({ success: true, data });
} catch (error) {
res.status(500).json({ error: 'İşleme başarısız.' });
}
});
app.listen(3000, () => console.log('Servis 3000 portunda çalışıyor.'));
Burada "multer" kütüphanesi, gelen dosyayı geçici olarak "uploads" klasörüne kaydeder. Ardından extractText fonksiyonu ile işlenir ve sonuç istemciye JSON formatında döner.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Yazılım güvenliği, veri gizliliği ve sunucu yönetimi sorumluluğu geliştiriciye aittir. Hassas verilerin işlenmesi durumunda KVKK ve GDPR uyumluluğunu göz önünde bulundurunuz.
Sıkça Sorulan Sorular
PDF içindeki tabloları nasıl ayrıştırırım?
PDF içindeki tablolar "pdf-parse" ile düz metin olarak gelir. Tablo yapısını korumak için "pdf-table-extractor" gibi daha spesifik kütüphaneler kullanabilir veya metni satır bazlı bölerek (split) kendi ayrıştırma mantığınızı yazabilirsiniz.
Çok büyük PDF dosyalarında bellek sorunu yaşar mıyım?
Evet, büyük dosyalar Node.js'in bellek sınırlarını zorlayabilir. Bu durumda dosyayı stream (akış) yöntemiyle okumalı veya dosyayı sayfalara bölerek parça parça işlemelisiniz.
Taranmış (Resim tabanlı) PDF'leri okuyabilir miyim?
Hayır, bu rehberde anlatılan yöntemler metin tabanlı PDF'ler içindir. Taranmış PDF'ler için OCR (Optik Karakter Tanıma) teknolojisi (örneğin Tesseract.js) kullanmanız gerekir.
Hangi Node.js sürümünü kullanmalıyım?
2026 yılı itibarıyla en güncel ve kararlı Node.js LTS sürümünü kullanmanız, güvenlik yamaları ve performans iyileştirmelerinden faydalanmanızı sağlar.
Veri ayrıştırma doğruluğunu nasıl artırırım?
Regex desenlerinizi olabildiğince spesifik tutun ve metin temizleme (boşlukları silme, karakter kodlamalarını düzeltme) işlemlerini ayrıştırmadan önce mutlaka yapın.
PDF İşleme Servislerinde Performans Optimizasyonu ve Ölçeklendirme
PDF ayrıştırma işlemleri CPU yoğunluklu görevlerdir. Özellikle çok sayfalı veya karmaşık görseller içeren dosyalar, Node.js'in tek iş parçacıklı (single-threaded) yapısını zorlayabilir. Bu darboğazı aşmak için uygulamanızı yatayda ölçeklendirmeniz veya ağır işlemleri ana uygulama döngüsünden ayırmanız gerekir.
Worker Threads Kullanımı
PDF işleme sürecini ana event loop'tan çıkarmak için Node.js'in worker_threads modülünü kullanabilirsiniz. Bu sayede ana sunucunuz gelen HTTP isteklerini karşılamaya devam ederken, PDF ayrıştırma işlemi farklı bir çekirdek üzerinde yürütülür.
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
if (isMainThread) {
function parsePdfInWorker(filePath) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, { workerData: filePath });
worker.on('message', resolve);
worker.on('error', reject);
});
}
} else {
const pdfData = parseLogic(workerData); // PDF işleme fonksiyonunuz
parentPort.postMessage(pdfData);
}
Redis ile Kuyruk (Queue) Yapısı
Eğer sisteminize aynı anda onlarca PDF yükleniyorsa, Express.js üzerinden doğrudan işlem yapmak yerine bir kuyruk mekanizması kurmalısınız. BullMQ veya Bee-Queue gibi kütüphaneler, PDF işlemlerini arka planda sıraya alarak sunucunun çökmesini engeller.
Üretim Ortamında (Deployment) Hata Ayıklama ve İzleme
PDF ayrıştırma servislerinde en sık karşılaşılan sorunlar; hatalı biçimlendirilmiş PDF'ler, eksik fontlar veya beklenmedik karakter kodlamalarıdır. Üretim ortamında bu hataları yönetmek için şu stratejileri izleyin:
- Log Yönetimi: Hatalı ayrıştırılan dosyaların ham hallerini (veya hata loglarını) bir bulut depolama alanına (S3 gibi) kaydedin. Bu, regex desenlerinizi güncellemek için size veri sağlar.
- Süre Sınırı (Timeout): Her PDF işleme süreci için bir zaman aşımı tanımlayın. Sonsuz döngüye giren veya yanıt vermeyen kütüphane çağrılarını
Promise.race()ile sonlandırın.
const timeout = (ms) => new Promise((_, reject) =>
setTimeout(() => reject(new Error('PDF işleme zaman aşımına uğradı')), ms)
);
async function safeParse(pdfBuffer) {
return Promise.race([
parsePdf(pdfBuffer),
timeout(10000) // 10 saniye limit
]);
}
Yaygın Hata Senaryoları ve Çözümleri
| Hata Türü | Olası Neden | Çözüm |
|---|---|---|
| Encoding Sorunu | PDF'in özel karakter seti kullanması | iconv-lite ile metni UTF-8'e zorlayın. |
| Bellek Taşması | Çok büyük dosya boyutu | Stream (akış) tabanlı okuma kütüphanelerine geçin. |
| Boş Veri Dönmesi | PDF'in "Image-only" olması | OCR (Tesseract.js) entegrasyonu ekleyin. |
Bu yaklaşımlar, servisinizi sadece bir prototip olmaktan çıkarıp, kurumsal düzeyde stabil çalışan bir veri işleme hattına dönüştürecektir. Özellikle hata ayıklama süreçlerinde, ayrıştırılan metinlerin "ham" halini bir log dosyasında tutmak, regex desenlerinizin neden başarısız olduğunu anlamanız için en iyi yoldur.
Sonuç
Node.js ile PDF dosyalarından veri ayrıştırma servisi oluşturmak, doğru kütüphaneler ve temiz bir kod yapısı ile oldukça verimli bir süreçtir. Bu rehberde öğrendiğiniz temel adımları kullanarak kendi ihtiyaçlarınıza göre özelleştirilmiş, ölçeklenebilir servisler geliştirebilirsiniz. Bir sonraki adım olarak, ayrıştırdığınız verileri bir veritabanına kaydetmeyi veya bu süreci bir kuyruk yapısı (RabbitMQ veya Redis) ile asenkron hale getirmeyi deneyebilirsiniz.


Yorumlar (0)
Yorum Yaz