0Pricing
AI Engineering Academy · บทเรียน

การโหลดเอกสารและการดึงข้อความ

โหลด PDF เอกสาร Word และไฟล์ข้อความธรรมดาด้วยไลบรารี Python ทำความสะอาดข้อความที่ดึงได้ และเตรียมข้อความสำหรับแบ่งส่วนและสร้างเวกเตอร์ฝังตัว

การโหลดเอกสารและการดึงข้อความ เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดการโหลดเอกสารจึงไม่ใช่เรื่องง่าย

ขั้นแรกของกระบวนการ RAG ใด ๆ คือการนำข้อความดิบออกจากเอกสารของคุณ ฟังดูเหมือนง่าย แต่ในทางปฏิบัติกลับซับซ้อนกว่าที่คาดไว้ ไฟล์ PDF อาจฝังข้อความเป็นอักขระ เป็นรูปภาพ หรือเป็นทั้งสองแบบผสมกัน เอกสาร Word มีมาร์กอัปการจัดรูปแบบที่คุณต้องลบออก หน้า HTML มีเมนูนำทางและโฆษณาอยู่ร่วมกับเนื้อหาจริง ตัวโหลดที่มีประสิทธิภาพต้องรองรับทุกกรณีเหล่านี้ และสร้างข้อความที่สะอาดและต่อเนื่องสำหรับการแบ่งเป็นชิ้นข้อมูล

การโหลด PDF ด้วย pypdf

pypdf เป็นไลบรารี Python มาตรฐานสำหรับอ่านไฟล์ PDF ที่มีข้อความฝังอยู่ ไลบรารีนี้ดึงข้อความทีละหน้า โดยรักษาขอบเขตเดิมของแต่ละหน้าไว้ ซึ่งเป็นเมทาดาทาที่มีประโยชน์ อย่างไรก็ตาม pypdf ไม่สามารถอ่าน PDF ที่สแกนมา (รูปภาพของข้อความ) ได้ เพราะไฟล์เหล่านั้นต้องใช้ OCR ควรดึงหมายเลขหน้ามาพร้อมกับข้อความเสมอ เพื่อให้คุณอ้างอิงหน้าที่แน่นอนได้ในการอ้างอิงแหล่งที่มาของ RAG

from pypdf import PdfReader

def load_pdf(file_path):
    reader = PdfReader(file_path)
    pages = []
    for page_num, page in enumerate(reader.pages, start=1):
        text = page.extract_text()
        if text and text.strip():  # skip blank pages
            pages.append({
                'text': text,
                'metadata': {
                    'source': file_path,
                    'page': page_num,
                    'doc_type': 'pdf'
                }
            })
    return pages

docs = load_pdf('annual_report.pdf')
print(f'Loaded {len(docs)} non-empty pages')

การโหลดเอกสาร Word ด้วย python-docx

ไฟล์ Microsoft Word (.docx) จัดเก็บเนื้อหาในรูปแบบ XML ไลบรารี python-docx จะวิเคราะห์ XML นี้และเปิดให้เข้าถึงย่อหน้า ตาราง และหัวข้อในรูปออบเจ็กต์ Python ดึงข้อความของย่อหน้าตามลำดับ และเก็บระดับของหัวข้อไว้เพื่อรักษาโครงสร้างเอกสาร หัวข้อส่วนต่าง ๆ เป็นบริบทที่มีประโยชน์ ซึ่งช่วยปรับปรุงคุณภาพการแบ่งและการค้นคืนเมื่อใส่หัวข้อเหล่านั้นไว้ร่วมกับข้อความที่หัวข้อเริ่มต้น

from docx import Document

def load_docx(file_path):
    doc = Document(file_path)
    sections = []
    current_section = {'heading': '', 'text': ''}

    for para in doc.paragraphs:
        if para.style.name.startswith('Heading'):
            if current_section['text'].strip():
                sections.append(current_section.copy())
            current_section = {'heading': para.text, 'text': ''}
        else:
            current_section['text'] += para.text + '\n'

    if current_section['text'].strip():
        sections.append(current_section)

    return [{'text': f"{s['heading']}\n{s['text']}",
             'metadata': {'source': file_path, 'section': s['heading']}}
            for s in sections]

การโหลดหน้าเว็บและ HTML

