Mengekstrak teks daripada PDF biasanya mudah apabila ia dalam bahasa Inggeris dan tidak mempunyai fon terbenam. Walau bagaimanapun, sebaik sahaja andaian tersebut dialih keluar, ia menjadi mencabar untuk menggunakan perpustakaan python asas seperti pdfminer atau pdfplumber. Bulan lalu, saya ditugaskan untuk mengekstrak teks daripada PDF bahasa Gujarati dan mengimport medan data seperti nama, alamat, bandar, dll., ke dalam format JSON.
Jika fon dibenamkan dalam PDF itu sendiri, penyalinan tampal mudah tidak akan berfungsi dan menggunakan pdfplumber akan mengembalikan teks sampah yang tidak boleh dibaca. Oleh itu, saya terpaksa menukar setiap halaman PDF kepada imej dan kemudian menggunakan OCR menggunakan perpustakaan pytesseract untuk "mengimbas" halaman dan bukannya hanya membacanya. Tutorial ini akan menunjukkan kepada anda cara untuk melakukannya.
Anda boleh memasang perpustakaan Python menggunakan arahan pip seperti yang ditunjukkan di bawah. Untuk Tesseract-OCR, muat turun dan pasang perisian dari tapak rasmi. pytesseract hanyalah pembalut di sekeliling perisian tesseract.
pip install pdfplumber pip install pdf2image pip install pytesseract
Langkah pertama ialah menukar halaman PDF anda kepada imej. Fungsi extract_text_from_pdf() ini betul-betul-anda melepasi laluan PDF dan page_num (sifar diindeks) sebagai parameter. Harap maklum bahawa saya menukar halaman kepada hitam putih terlebih dahulu untuk kejelasan, ini adalah pilihan.
# Extract text from a specific page of a PDF def extract_text_from_pdf(pdf_path, page_num): # Use pdfplumber to open the PDF pdf = pdfplumber.open(pdf_path) print(f"extracting page {page_num}..") page = pdf.pages[page_num] images = convert_from_path(pdf_path, first_page=page_num+1, last_page=page_num+1) image = images[0] # Convert to black and white bw_image = convert_to_bw(image) # Save the B&W image for debugging (optional) #bw_image.save("bw_page.png") # Perform OCR on the B&W image e_text = ocr_image(bw_image) open('out.txt', 'w', encoding='utf-8').write(e_text) #print("output written to file.") try: process_text(page_num, e_text) except Exception as e: print("Error occurred:", e) print("done..") # Convert image to black and white def convert_to_bw(image): # Convert to grayscale gray = image.convert('L') # Apply threshold to convert to pure black and white bw = gray.point(lambda x: 0 if x < 128 else 255, '1') return bw # Perform OCR using Tesseract on a given image def ocr_image(image_path): try: # Perform OCR custom_config = r'--oem 3 --psm 6 -l guj+eng' text = pytesseract.image_to_string(image_path, config=custom_config) # --psm 6 treats the image as a block of text return text except Exception as e: print(f"Error during OCR: {e}") return None
Fungsi ocr_image() menggunakan pytesseract untuk mengekstrak teks daripada imej melalui OCR. Parameter teknikal seperti --oem dan --psm mengawal cara imej diproses dan parameter -l guj eng menetapkan bahasa untuk dibaca. Memandangkan PDF ini mengandungi teks Inggeris sekali-sekala, saya menggunakan guj eng.
Setelah anda mengimport teks menggunakan OCR, anda boleh menghuraikannya dalam format yang anda mahukan. Ini berfungsi sama seperti perpustakaan PDF lain seperti pdfplumber atau pypdf2.
nums = ['0', '૧', '૨', '૩', '૪', '૫', '૬', '૭', '૮', '૯'] def process_text(page_num, e_text): obj = None last_surname = None last_kramank = None print(f"processing page {page_num}..") for line in e_text.splitlines(): line = line.replace('|', '').replace('[', '').replace(']', '') parts = [word for word in line.split(' ') if word] if len(parts) == 0: continue new_rec = True for char in parts[0]: if char not in nums: new_rec = False break if len(parts) < 2: continue if new_rec and len(parts[0]) >= 2: # numbered line if len(parts) < 9: continue if obj: records.append(obj) obj = {} last_surname = parts[1] obj['kramank'] = parts[0] last_kramank = parts[0] obj['full_name'] = ' '.join(parts[1:4]) obj['surname'] = parts[1] obj['pdf_page_num'] = page_num + 1 obj['registered_by'] = parts[4] obj['village_vatan'] = parts[5] obj['village_mosal'] = parts[6] if parts[8] == 'વર્ષ': idx = 7 obj['dob'] = parts[idx] + ' વર્ષ' idx += 1 elif len(parts[7]) == 8 and parts[7][2] == '-': idx = 7 obj['dob'] = parts[idx] else: print("warning: no date") idx = 6 obj['marital_status'] = parts[idx+1] obj['extra_fields'] = '::'.join(parts[idx+2:-2]) obj['blood_group'] = parts[-1] elif parts[0] == last_surname: # new member in existing family if obj: records.append(obj) obj = {} obj['kramank'] = last_kramank obj['surname'] = last_surname obj['full_name'] = ' '.join(parts[0:3]) obj['pdf_page_num'] = page_num + 1 obj['registered_by'] = parts[3] obj['village_vatan'] = parts[4] obj['village_mosal'] = parts[5] if len(parts) <= 6: continue if parts[7] == 'વર્ષ': # date exists idx = 6 obj['dob'] = parts[idx] + ' વર્ષ' idx += 1 elif len(parts[6]) == 8 and parts[6][2] == '-': idx = 6 obj['dob'] = parts[idx] else: print("warning: no date") idx = 5 obj['marital_status'] = parts[idx+1] obj['extra_fields'] = '::'.join(parts[idx+2:-2]) obj['blood_group'] = parts[-1] elif obj: # continuation lines if ("(" in line and ")" in line) or "મો.ઃ" in line: obj['extra_fields'] += ' ' + '::'.join(parts[0:]) if obj: records.append(obj) jstr = json.dumps(records, indent=4) open("guj.json", 'w', encoding='utf-8').write(jstr) print(f"written page {page_num} to json..")
Setiap PDF mempunyai nuansa tersendiri yang mesti diambil kira. Dalam kes ini, nombor siri baharu (seperti 0૧ atau 0૨) dalam medan pertama menandakan kumpulan baharu apabila medan seterusnya (nama keluarga) bertukar.
pytesseract ialah bukti evolusi dan kemajuan dalam teknologi IT. Kira-kira sedekad yang lalu, membaca atau menghuraikan imej PDF menggunakan OCR dalam bahasa bukan bahasa Inggeris pada PC atau komputer riba yang dikonfigurasikan sederhana adalah hampir mustahil. Ini benar-benar kemajuan! Selamat mengekod, dan beritahu saya bagaimana ia berlaku dalam ulasan di bawah.
Atas ialah kandungan terperinci Membuka Kunci Teks daripada PDF Fon Terbenam: Tutorial OCR pytesseract. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!