Indlæsning af dokumenter og tekstudtræk
Indlæs PDF'er, Word-dokumenter og almindelige tekstfiler ved hjælp af Python-biblioteker, rens den udtrukne tekst, og gør den klar til opdeling i bidder og embedding.
Indlæsning af dokumenter og tekstudtræk er en gratis AI Engineering Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i AI Engineering Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. AI Engineering Academy-kurset indeholder 4 lektioner i alt.
Hvorfor dokumentindlæsning ikke er enkelt
Det første trin i enhver RAG-pipeline er at hente rå tekst ud af dine dokumenter. Det lyder enkelt, men er overraskende vanskeligt i praksis. PDF-filer kan indeholde tekst som tegn, som billeder eller som en blanding af begge dele. Word-dokumenter indeholder formateringsmarkering, som du skal fjerne. HTML-sider indeholder navigationsmenuer og annoncer sammen med det egentlige indhold. En robust indlæser skal håndtere alle disse tilfælde og producere ren, sammenhængende tekst til opdeling i tekststykker.
Indlæsning af PDF-filer med pypdf
pypdf er standardbiblioteket i Python til læsning af PDF-filer, der indeholder indlejret tekst. Det udtrækker tekst side for side og bevarer de oprindelige sidegrænser, som er værdifulde metadata. pypdf kan dog ikke læse scannede PDF-filer (billeder af tekst) — de kræver OCR. Udtræk altid sidetal sammen med teksten, så du kan henvise til den præcise side i dine RAG-kildehenvisninger.
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')Indlæsning af Word-dokumenter med python-docx
Microsoft Word-filer (.docx) gemmer indhold i XML-format. Biblioteket python-docx fortolker denne XML og stiller afsnit, tabeller og overskrifter til rådighed som Python-objekter. Udtræk afsnitsteksten sekventielt, og registrér overskriftsniveauer for at bevare dokumentstrukturen — sektionsoverskrifter er værdifuld kontekst, der forbedrer kvaliteten af opdeling i tekststykker og hentning, når de inkluderes sammen med den tekst, de introducerer.
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]Indlæsning af websider og HTML
HTML-sider indeholder meget støj: navigationsbjælker, sidefødder, cookiebannere og annonceblokke. Brug BeautifulSoup til at fortolke HTML og udtrække kun hovedindholdsområdet. Målret elementer som <article>, <main> eller indholdsspecifikke CSS-klasser. Fjern script-, style- og nav-tags, før du udtrækker tekst, så du undgår at forurene dine tekststykker med JavaScript-kode eller menupunkter.
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'}}]Håndtering af scannede PDF-filer med OCR
Scannede PDF-filer gemmer sider som billeder uden indlejret tekst. Hvis du vil udtrække tekst, skal du bruge Optical Character Recognition (OCR). Biblioteket pytesseract fungerer som en wrapper omkring Googles Tesseract OCR-motor. OCR er langsommere og mindre præcist end tekstudtræk (80-95 % tegnpræcision ved gode scanninger), så vælg altid digitale PDF-filer, når de er tilgængelige. Angiv i metadataene, når OCR er blevet brugt, så du kan gennemgå udtræk med lav sikkerhed.
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 resultsBrug af Unstructured til alle formater
Biblioteket unstructured er en schweizerkniv til indlæsning af dokumenter og håndterer PDF-filer, Word, Excel, PowerPoint, HTML, e-mails og meget mere via en samlet API. Det bruger heuristikker til at identificere dokumentelementer (titel, brødtekst, tabel, sidehoved) og returnerer dem som strukturerede objekter. Det er især nyttigt, når dit korpus indeholder blandede dokumenttyper, og du ønsker metadata på elementniveau uden at skrive format-specifikke parsere.
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')Rensning af tekst efter udtræk
Rå tekst fra et udtræk er sjældent ren. PDF-udtræk resulterer ofte i linjeskift med bindestreger fra spaltelayouts, ekstra mellemrum, sidehoveder, der gentages på hver side, og forvanskede specialtegn. Anvend en rensepipeline: fjern overflødige mellemrum, saml ord med bindestreger på tværs af linjeskift igen, fjern sidehoveder og sidefødder, der identificeres via mønstergenkendelse, og normalisér Unicode-tegn. Ren tekst giver markant bedre sammenhæng mellem tekststykker.
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()Indlæsning fra databaser og API'er
Al viden findes ikke i filer. Interne databaser, CRM-systemer, supportsystemer og REST-API'er er også kilder. Indlæs strukturerede databas rækker ved at forbinde relevante tabeller og sammenkæde feltværdier til afsnit i naturligt sprog, som indlejringsmodellen kan forstå. Hent paginerede resultater fra API'er, og serialisér hver post som et tekstdokument med nøgle-værdi-par.
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 docsSporing af dokumenternes oprindelse
Alle indlæste dokumenter bør have metadata om oprindelse gennem hele pipelinen: kilde-URL eller filsti, dokumenttitel, forfatter, oprettelsesdato og seneste ændringsdato. Disse metadata følger hvert tekststykke ind i vektorlageret og vises i LLM-citater. Uden oplysninger om oprindelse kan du ikke fortælle brugerne, hvor et svar kom fra, du kan ikke opdatere bestemte dokumenter i indekset, og du kan ikke filtrere hentningen efter kildeattributter.
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 pagesBatchindlæsning af store dokumentsamlinger
Når du indekserer tusindvis af dokumenter, skal du indlæse dem parallelt ved hjælp af concurrent.futures for at udnytte I/O- og CPU-ressourcerne fuldt ud. Implementér en fremdriftsmåler og en fejllog, så mislykkede dokumentindlæsninger ikke lydløst fjerner indhold fra dit indeks. Lad aldrig en enkelt beskadiget fil få hele indlæsningsjobbet til at gå ned — fang undtagelser for hvert dokument, og fortsæt med det næste.
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, errorsValidering af kvaliteten af indlæst indhold
Efter indlæsningen skal du kontrollere, at du har udtrukket meningsfuldt indhold. Kontrollér: minimumslængde for tekst (spring tekststykker med færre end 50 tegn over), sprogidentifikation (hvis din RAG kun understøtter engelsk, skal du filtrere sider, der ikke er på engelsk), og identifikation af forvansket tekst (en høj andel af ikke-ASCII-tegn kan tyde på OCR-fejl eller problemer med tegnkodningen). Log statistikker som antal indlæste sider, gennemsnitlig sidelængde og fejlrate for at opdage problemer med indlæsningen tidligt.
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 validHurtigt tjek
Test din forståelse af begreberne inden for AI Engineering fra denne lektion.
Opsummering af lektionen
I denne lektion har du lært om: format-specifikke indlæsere til PDF-filer med pypdf, Word-dokumenter med python-docx, HTML med BeautifulSoup og scannede dokumenter med OCR, biblioteket unstructured som en samlet indlæser til flere formater samt bedste praksis til produktion, herunder tekstrensning, metadata om oprindelse, parallel batchindlæsning og validering af indhold. Næste gang tager vi fat på strategier for opdeling i tekststykker, som afgør, hvordan hentet tekst mappes til modellens kontekst.
Lær Python med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “Indlæsning af dokumenter og tekstudtræk” gratis?
Ja — hele teksten til “Indlæsning af dokumenter og tekstudtræk” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af AI Engineering Academy-kurset, skal du opgradere til CoddyKit PRO. AI Engineering Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Indlæsning af dokumenter og tekstudtræk”?
Indlæs PDF'er, Word-dokumenter og almindelige tekstfiler ved hjælp af Python-biblioteker, rens den udtrukne tekst, og gør den klar til opdeling i bidder og embedding. Du øver dig i AI Engineering Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på AI Engineering Academy?
Der kræves ingen tidligere erfaring. AI Engineering Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Indlæsning af dokumenter og tekstudtræk”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne AI Engineering Academy-lektion?
Ja. Alle AI Engineering Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Indlæsning af dokumenter og tekstudtræk
- Strategier til opdeling: Fast størrelse, sætninger og rekursion
- Indeksering: Embedding og lagring af bidder
- Forespørg, hent, og generér