หน้า HTML มี เนื้อหาส่วนเกิน อยู่มาก เช่น แถบนำทาง ส่วนท้าย แบนเนอร์คุกกี้ และบล็อกโฆษณา ใช้ BeautifulSoup เพื่อวิเคราะห์ HTML และดึงเฉพาะพื้นที่เนื้อหาหลัก เลือกองค์ประกอบอย่าง <article>, <main> หรือคลาส CSS ที่เจาะจงกับเนื้อหา ลบแท็กสคริปต์ สไตล์ และการนำทางก่อนดึงข้อความ เพื่อไม่ให้ชิ้นข้อมูลของคุณปนเปื้อนด้วยโค้ด JavaScript หรือรายการเมนู

import requests
from bs4 import BeautifulSoup

def load_url(url):
    response = requests.get(url, timeout=10)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, 'html.parser')

    # Remove noise elements
    for tag in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
        tag.decompose()

    # Try to find main content
    main = soup.find('article') or soup.find('main') or soup.find('body')
    text = main.get_text(separator='\n', strip=True)

    return [{'text': text, 'metadata': {'source': url, 'doc_type': 'html'}}]

การจัดการ PDF ที่สแกนด้วย OCR

ไฟล์ PDF ที่สแกนจะจัดเก็บแต่ละหน้าเป็นรูปภาพโดยไม่มีข้อความฝังอยู่ หากต้องการดึงข้อความออกมา คุณต้องใช้ การรู้จำอักขระด้วยแสง (OCR) ไลบรารี pytesseract เป็นตัวห่อหุ้มเอนจิน Tesseract OCR ของ Google โดย OCR ทำงานช้ากว่าและมีความแม่นยำน้อยกว่าการดึงข้อความ (มีความแม่นยำระดับอักขระ 80-95% สำหรับการสแกนคุณภาพดี) ดังนั้นควรเลือกใช้ไฟล์ PDF ดิจิทัลเสมอเมื่อมีให้ใช้ ระบุในข้อมูลเมทาดาทาว่าใช้ OCR เพื่อให้คุณตรวจสอบข้อความที่ดึงออกมาและมีความเชื่อมั่นต่ำได้

import pytesseract
from pdf2image import convert_from_path

def load_scanned_pdf(file_path):
    # Convert PDF pages to PIL images
    pages_as_images = convert_from_path(file_path, dpi=300)
    results = []
    for page_num, img in enumerate(pages_as_images, start=1):
        text = pytesseract.image_to_string(img, lang='eng')
        results.append({
            'text': text,
            'metadata': {
                'source': file_path,
                'page': page_num,
                'ocr': True  # flag for quality review
            }
        })
    return results

การใช้ Unstructured กับทุกรูปแบบ

ไลบรารี unstructured เป็นเครื่องมืออเนกประสงค์สำหรับโหลดเอกสาร โดยรองรับ PDF, Word, Excel, PowerPoint, HTML อีเมล และรูปแบบอื่น ๆ ผ่านส่วนติดต่อ API แบบรวมเป็นหนึ่งเดียว ไลบรารีนี้ใช้หลักการวิเคราะห์แบบฮิวริสติกเพื่อระบุองค์ประกอบของเอกสาร (ชื่อเรื่อง ข้อความบรรยาย ตาราง ส่วนหัว) แล้วส่งคืนเป็นออบเจ็กต์ที่มีโครงสร้าง วิธีนี้มีประโยชน์เป็นพิเศษเมื่อคลังเอกสารของคุณมี เอกสารหลายประเภทปะปนกัน และคุณต้องการเมทาดาทาในระดับองค์ประกอบโดยไม่ต้องเขียนตัวแยกวิเคราะห์เฉพาะรูปแบบ

from unstructured.partition.auto import partition

def load_any_document(file_path):
    elements = partition(filename=file_path)
    docs = []
    for element in elements:
        docs.append({
            'text': str(element),
            'metadata': {
                'source': file_path,
                'element_type': type(element).__name__,
                'category': element.category
            }
        })
    return docs

# Works on .pdf, .docx, .pptx, .html, .eml, .xlsx
docs = load_any_document('presentation.pptx')

การทำความสะอาดข้อความหลังการดึงข้อมูล

ข้อความดิบที่ดึงออกมาแทบไม่เคยสะอาดเรียบร้อย การดึงข้อความจาก PDF มักทำให้เกิด การตัดบรรทัดตรงยัติภังค์จากการจัดวางแบบหลายคอลัมน์ ช่องว่างส่วนเกิน ส่วนหัวหน้าที่ซ้ำกันทุกหน้า และอักขระพิเศษที่ผิดเพี้ยน ให้ใช้กระบวนการทำความสะอาด โดยลบช่องว่างที่มากเกินไป เชื่อมคำที่ถูกตัดด้วยยัติภังค์ข้ามการขึ้นบรรทัดใหม่ ลบส่วนหัวและท้ายหน้าที่ระบุได้จากการจับคู่รูปแบบ และทำอักขระ Unicode ให้เป็นรูปแบบมาตรฐาน ข้อความที่สะอาดช่วยให้ชิ้นข้อความมีความต่อเนื่องสอดคล้องกันดีขึ้นอย่างมาก

