Estrarre link da PDF
Da sette annotazioni di un PDF escono i quattro veri link web, ognuno con il suo numero di pagina; commenti, evidenziazioni e salti interni restano fuori. Un link ripetuto su tre pagine compare tre volte. Gratis nel suo browser.
- Gratis
- Funziona nel suo browser
- Senza registrazione
- I suoi dati restano sul dispositivo
Esegui gratis nel browser
Funziona nel tuo browser: gratis, senza registrazione, i file non escono dal tuo dispositivo.
L'estrattore di link da PDF legge l'elenco di annotazioni pagina per pagina di un PDF — esattamente ciò che una libreria di lettura come pdf.js restituisce da getAnnotations — e restituisce ogni collegamento ipertestuale trovato, con il suo numero di pagina e la sua URL di destinazione. È il passaggio mancante tra «ho le annotazioni» e «so dove punta questo documento»: un passaggio deterministico, senza rendering, senza OCR e senza supposizioni. I link puramente interni e le annotazioni che non sono link vengono scartati, così ciò che riceve è un elenco pulito e ordinato dei riferimenti esterni che il documento fa, pronto per un audit, una lista iniziale per un crawler o un controllo di conformità.
Perché le annotazioni e non il testo grezzo
Cercare i link scorrendo il testo estratto non è affidabile: una URL visibile nel testo potrebbe non essere cliccabile, e un link cliccabile può mostrare un testo di ancoraggio che non somiglia affatto alla sua destinazione. La fonte autorevole per estrarre i link da un PDF è il livello delle annotazioni. I lettori PDF memorizzano gli elementi interattivi come annotazioni associate a una pagina, e i collegamenti ipertestuali vivono lì come voci di sottotipo Link con una URI.
Questa capacità prende quell'elenco come input — un record per annotazione con numero di pagina, sottotipo e URI opzionale — e lo filtra fino ai veri collegamenti in uscita. Poiché il numero di pagina viaggia con ogni annotazione, ogni risultato Le dice esattamente in quale punto del documento si trova il link, ed è ciò che rende l'output utilizzabile per revisioni e audit invece di una semplice lista di URL.
Cosa conserva l'estrattore e cosa scarta
Il filtro è volutamente rigoroso. Tra le annotazioni Link, sopravvivono solo quelle con una URI non vuota: un'annotazione di link senza URI è in genere un salto interno a un'altra pagina, cioè navigazione dentro il documento e non un collegamento verso una destinazione esterna, quindi viene esclusa. Le URI vengono ripulite dagli spazi circostanti ma per il resto restituite letteralmente: senza riscrittura, senza risoluzione, senza deduplicazione.
Se la stessa URL compare su tre pagine, riceve tre voci, perché il fatto che compaia tre volte è un'informazione. L'output è ordinato esattamente come arrivano le annotazioni, il che in pratica significa l'ordine del documento.
La stessa URL può legittimamente comparire più volte in un documento lungo — nel piè di pagina ripetuto, in una bibliografia e in una pagina di contatti — e fondere quelle occorrenze cancellerebbe la differenza tra una citazione occasionale e un riferimento sistematico, quindi l'estrattore le conserva tutte e lascia a chi chiama decidere cosa aggregare a valle.
Dove si inserisce in una pipeline
Il flusso tipico è: aprire il PDF con una libreria di lettura, raccogliere le annotazioni pagina per pagina, appiattirle nell'elenco di record che questa capacità si aspetta e inviarle. Riceve indietro un conteggio e un array di coppie {page, url}. I team la usano per inventariare i riferimenti in uscita di contratti e report prima della pubblicazione, per costruire la lista iniziale di una passata di verifica dei link, o per confermare che un documento anonimizzato non punta più dove non dovrebbe.
Un elenco di annotazioni vuoto viene trattato come un errore e non come un risultato vuoto, perché un elenco vuoto significa quasi sempre che il passaggio di estrazione a monte è fallito o che il file non ha mai avuto un livello di annotazioni — e restituire silenziosamente zero link lo nasconderebbe.
Casi d'uso
Verifichi i riferimenti in uscita prima di pubblicare
Inventari ogni collegamento ipertestuale di un report o contratto, con i numeri di pagina, così i revisori possono confermare che ogni destinazione è intenzionale e corretta.
Alimenti un controllo dei link rotti
Passi le URL estratte a un verificatore di link per individuare destinazioni morte in un documento che i Suoi clienti stanno per scaricare.
Verifichi un documento anonimizzato
Confermi che la versione pubblicata di un PDF non punta più a URL interne di staging o di partner che avrebbero dovuto essere rimosse.
Domande frequenti
Quanto costa?
È anche gratuita da eseguire nel Suo browser su questa pagina.
Che input si aspetta?
Un elenco di annotazioni appiattito: un record per annotazione con il numero di pagina che parte da 1, il suo sottotipo e, per i link, la sua URI. Librerie di lettura come pdf.js producono questo da getAnnotations con un piccolo passaggio di mappatura.
Perché ricevo un errore invece di un elenco vuoto?
Un array di annotazioni vuoto significa che l'estrazione a monte è fallita o che il PDF non ha un livello di annotazioni.
I salti interni di pagina sono inclusi?
No. Le annotazioni di link senza URI sono destinazioni interne al documento, non collegamenti in uscita, e vengono ignorate.
Le URL duplicate vengono deduplicate?
No. Se la stessa URL è collegata su tre pagine riceve tre voci, perché ogni occorrenza porta il proprio numero di pagina e quella ripetizione è di per sé un'informazione utile.
Scarica o valida le URL?
No. L'estrazione è puramente locale e deterministica; non viene fatta alcuna richiesta di rete verso le destinazioni.
Strumenti correlati
Per sviluppatori — accesso via API
Tutto quello che vedi in questa pagina è disponibile anche via API. Questa sezione è per i team che vogliono integrarlo nei propri sistemi; chi non ne ha bisogno può semplicemente usare lo strumento qui sopra.
Endpoint
Autenticazione con Bearer token: un POST mette in coda l'attività e il risultato arriva via webhook o link firmato.
Chiamala dal tuo stack
curl -X POST https://api.kit.forhosting.com/pdf/extract-links \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"annotations":[{"page":1,"subtype":"Link","uri":"https://example.com/docs"},{"page":1,"subtype":"Text","uri":null},{"page":3,"subtype":"Link","uri":"https://example.com/contact"}]}'const res = await fetch("https://api.kit.forhosting.com/pdf/extract-links", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"annotations": [
{
"page": 1,
"subtype": "Link",
"uri": "https://example.com/docs"
},
{
"page": 1,
"subtype": "Text",
"uri": null
},
{
"page": 3,
"subtype": "Link",
"uri": "https://example.com/contact"
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/extract-links",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"annotations": [
{
"page": 1,
"subtype": "Link",
"uri": "https://example.com/docs"
},
{
"page": 1,
"subtype": "Text",
"uri": null
},
{
"page": 3,
"subtype": "Link",
"uri": "https://example.com/contact"
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/extract-links", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"annotations":[{"page":1,"subtype":"Link","uri":"https://example.com/docs"},{"page":1,"subtype":"Text","uri":null},{"page":3,"subtype":"Link","uri":"https://example.com/contact"}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"annotations":[{"page":1,"subtype":"Link","uri":"https://example.com/docs"},{"page":1,"subtype":"Text","uri":null},{"page":3,"subtype":"Link","uri":"https://example.com/contact"}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/extract-links", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Esempio di richiesta
{
"annotations": [
{
"page": 1,
"subtype": "Link",
"uri": "https://example.com/docs"
},
{
"page": 1,
"subtype": "Text",
"uri": null
},
{
"page": 3,
"subtype": "Link",
"uri": "https://example.com/contact"
}
]
}Esempio di risposta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.extract_links",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}L'API è asincrona: ricevi subito un task_id e puoi fare polling fino a 1 richiesta al secondo.
Prezzi
Prezzo pubblicato, senza token né crediti. Se l'attività fallisce, non paghi.
Limiti
max_mb | 1 |
max_annotations | 50000 |
Errori
| HTTP | Codice | Significato |
|---|---|---|
401 | unauthorized | Chiave API mancante o non valida: controlla l'header Authorization. |
402 | insufficient_balance | Credito esaurito: ricarica per continuare a eseguire attività. |
404 | unknown_type | Tipo di attività sconosciuto: controlla il campo type della richiesta. |
429 | rate_limited | Troppe richieste in poco tempo: rallenta e riprova tra qualche secondo. |
Note tecniche
Perché le annotazioni e non il testo grezzo
Il contratto inoltre valida ogni record strada facendo: un numero di pagina mancante, una pagina non intera o un sottotipo assente interrompe la chiamata con un chiaro errore invalid_input, invece di produrre in silenzio una risposta parziale che Lei sarebbe tentato di ritenere valida.
Dove si inserisce in una pipeline
Lo stesso codice gira gratis nel Suo browser su questa pagina, così può validare un payload incollandolo e pagare solo quando automatizza la chiamata.