Portable Document Format (PDF), sebuah format file yang distandarisasi oleh ISO 32000, dikembangkan oleh Adobe pada tahun 1992 untuk menyajikan dokumen yang menyertakan format teks dan gambar dengan cara yang tidak bergantung pada perangkat lunak aplikasi, perangkat keras, dan sistem operasi.
Panduan ini mencakup cara memuat dokumen PDF ke dalam format Dokumen LangChain. Format ini digunakan di bagian hilir.
LangChain terintegrasi dengan berbagai pengurai PDF. Beberapa di antaranya sederhana dan relatif tingkat rendah, sementara yang lain mendukung OCR dan pemrosesan gambar atau melakukan analisis tata letak dokumen tingkat lanjut.
defshow_metadata(docs):if docs:print("[metadata]")print(list(docs[0].metadata.keys()))print("\n[examples]") max_key_length =max(len(k) for k in docs[0].metadata.keys())for k, v in docs[0].metadata.items():print(f"{k:<{max_key_length}} : {v}")
PyPDF
Di sini kita menggunakan pypdf untuk memuat PDF sebagai sebuah larik dokumen, yang masing-masing berisi konten halaman dan metadata beserta nomor halaman.
# install# !pip install -qU pypdf
from langchain_community.document_loaders import PyPDFLoader# mengatur jalur berkasloader =PyPDFLoader(FILE_PATH)# Inisialisasi pemuat PDFdocs = loader.load()# mencetak isi dokumenprint(docs[10].page_content[:300])
# keluaran metadatashow_metadata(docs)
PyPDF (OCR)
Beberapa PDF berisi gambar teks dalam dokumen atau gambar yang dipindai. Anda juga dapat menggunakan paket rapidocr-onnxruntime untuk mengekstrak teks dari gambar.
PyMuPDF dioptimalkan untuk kecepatan dan menyertakan metadata yang mendetail tentang PDF dan halaman-halamannya. Ini mengembalikan satu dokumen per halaman:
# install# !pip install -qU pymupdf
from langchain_community.document_loaders import PyMuPDFLoader# membuat sebuah contoh pemuat PyMuPDFloader =PyMuPDFLoader(FILE_PATH)# memuat dokumendocs = loader.load()# mencetak isi dokumenprint(docs[10].page_content[:300])
show_metadata(docs)
Tidak terstruktur
Unstructured mendukung antarmuka umum untuk menangani format file yang tidak terstruktur atau semi-terstruktur seperti Markdown atau PDF.
UnstructuredPDFLoader dari LangChain terintegrasi dengan Unstructured untuk mengurai dokumen PDF menjadi objek Dokumen LangChain.
# install# !pip install -qU unstructured
from langchain_community.document_loaders import UnstructuredPDFLoader# membuat sebuah contoh dari UnstructuredPDFLoaderloader =UnstructuredPDFLoader(FILE_PATH)# memuat datadocs = loader.load()# mencetak isi dokumenprint(docs[0].page_content[:300])
show_metadata(docs)
Secara internal, unstructured menciptakan "elemen" yang berbeda untuk setiap potongan teks. Secara default, semua ini digabungkan, tetapi dapat dengan mudah dipisahkan dengan menentukan mode="elements".
# membuat sebuah contoh UnstructuredPDFLoader (mode = "elements")loader =UnstructuredPDFLoader(FILE_PATH, mode ="elements")# memuat datadocs = loader.load()# mencetak isi dokumenprint(docs[0].page_content)
Lihat rangkaian lengkap jenis elemen untuk dokumentasi khusus ini
set(doc.metadata["category"] for doc in docs)# mengekstrak kategori data
show_metadata(docs)
PyPDFium2
from langchain_community.document_loaders import PyPDFium2Loader# membuat sebuah contoh dari pemuat PyPDFium2loader =PyPDFium2Loader(FILE_PATH)# memuat datadocs = loader.load()# mencetak isi dokumenprint(docs[10].page_content[:300])
show_metadata(docs)
PDFMiner
from langchain_community.document_loaders import PDFMinerLoader# membuat sebuah contoh pemuat PDFMinerloader =PDFMinerLoader(FILE_PATH)# memuat datadocs = loader.load()# mencetak isi dokumenprint(docs[0].page_content[:300])
show_metadata(docs)
Menggunakan PDFMiner untuk menghasilkan teks HTML
Metode ini memungkinkan Anda untuk mengurai konten HTML keluaran melalui BeautifulSoup untuk mendapatkan informasi yang lebih terstruktur dan lebih kaya tentang ukuran font, nomor halaman, header/footer PDF, dll. yang dapat membantu Anda membagi teks secara semantik menjadi beberapa bagian.
from langchain_community.document_loaders import PDFMinerPDFasHTMLLoader# membuat sebuah contoh dari PDFMinerPDFasHTMLLoaderloader =PDFMinerPDFasHTMLLoader(FILE_PATH)# memuat dokumendocs = loader.load()# mencetak isi dokumenprint(docs[0].page_content[:300])
from bs4 import BeautifulSoupsoup =BeautifulSoup(docs[0].page_content, "html.parser")# inisialisasi parser HTMLcontent = soup.find_all("div")# mencari semua tag div
import recur_fs =Nonecur_text =""snippets = [] # kumpulkan semua potongan dengan ukuran font yang samafor c in content: sp = c.find("span")ifnot sp:continue st = sp.get("style")ifnot st:continue fs = re.findall("font-size:(\d+)px", st)ifnot fs:continue fs =int(fs[0])ifnot cur_fs: cur_fs = fsif fs == cur_fs: cur_text += c.textelse snippets.append((cur_text, cur_fs)) cur_fs = fs cur_text = c.textsnippets.append((cur_text, cur_fs))# Kemungkinan untuk menambahkan strategi untuk menghapus cuplikan duplikat (karena header/footer PDF muncul di beberapa halaman, duplikat dapat dianggap sebagai informasi duplikat ketika ditemukan)
from langchain_core.documents import Documentcur_idx =-1semantic_snippets = []# judul mengasumsikan: ukuran huruf besarfor s in snippets:# tentukan judul baru: font cuplikan saat ini > font judul lamaif (not semantic_snippetsor s[1]> semantic_snippets[cur_idx].metadata["heading_font"] ): metadata ={"heading": s[0],"content_font":0,"judul_font": s[1]} metadata.update(docs[0].metadata) semantic_snippets.append(Document(page_content="", metadata=metadata)) cur_idx +=1continue# tentukan konten bagian yang sama: font cuplikan saat ini <= font konten sebelumnyaif (not semantic_snippets[cur_idx].metadata["content_font"]or s[1]<= semantic_snippets[cur_idx].metadata["content_font"] ): semantic_snippets[cur_idx].page_content += s[0] semantic_snippets[cur_idx].metadata["content_font"]=max( s[1], semantic_snippets[cur_idx].metadata["content_font"] )continue# membuat kondisi bagian baru: font cuplikan saat ini > font konten sebelumnya, kurang dari font judul sebelumnya metadata ={"heading": s[0],"content_font":0,"heading_font": s[1]} metadata.update(docs[0].metadata) semantic_snippets.append(Document(page_content="", metadata=metadata)) cur_idx +=1print(semantic_snippets[4])
Direktori PyPDF
Memuat PDF dari direktori
from langchain_community.document_loaders import PyPDFDirectoryLoader# jalur direktoriloader =PyPDFDirectoryLoader("data/")# memuat dokumendocs = loader.load()# mencetak jumlah dokumenprint(len(docs))
# mencetak isi dari dokumenprint(docs[50].page_content[:300])
# cetak metadataprint(docs[50].metadata)
PDFPlumber
Seperti PyMuPDF, dokumen keluaran berisi metadata terperinci tentang PDF dan halamannya, dan mengembalikan satu dokumen per halaman.
from langchain_community.document_loaders import PDFPlumberLoader# membuat sebuah contoh pemuat dokumen PDFloader =PDFPlumberLoader(FILE_PATH)# memuat dokumendocs = loader.load()# mengakses data dokumen pertamaprint(docs[10].page_content[:300])