import re

def clean_text(text):
    # Rejoin hyphenated line breaks (PDF column artifacts)
    text = re.sub(r'-(\n)([a-z])', r'\2', text)
    # Normalize whitespace
    text = re.sub(r' +', ' ', text)
    text = re.sub(r'\n{3,}', '\n\n', text)
    # Remove page numbers standing alone on a line
    text = re.sub(r'^\d+$', '', text, flags=re.MULTILINE)
    # Strip leading/trailing whitespace from each line
    lines = [line.strip() for line in text.split('\n')]
    return '\n'.join(lines).strip()

การโหลดจากฐานข้อมูลและ API

แหล่งความรู้ไม่ได้อยู่ในไฟล์ทั้งหมด ฐานข้อมูลภายใน ระบบ CRM เครื่องมือจัดการบัตรแจ้งปัญหา และ REST API ก็เป็นแหล่งข้อมูลเช่นกัน ให้โหลดแถวข้อมูลที่มีโครงสร้างจากฐานข้อมูลโดยเชื่อมตารางที่เกี่ยวข้อง แล้วนำค่าของฟิลด์มาต่อกันเป็นย่อหน้าภาษาธรรมชาติที่โมเดลการฝังเวกเตอร์เข้าใจได้ สำหรับ API ให้ดึงผลลัพธ์แบบแบ่งหน้า แล้วแปลงข้อมูลแต่ละระเบียนเป็นเอกสารข้อความที่มีคู่คีย์-ค่า

import psycopg2

def load_from_database(conn_string, query):
    conn = psycopg2.connect(conn_string)
    cursor = conn.cursor()
    cursor.execute(query)
    columns = [desc[0] for desc in cursor.description]
    docs = []
    for row in cursor.fetchall():
        # Convert row to natural language text
        parts = [f'{col}: {val}' for col, val in zip(columns, row) if val]
        text = '\n'.join(parts)
        docs.append({'text': text, 'metadata': {'source': 'database'}})
    conn.close()
    return docs

การติดตามแหล่งที่มาของเอกสาร

เอกสารทุกฉบับที่โหลดเข้ามาควรมี เมทาดาทาแหล่งที่มา ติดไปตลอดกระบวนการทั้งหมด ได้แก่ URL ต้นทางหรือเส้นทางไฟล์ ชื่อเอกสาร ผู้เขียน วันที่สร้าง และวันที่แก้ไขล่าสุด เมทาดาทานี้จะติดไปกับชิ้นข้อความแต่ละชิ้นเข้าสู่ที่จัดเก็บเวกเตอร์ และปรากฏในข้อมูลอ้างอิงของ LLM หากไม่มีแหล่งที่มา คุณจะบอกผู้ใช้ไม่ได้ว่าคำตอบมาจากที่ใด ไม่สามารถอัปเดตเอกสารเฉพาะรายการในดัชนี และไม่สามารถกรองการค้นคืนตามคุณลักษณะของแหล่งที่มาได้

import os
from datetime import datetime

def load_pdf_with_provenance(file_path):
    from pypdf import PdfReader
    reader = PdfReader(file_path)
    stat = os.stat(file_path)
    base_metadata = {
        'source': file_path,
        'title': reader.metadata.get('/Title', os.path.basename(file_path)),
        'author': reader.metadata.get('/Author', 'Unknown'),
        'doc_type': 'pdf',
        'file_size_kb': stat.st_size // 1024,
        'loaded_at': datetime.utcnow().isoformat()
    }
    pages = []
    for i, page in enumerate(reader.pages, 1):
        text = page.extract_text()
        if text and text.strip():
            pages.append({'text': text, 'metadata': {**base_metadata, 'page': i}})
    return pages

การโหลดชุดเอกสารขนาดใหญ่เป็นชุด

เมื่อสร้างดัชนีเอกสารหลายพันฉบับ ให้โหลดเอกสารเหล่านั้น แบบขนาน โดยใช้ concurrent.futures เพื่อใช้ทรัพยากร I/O และ CPU ได้เต็มประสิทธิภาพ จัดทำตัวติดตามความคืบหน้าและบันทึกข้อผิดพลาด เพื่อไม่ให้เอกสารที่โหลดไม่สำเร็จหายไปจากดัชนีโดยไม่มีการแจ้งเตือน อย่าปล่อยให้ไฟล์ที่เสียหายเพียงไฟล์เดียวทำให้งานโหลดทั้งหมดหยุดทำงาน — ดักจับข้อยกเว้นแยกตามเอกสาร แล้วดำเนินการกับเอกสารถัดไป

