Come posso verificare link validi (non morti) a livello di codice usando PHP?

StackOverflow https://stackoverflow.com/questions/244506

  •  05-07-2019
  •  | 
  •  

Domanda

Dato un elenco di URL, vorrei verificare che ciascun URL:

  • Restituisce un codice di stato 200 OK
  • Restituisce una risposta entro X tempo

L'obiettivo finale è un sistema in grado di contrassegnare gli URL come potenzialmente rotti in modo che un amministratore possa esaminarli.

Lo script sarà scritto in PHP e molto probabilmente verrà eseguito su base giornaliera tramite cron.

Lo script elaborerà circa 1000 URL alla volta.

La domanda ha due parti:

  • Ci sono dei big big con un'operazione come questa, in quali problemi hai riscontrato?
  • Qual è il metodo migliore per verificare lo stato di un URL in PHP considerando sia l'accuratezza che le prestazioni?
È stato utile?

Soluzione

Usa l'estensione PHP cURL. A differenza di fopen () può anche fare richieste HTTP HEAD che sono sufficienti per verificare la disponibilità di un URL e risparmiare un sacco di banda senza che sia necessario scaricare l'intero corpo della pagina per controllare.

Come punto di partenza potresti usare alcune funzioni come questa:

function is_available($url, $timeout = 30) {
    $ch = curl_init(); // get cURL handle

    // set cURL options
    $opts = array(CURLOPT_RETURNTRANSFER => true, // do not output to browser
                  CURLOPT_URL => $url,            // set URL
                  CURLOPT_NOBODY => true,         // do a HEAD request only
                  CURLOPT_TIMEOUT => $timeout);   // set timeout
    curl_setopt_array($ch, $opts); 

    curl_exec($ch); // do it!

    $retval = curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200; // check if HTTP OK

    curl_close($ch); // close handle

    return $retval;
}

Tuttavia, ci sono moltissime possibili ottimizzazioni: potresti voler riutilizzare l'istanza cURL e, se controlli più di un URL per host, riutilizzare persino la connessione.

Oh, e questo codice controlla rigorosamente il codice di risposta HTTP 200. Non segue i reindirizzamenti (302) - ma esiste anche un'opzione cURL per questo.

Altri suggerimenti

Cerca in cURL. C'è una libreria per PHP.

Esiste anche una versione eseguibile di cURL in modo da poter scrivere lo script in bash.

In realtà ho scritto qualcosa in PHP che lo fa su un database di 5k + URL. Ho usato la classe PEAR HTTP_Request , che ha un metodo chiamato getResponseCode (). Ho appena passato gli URL, passandoli a getResponseCode e valutando la risposta.

Tuttavia, non funziona per indirizzi FTP, URL che non iniziano con http o https (non confermato, ma credo sia il caso) e siti con certificati di sicurezza non validi (non viene trovato uno 0). Inoltre, viene restituito uno 0 per il server non trovato (non esiste un codice di stato per quello).

Ed è probabilmente più semplice di cURL poiché includi alcuni file e usi una singola funzione per recuperare un codice intero.

  1. fopen () supporta URI http.
  2. Se hai bisogno di maggiore flessibilità (come il timeout), controlla l'estensione cURL.

Sembra che potrebbe essere un lavoro per curl .

Se non sei bloccato su PHP, Perl's LWP potrebbe anche essere una risposta.

Dovresti anche essere a conoscenza degli URL che restituiscono 301 o 302 risposte HTTP che reindirizzano a un'altra pagina. In genere ciò non significa che il collegamento non sia valido. Ad esempio, http://amazon.com restituisce 301 e reindirizza a http://www.amazon.com/ .

Restituire una risposta 200 non è sufficiente; molti link validi continueranno a restituire "200" dopo che si trasformano in portali porno / giochi d'azzardo quando l'ex proprietario non riesce a rinnovare.

Gli abusivi di dominio in genere assicurano che ogni URL nei loro domini restituisca 200.

Un potenziale problema che incontrerai senza dubbio è quando la casella su cui è in esecuzione questo script perde l'accesso a Internet ... otterrai 1000 falsi positivi.

Probabilmente sarebbe meglio per il tuo script mantenere un certo tipo di cronologia e segnalare un errore solo dopo 5 giorni di errore.

Inoltre, lo script dovrebbe essere autocontrollato in qualche modo (come controllare un sito Web ben noto [google?]) prima di continuare con i controlli standard.

Per farlo devi solo uno script bash. Controlla la mia risposta su un post simile qui . È un one-liner che riutilizza le connessioni HTTP per migliorare notevolmente la velocità, riprova n volte per errori temporanei e segue i reindirizzamenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top