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.