Ebizapple
Ta kontakt Logg inn i kundeportalen

+47 464 69 500 [email protected]

ProduktdataPDFBildematching

Produktdata ut av en PDF-katalog: løsningen lå i fontvekten

En PDF-katalog på tolv megabyte inn, nittitre produkter ut. Bildene koblet vi på til slutt — og løsningen lå i fontvekten, ikke i posisjonen.

Daglig leder, Ebizapple Oppdatert 16 min lesetid
Diagram «pdf-ekstraksjon»: Fontvekten avgjorde hvilket bilde som hørte til, badge halvfet, liste normal, samme tall, ulik vekt

Vi hadde nettopp fått en PDF-katalog på tolv megabyte gjennom kverna. Nittitre produkter ut i den andre enden, med navn, artikkelnummer, pris og kategori. Hundre og ti bilder fra samme fil.

Så koblet vi bildene til produktene, og oppdaget at alle produktene på samme side hadde fått det samme bildet.

Regelen vi hadde brukt var «ta det største bildet på siden». Rimelig når det er ett produkt per side, verdiløs når det er åtte.

Artikkelen handler om hvorfor det skjer, hva som løste det, og hva du gjør når to systemer beskriver samme produkt med hvert sitt navn.


Diagram «pdf-ekstraksjon»: 1, 2, 3, 4, 5, 6, 7, 8, badge   halvfet, liste   normal, samme tall, ulik vekt, PDF-EKSTRAKSJON
Skisse av en katalogside der åtte bildemerker i halvfet skiller seg fra listetall i normal vekt

Kort vei til svaret: har du en katalog eller prisliste som skal bli til data, send oss en prøvefil — vi sier hva som lar seg hente og hva som ikke gjør det. Vil du forstå mekanikken selv, les videre.

Slik vurderer vi uttrekket fra en PDF

Denne artikkelen bygger på arbeid vi har gjort selv, i to spor: en pipeline som henter produktdata og bilder ut av leverandørkataloger, og uttrekksjobber som leser kampanjeaviser side for side. Tallene er lest av fra kjøringene, ikke anslått i etterkant.

Det er verdt å si hva dette ikke er:

  • Vi lover ingen treffprosent på forhånd. Tallene gjelder den katalogen de ble målt på, med den typografien den hadde
  • Terskler som virker på ett dokumentdesign, må ofte kalibreres på nytt for det neste. Vi har ikke regnet gjennomsnitt over hundre kataloger
  • Kildedokumentene og kundenes data er ikke gjengitt her
  • Produktene som ikke lot seg koble sikkert, ble merket som usikre i grensesnittet — de blir ikke skjult her heller

Det vi kan stå inne for: hver mekanisme under er bygget og kjørt, og hvert stoppunkt er et vi faktisk traff.

Formater og verktøy endrer seg. Artikkelen gjennomgås derfor hver gang formatene eller verktøyene endrer seg. Sist gjennomgått 14. august 2026.

Skrevet av Svein Tore Olsen, daglig leder i Ebizapple.


Diagram «En PDF beskriver utseende»: En PDF beskriver utseende, Setningen hele artikkelen hviler på, SLIK SER DU, 01
Alt som er vanskelig med PDF-uttrekk følger av denne ene forskjellen.

En PDF er et layoutformat, ikke et dataformat

Dette er den ene setningen hele artikkelen hviler på.

Når du åpner en pdf-katalog og ser en tabell, ser du ikke en tabell. Du ser tekstbokser plassert på hvert sitt punkt i et koordinatsystem, med hver sin skrifttype og punktstørrelse. At de danner rader og kolonner for øyet ditt, er et resultat av at noen plasserte dem pent — ikke av at filen vet at de hører sammen. Formatet beskriver utseende, ikke betydning.

Praktiske konsekvenser, i den rekkefølgen de pleier å overraske folk:

Leserekkefølgen er ikke logisk rekkefølge. Tekstbokser ligger i den rekkefølgen de ble skrevet inn i filen — kolonnevis, tilfeldig, eller hoppende mellom to spalter. Kopierer du en tabell inn i et regneark, får du ofte noe som ser ut som data, men der prisen tilhører feil produkt.

