PHP: estrarre i link interni da una pagina remota

In questo tutorial vedremo come estrarre i link da una pagina HTML di un sito con PHP.

Si tratta sostanzialmente di individuare tutti gli elementi HTML a il cui attributo href faccia riferimento a pagine interne al sito scelto come punto di partenza. Dobbiamo anche fare in modo che l'array restituito non contenga URL duplicati e per farlo ricorreremo alla funzione array_unique() trattandosi di valori primitivi (stringhe).

La nostra implementazione potrebbe essere la seguente:


    class Scraper
    {
        private $url;
        private $skipSSL;
        private $links;
    
        public function __construct($url, $skipSSL = false)
        {
            $this->url = $url;
            $this->skipSSL = $skipSSL;
            $this->links = [];
    
            $this->fetch();
        }
    
        public function getLinks() 
        {
            return $this->links;
        }
    
        private function fetch()
        {
            $this->parsePage();
            $this->links = array_unique($this->links);
        }
    
        private function parsePage()
        {
            $page = $this->getPage();
            if(is_null($page)) {
                return $page;
            }
    
            $document = new DOMDocument();
            libxml_use_internal_errors(true);
            $document->loadHTML($page);
            $links = $document->getElementsByTagName('a');
    
            foreach ($links as $link) {
                $href = $link->getAttribute('href');
                $pattern = '#^' . $this->url . '#';
                if(preg_match($pattern, $href)) {
                    $this->links[] = $href;
                }
            }
        }
    
        private function getPage()
        {
            if(!filter_var($this->url, FILTER_VALIDATE_URL)) {
                return null;
            }
            $ch = curl_init();
    
            curl_setopt($ch, CURLOPT_URL, $this->url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
    
            if($this->skipSSL) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            }
    
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2');
    
            $response = curl_exec($ch);
            $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    
            if(curl_error($ch) || strstr($contentType, 'text/html') === false) {
                return null;
            }
    
            curl_close($ch);
    
            return $response;
        }
    }    

Esempio d'uso:


    $scraper = new Scraper('https://gabrieleromanato.com');
    print_r($scraper->getLinks());    
    

L'aspetto importante da ricordare è che la gestione degli errori non può mancare. In questo caso restituiamo solo valori predefiniti, ma è in quei punti dei metodi che andrebbe aggiunto il logging degli errori.

Torna su