from concurrent.futures import ThreadPoolExecutor, as_completed

def batch_load_documents(file_paths, max_workers=8):
    all_docs = []
    errors = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_path = {
            executor.submit(load_pdf_with_provenance, p): p
            for p in file_paths
        }
        for future in as_completed(future_to_path):
            path = future_to_path[future]
            try:
                docs = future.result()
                all_docs.extend(docs)
                print(f'Loaded {len(docs)} pages from {path}')
            except Exception as e:
                errors.append({'path': path, 'error': str(e)})
    return all_docs, errors

การตรวจสอบคุณภาพเนื้อหาที่โหลด

หลังจากโหลดแล้ว ให้ตรวจสอบว่าคุณดึงเนื้อหาที่มีความหมายออกมาได้ ให้ตรวจสอบสิ่งต่อไปนี้: ความยาวข้อความขั้นต่ำ (ข้ามชิ้นข้อความที่มีอักขระน้อยกว่า 50 ตัว) การตรวจจับภาษา (หาก RAG ของคุณรองรับเฉพาะภาษาอังกฤษ ให้กรองหน้าที่ไม่ใช่ภาษาอังกฤษออก) และ การตรวจจับข้อความที่ผิดเพี้ยน (อัตราส่วนอักขระที่ไม่ใช่ ASCII สูงอาจบ่งชี้ว่า OCR ล้มเหลวหรือเกิดปัญหาการเข้ารหัส) บันทึกสถิติต่าง ๆ เช่น จำนวนหน้าที่โหลด ความยาวหน้าโดยเฉลี่ย และอัตราข้อผิดพลาด เพื่อให้ตรวจพบปัญหาการโหลดได้ตั้งแต่เนิ่น ๆ

def validate_documents(docs, min_length=100):
    valid = []
    skipped = 0
    for doc in docs:
        text = doc['text']
        if len(text) < min_length:
            skipped += 1
            continue
        # Check for high non-ASCII ratio (garbled OCR)
        non_ascii = sum(1 for c in text if ord(c) > 127)
        if non_ascii / max(len(text), 1) > 0.3:
            skipped += 1
            continue
        valid.append(doc)
    print(f'Valid: {len(valid)}, Skipped: {skipped}')
    return valid

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจแนวคิดวิศวกรรม AI จากบทเรียนนี้

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้เกี่ยวกับ ตัวโหลดเฉพาะรูปแบบสำหรับ PDF ด้วย pypdf เอกสาร Word ด้วย python-docx, HTML ด้วย BeautifulSoup และเอกสารที่สแกนด้วย OCR รวมถึง ไลบรารี unstructured ในฐานะตัวโหลดเอกสารหลายรูปแบบแบบรวมเป็นหนึ่งเดียว และ แนวปฏิบัติที่ดีสำหรับระบบจริง ซึ่งครอบคลุมการทำความสะอาดข้อความ เมทาดาทาแหล่งที่มา การโหลดเป็นชุดแบบขนาน และการตรวจสอบเนื้อหา บทถัดไปเราจะจัดการกลยุทธ์การแบ่งชิ้นข้อความ ซึ่งเป็นตัวกำหนดว่าข้อความที่ค้นคืนมาจะเชื่อมโยงกับบริบทของโมเดลอย่างไร

คำถามที่พบบ่อย

บทเรียน “การโหลดเอกสารและการดึงข้อความ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การโหลดเอกสารและการดึงข้อความ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การโหลดเอกสารและการดึงข้อความ”

โหลด PDF เอกสาร Word และไฟล์ข้อความธรรมดาด้วยไลบรารี Python ทำความสะอาดข้อความที่ดึงได้ และเตรียมข้อความสำหรับแบ่งส่วนและสร้างเวกเตอร์ฝังตัว คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การโหลดเอกสารและการดึงข้อความ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม

ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การโหลดเอกสารและการดึงข้อความ
  2. กลยุทธ์การแบ่งส่วน: ขนาดคงที่ เทียบกับประโยค เทียบกับแบบเรียกซ้ำ
  3. การทำดัชนี: การสร้างและจัดเก็บส่วนข้อความ
  4. ค้นคำค้น คืนข้อมูล และสร้างคำตอบ
← กลับไปที่ AI Engineering Academy