En rad er ikke en enhet. «Lager 6308 · 2RS · 349,00» kan være tre tekstbokser, eller én, eller sju. Det ser du bare på koordinatene.

Det som ser likt ut, kan være ulikt. To tall i samme kolonne kan ha ulik skrifttype fordi det ene er et listenummer og det andre noe annet. Øyet ditt filtrerer det bort. En maskin gjør ikke det — med mindre du ber den om det. Der lå løsningen på bildeproblemet vårt.

Noen PDF-er har ikke tekst i det hele tatt. En skannet katalog er bilder av sider. Da bytter du et strukturproblem mot et lesefeilproblem.

Det er samme skille vi beskriver i gjennomgangen av å hente produktdata fra en nettside: forskjellen mellom det et menneske ser og det en maskin får utlevert, er større enn folk tror. Der var det DOM-en mot HTML-en. Her er det layout mot data.


Fire veier ut av dokumentet

Det finnes fire, og vi har brukt alle. Oftest to sammen.

Metode Passer når Bryter sammen når
Koordinater og font — les tekstlaget med posisjon og skrifttype Dokumentet er maskingenerert, typografien konsekvent Malen skifter midt i katalogen, eller filen er skannet
Regeluttrekk — flat teksten ut og kjør et mønster over den Radene har fast form: «tekst, datointervall, pris, kr» Ett produkt mangler pris, eller et navn ligner et datointervall
Språkmodell — send dokumentet inn, be om strukturerte felter Layouten er uryddig og feltene varierer fra side til side Du trenger garantert samme svar hver gang
Tekstgjenkjenning — les sidene som bilder Dokumentet er skannet, uten tekstlag Trykket er dårlig, eller 0/O og 1/l må skilles presist

Den siste kolonnen er den viktigste. Alle fire virker på et godt dokument. Det er hvordan de svikter som avgjør valget — og særlig om de sier fra når de svikter.

Koordinater og font: presist så lenge malen holder

Har filen et tekstlag, får du mer enn tegnene. Hver tekstboks ligger på et punkt i et koordinatsystem, med sin egen skrifttype og punktstørrelse — og alt det er data du kan sortere på. Det er slik en «rad» i det hele tatt lar seg gjenskape: ikke fordi filen vet at feltene hører sammen, men fordi de står på samme høyde.

Metoden er den mest presise av de fire når den først treffer, og det var den som til slutt løste bildeproblemet i denne jobben. Prisen er at den arver malen. Skifter katalogen oppsett midt i filen — et innstikk, en annonse, en temaside med annen typografi — slutter regelen å gjelde, og den sier ikke fra. Derfor bruker vi den på dokumenter vi har sett gjennom, ikke på et vedlegg vi mottar for første gang.

Regeluttrekk: billig, presist, og sprøtt

Kampanjeavisene er det reneste eksempelet. Jobben vår henter siden, stripper bort all markering, klipper ut strekket mellom to faste overskrifter og kjører ett mønster over resten som plukker ut varenavn, gyldighetsperiode og pris.

Det kjører på sekunder og koster nesten ingenting. Det er også helt avhengig av at avisen har akkurat de to overskriftene, og at hver linje har de tre feltene i den rekkefølgen. Fjernes den ene overskriften, står du igjen med tom tekst.

Vi bygde også et hjelpeledd: én jobb som finner avisens interne løpenummer i sidekoden, slik at ingen må klippe det ut manuelt for hver nye avis. Slike kjedelige mellomledd avgjør om en automatisering kjører av seg selv eller krever en person hver mandag.

Språkmodell: robust mot rot, svak på gjentakelse

For dokumenter uten fast mal sender vi hele PDF-en inn til en språkmodell og ber om strukturerte felter tilbake — der kategorien må være én av en lukket liste, ikke fritekst.

To grep skiller noe som virker fra noe som ser ut som det virker:

Be om struktur, ikke om tekst som ser strukturert ut. Ber du en modell skrive JSON som fritekst, holder det lenge — helt til ett uunnslupt anførselstegn ødelegger hele svaret.

Regn ut summene selv. Antall, prisintervall, kategoritelling — alt som kan utledes av dataene, skal utledes av koden etterpå. Modellen skal levere radene, ikke telle dem.

Et tredje grep handler ikke om teknikk: hvert uttrukket produkt får et konfidensnivå og lander i en liste merket «til gjennomgang».

Tekstgjenkjenning: OCR når tekstlaget mangler

De tre veiene over leser tekst som allerede står i filen. En skannet katalog er bilder av sider, og da står ikke den teksten der. Igjen står tekstgjenkjenning — OCR — som leser sidene som bilder og gjetter seg frem til tegnene.

Forskjellen på tekstlag og OCR er ikke en gradsforskjell. Et tekstlag gir deg tegnene slik de ble satt, med skrifttype og posisjon på kjøpet. OCR gir deg en kvalifisert gjetning per tegn, uten typografien som de andre metodene lener seg på — og gjetningen er svakest der det koster mest: 0 mot O og 1 mot l, i artikkelnumre som ikke betyr noe og derfor ikke kan avsløre en feil ved å se rart ut.

Vi sier ikke nei til skannede dokumenter, men vi regner alltid med korrektur på dem, og verifiserer numrene mot en kjent liste før de får lov til å bli data. Er det et valg mellom OCR og å be leverandøren om den samme katalogen med tekstlag, er det siste alltid billigere.


Har du en katalog som skal bli til data? Vi ser på en prøvefil og sier hva som er mulig — og hva som blir dyrt. Be om en vurdering.


Når du bør gi opp og be om et dataeksport

Dette er rådet vi gir oftest, og det som selger dårligst.

En PDF er alltid avledet. Noen har en database et sted, og PDF-en er en utskrift av den. Å hente data ut av utskriften er å gjenskape noe som allerede finnes, med tap.

Så spør. En CSV-fil, et regneark, en ukentlig eksport. Mange leverandører har det liggende. Under står regelen vi bruker før vi sier ja til slikt arbeid.

Situasjon Vi ville Hvorfor
Leverandøren kan sende CSV eller regneark Ta eksporten Ferdige felter slår enhver utgraving, og knekker ikke når malen endres.
Fast mal, skal leses hver uke Bygg regeluttrekk Billigst i drift. Legg inn en sjekk på at det faktisk kom noe ut.
Ett dokument, én gang, femti sider Språkmodell + gjennomgang Å bygge en regel lønner seg ikke for én kjøring.
Dokumentet er skannet Regn med korrektur Artikkelnumre ryker først. Verifiser mot en kjent liste.
Malen skifter mellom sidene Del opp per malvariant Ett mønster som skal dekke alt, dekker ingenting godt.
Tallene skal inn i et system som fakturerer Stopp og be om eksport Feil pris fra et uttrekk er ikke en skrivefeil, det er en faktura.
Du vet ikke hvilken rad som gjelder deg Få dokumentet vurdert Én prøvefil er nok — send den inn.

Legg merke til at «be om eksport» går igjen. Det er ikke beskjedenhet. Det er at en avtalt datakanal er den eneste varianten som fortsatt virker neste år.


Diagram «Tre forsøk på å koble bilde til produkt»: Tre forsøk på å koble bilde til produkt, 01, Største bilde
De to første forsøkene var ikke dumme. De var rimelige antakelser som holdt helt til de ikke gjorde det.

Bildeproblemet, og hva som løste det

Tilbake til produktene som alle fikk samme bilde.

Bildene lå i filen som egne objekter, og vi hentet dem ut med posisjon. Vi filtrerte bort alt under en viss flatestørrelse, ellers drukner du i ikoner, logoer og QR-koder.

Da satt vi med drøyt hundre bilder som visste hvor de var, og nittitre produkter som ikke visste noe om hvor de var. Ingen felles nøkkel.

Så oppdaget vi at katalogen selv hadde løsningen trykt på seg.

Hvert produktbilde hadde et lite tall stemplet på seg. En badge. I prislisten under sto de samme tallene som listenumre. Koblingen fantes — designeren hadde laget den for leseren. Problemet var at tallet «4» på et bilde og tallet «4» i prislisten er samme tegn for en maskin.

Første forsøk var å skille dem på x-posisjon: badges inne i bildeflaten, listenumre i margen. Det virket på de fleste sidene, og feilet der en bildeflate strakte seg over margen. En terskel som er nesten riktig er den verste typen — den gir et resultat som ser fornuftig ut.

Det som virket var fontvekten. Badgene var satt i halvfet, litt større. Listetallene i normal vekt, litt mindre. Ikke fordi noen tenkte på maskinlesing, men fordi det ser bedre ut. Skrifttype og punktstørrelse ligger lagret sammen med hver tekstboks — en visuell detalj for leseren var et entydig skille for koden.

Resultatet: de fleste produktene ble koblet til bildet sitt gjennom en verifiserbar badge. Resten falt tilbake på «største ubrukte bilde på siden» — og ble merket i grensesnittet som nettopp det.

To ting er verdt å ta med videre:

Verifiser koblingen objektivt. Vi sammenlignet sjekksummen på hver bildefil mot koblingstabellen i stedet for å se på skjermen og synes at det så riktig ut. Å se på et resultat er ikke det samme som å måle det.

Ikke skjul de usikre. Et produkt med usikker bildekobling er fortsatt nyttig — hvis den som ser på det vet at det er usikkert. Samme grunn til at vi ikke gir ytelsesgaranti på noe en tredjepart bestemmer.

Teksten hadde samme problem, og samme løsning

Produktbeskrivelsene lå heller ikke merket. Men de lå i sitt eget punktstørrelsessjikt: sidetittel størst, ingress under, produktbeskrivelse under der igjen, spesifikasjoner nederst. Bare mellomsjiktet var teksten vi var ute etter, og vi hentet det ut på punktstørrelse alene.

Ikke alle produktene fikk en beskrivelse. Det var riktig — sider som er rene prislister har ingen redaksjonell tekst. Et uttrekk som ga beskrivelse til alle, ville ha funnet på noe.


Diagram «automatisering»: Tre feller som kostet timer, !, (?<cuid>) med feil hermetegn, BasicAggregator gir {object}
Tre uttrekksfeller: feil hermetegn i mønsteret, aggregert objekt i stedet for tekst, og et filter som spiser æ, ø og å
Diagram «Terskelen er en avveining»: Terskelen er en avveining, FOR LØS TERSKEL, 01, Ulike varer slås sammen, 02
Den venstre feilen er den dyre, nettopp fordi den ser bra ut.

Matching uten felles nøkkel

Nå til det problemet folk faktisk sitter fast i: leverandøren kaller produktet én ting, butikken en annen, og ingen kolonne er lik i begge.

Regel én: navnet er aldri nøkkelen

Det første vi gjør er å slå fast hva som er den kanoniske nøkkelen, og det er aldri produktnavnet.

Navn kolliderer. To varianter av samme produkt kan hete nesten det samme og være ulike varer — ulik størrelse, ulik pris, ulikt artikkelnummer. Matcher du på navn, slår du dem sammen, og ingen oppdager det før noen bestiller feil størrelse.

Artikkelnummeret er nøkkelen. Alt annet er hjelpefelt.

Regel to: matching uten nøkkel er en skala, ikke en bryter

Når det ikke finnes et felles artikkelnummer, må du sammenligne noe uskarpt — som regel hvor mye ordene i to produktnavn overlapper. Da må du velge en terskel, og det er en avveining du ikke kommer unna:

Legg merke til den midterste kolonnen i første rad. For løs matching gir et penere resultat enn riktig matching. Derfor er den farlig. En rapport uten «ikke funnet»-rader ser ferdig ut.

Ett enkelt grep demper problemet: sammenlign bare innenfor samme kategori. Et lager skal ikke kunne matche en reim, uansett hvor mange ord som er felles. Kategorien er et gjerde, og gjerder er billigere enn presisjon. Det andre grepet fortjener sitt eget avsnitt.

Regel tre: forankre i et register

I sourcing-arbeidet for industrikomponenter starter vi med et delenummer og skal ende opp med å vite hvilket selskap som står bak. Kjeden:

  1. Utled merket fra delenummeret. Delenumre er ikke tilfeldige — de fleste produsenter har et gjenkjennelig mønster i begynnelsen.
  2. Oversett merket til et søkbart norsk navn. Merkenavn og selskapsnavn er ofte ikke det samme. Den oversettelsen er en liste noen må vedlikeholde, og den er verdt vedlikeholdet.
  3. Slå opp i Enhetsregisteret. Åpent, offentlig, ett svar per juridisk enhet.
  4. La en dommer velge én av treffene, med eksplisitte regler: foretrekk aksjeselskap og relevant næringskode, utelukk selskaper under avvikling eller konkurs, og utelukk foreninger og lag som tilfeldigvis har et lignende navn.
  5. Skriv tilbake organisasjonsnummeret, ikke navnet.

Etter steg fem er matchingen ikke lenger uskarp. Organisasjonsnummeret er et nisifret tall som enten stemmer eller ikke.

Det er hele poenget: du bruker det uskarpe én gang, for å komme frem til noe skarpt — og deretter bruker du bare det skarpe.

Og det avgjørende: dommeren har lov til å svare «ikke funnet». Da settes ingenting, og raden står igjen synlig uten organisasjonsnummer. Et system som alltid velger noe, ville satt feil nummer på hver rad der merket var ukjent — og ingen ville sett det.

Vi har skrevet en egen artikkel om nettopp den mekanismen, og om hva som skjer når den mangler: når AI går i stå og mennesket legger den siste brikken.


Derfor må et menneske se over grensetilfellene

Uttrukne produkter havner ikke i katalogen, men i en liste med tre automatisk satte felter:

  • et konfidensnivå per produkt — satt lavt når delenummeret var utydelig
  • et evidensnivå som sier at dette er leverandøroppgitt, ikke bekreftet
  • en status som sier «til gjennomgang»

Ingenting går videre uten at noen har sett på det.

Det er fristende å kalle dette en ufullstendig automatisering. Vi mener det motsatte: køen er produktet. Verdien ligger ikke i at maskinen gjetter det siste steget, men i at tusen sider er redusert til noen titalls rader en fagperson kan gå gjennom på en formiddag.

En innkjøper som ser hundre rader merket «høy» og seks merket «lav», bruker tiden på de seks. Den som får hundreogseks umerkede rader, må sjekke alle eller ingen — i praksis ingen. Samme arbeidsdeling som da vi kartla en produktkatalog på en nettside: maskinen tar volumet, mennesket tar resten.


Sitter dere med en leverandørkatalog dere ikke får ut av? Vi tar en titt på filen og sier hva som skal til. Ta kontakt — det koster ingenting å spørre.


Kampanjeaviser: samme problem, tynnere data

Kampanjeaviser ser lettere ut enn de er. En avisside har som regel bare tre felter per linje: hva varen heter, hvor lenge tilbudet gjelder, og hva den koster. Lite data, og derfor lite å kjenne igjen på.

Varenavnet er markedsføring, ikke identifikator. Det samme produktet heter noe annet i hver avis. Derfor blir matchingen over viktig — og derfor bør et treff mot butikkens eget sortiment bekreftes av en person før prisen brukes til noe.

Tomt er ikke det samme som ingen tilbud. Bommer mønsteret, kommer det ut null rader. Null rader betyr «avisen hadde ingen tilbud» og «jobben virket ikke» på nøyaktig samme måte. Den fellen har vi gått i, og behandler den nå som en egen sjekk: en avisside som gir null treff skal varsles, ikke logges.

Dette ligner mest på vanlig datainnhenting fra nettsider: kilden er ikke laget for deg, den kan endres uten varsel, og det eneste du kontrollerer er hvor tydelig du oppdager at den har endret seg.


Metoden, oppsummert

Står du foran samme problem, i denne rekkefølgen:

  1. Spør om en eksport først. PDF-en er en utskrift av noe.
  2. Finn ut om det finnes et tekstlag. Har filen ingen tekst, er du i gang med et helt annet prosjekt.
  3. Se på typografien før du skriver kode. Skrifttype og punktstørrelse er ofte den eneste strukturen som finnes, og den er gratis å lese.
  4. Bestem den kanoniske nøkkelen. Artikkelnummer, ikke navn. Alltid.
  5. Bruk uskarp matching én gang, for å komme frem til noe skarpt.
  6. La systemet ha lov til å si «vet ikke», og merk usikkerheten i grensesnittet. Skjuler du den, har du flyttet risikoen til den som stoler på tallene.

Vi oppgir ikke faste priser på slikt arbeid, fordi kostnaden avgjøres av dokumentet og ikke av oss. Fast mal med tekstlag kan være en dags jobb; samme sidetall skannet, med bilder som skal kobles, er noe helt annet — og forskjellen er ikke synlig fra utsiden. Derfor ber vi om en prøvefil først, og bruker nivåskalaen N1–N5 til vurderingen.

Er dataene først ute, skal de vises et sted: en dynamisk nettside med datakilde bak, eller en WordPress-nettside som tåler innhold utenfra. Å hente og å vise er to jobber.


Spørsmål om produktdata fra PDF-kataloger

Hvorfor blir tabeller rotete når jeg kopierer fra en PDF?

Fordi tabellen ikke finnes i filen. En pdf-katalog lagrer tekstbokser med koordinater og skrifttype, ikke rader og kolonner. Rekkefølgen du får ved kopiering er den boksene ble lagt inn i — ofte kolonnevis eller tilfeldig. Derfor havner prisen på feil produkt.

Kan AI lese en produktkatalog?

Ja, og det er ofte den beste metoden når layouten er uryddig. To forbehold: be om strukturerte felter i stedet for tekst som ser strukturert ut, og regn ut summer og tellinger i egen kode etterpå. Uttrekket bør dessuten få et konfidensnivå per rad og gå til gjennomgang.

Hvordan kobler man et produkt til riktig bilde?

Du trenger noe som binder dem sammen. I katalogen vi jobbet med var det små tall trykt på bildene, som gikk igjen som listenumre i prislisten — og skillet mellom tallgruppene lå i fontvekten. Finnes ingen slik kobling, må du falle tilbake på posisjon, og merke resultatet usikkert.

Hva gjør man når leverandør og butikk har ulike produktnavn?

Match aldri på navn alene. Sammenlign ordoverlapp innenfor samme kategori, sett en terskel, og la alt under den gå til manuell gjennomgang. Bruk der det er mulig det uskarpe treffet til å slå opp en hard identifikator — og bruk deretter bare den.

Hva er forskjellen på for løs og for streng matching?

For streng matching gir færre treff, og alle ser det med en gang. For løs matching gir feil treff, og det ser ingen — resultatet er pent, men to ulike varer er slått sammen. Derfor legger vi grensetilfellene i kø framfor å justere terskelen til rapporten ser fin ut.

Kan dere ikke bare konvertere PDF-en til Excel?

Det finnes verktøy som gjør det, og på et enkelt dokument med fast mal fungerer de. På en katalog med flere maler gir de et regneark som ser riktig ut og har feil i seg. Problemet er flyttet, ikke løst.


Videre lesing om uttrekk fra dokumenter

Har dere en katalog, prisliste eller kampanjeavis som skal bli til data? Send oss en prøvefil, så sier vi hva som lar seg gjøre — og hva som ikke gjør det. Ta kontakt, eller les om automatisering og dynamiske nettsider.

Mer om datainnhenting

Denne artikkelen hører til datainnhenting. Skal noen gjøre jobben for deg, er det dette vi tilbyr: hjelp til å hente ut data.