2 Stimmen

Wie kann man die Klasse beschleunigen, die Links in HTML prüft?

Ich habe eine Klasse zusammengeschustert, die Links überprüft. Es funktioniert, aber es ist langsam:

Die Klasse analysiert einen HTML-String und gibt alle ungültigen Links für die Attribute href und src zurück. Hier ist, wie ich es verwende:

$class = new Validurl(array('html' => file_get_contents('http://google.com')));

$invalid_links = $class->check_links();

print_r($invalid_links);

Bei HTML mit vielen Links wird es wirklich langsam, und ich weiß, dass es jeden Link durchgehen und verfolgen muss, aber vielleicht kann mir jemand mit mehr Erfahrung ein paar Tipps geben, wie ich es beschleunigen kann.

Hier ist der Code:

class Validurl{

    private $html = '';

    public function __construct($params){ 

        $this->html = $params['html'];

    } 

    public function check_links(){

        $invalid_links = array();    

        $all_links = $this->get_links();

        foreach($all_links as $link){

            if(!$this->is_valid_url($link['url'])){

                array_push($invalid_links, $link);

            }

        }

        return  $invalid_links;

    }

    private function get_links() {

        $xml = new DOMDocument();

        @$xml->loadHTML($this->html);

        $links = array();

        foreach($xml->getElementsByTagName('a') as $link) {
            $links[] = array('type' => 'url', 'url' => $link->getAttribute('href'), 'text' => $link->nodeValue);
        }

        foreach($xml->getElementsByTagName('img') as $link) {
            $links[] = array('type' => 'img', 'url' => $link->getAttribute('src'));
        }        

        return $links;
    }

    private function is_valid_url($url){

         if ((strpos($url, "http")) === false) $url = "http://" . $url;

         if (is_array(@get_headers($url))){

              return true;

         }else{

             return false;

         }
    }

}

2voto

Tom Imrei Punkte 1494

Zunächst einmal würde ich nicht schieben Sie die Links und Bilder in ein Array, und dann durch das Array zu iterieren, wenn Sie direkt die Ergebnisse von getElementsByTagName() iterieren könnte. Für <a>- und <img>-Tags müssten Sie das zweimal tun, aber wenn Sie die Prüflogik in eine Funktion aufteilen, können Sie diese einfach für jede Runde aufrufen.

Zweitens ist get_headers() langsam, basierend auf den Kommentaren aus der PHP-Handbuchseite . Sie sollten lieber cUrl auf eine Art und Weise wie diese verwenden (zu finden in einer Kommentar auf derselben Seite ):

function get_headers_curl($url) 
{ 
    $ch = curl_init(); 

    curl_setopt($ch, CURLOPT_URL,            $url); 
    curl_setopt($ch, CURLOPT_HEADER,         true); 
    curl_setopt($ch, CURLOPT_NOBODY,         true); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_TIMEOUT,        15); 

    $r = curl_exec($ch); 
    $r = split("\n", $r); 
    return $r; 
}

UPDATE: und ja, eine Art Zwischenspeicherung könnte auch helfen, z.B. eine SQLITE-Datenbank mit einer Tabelle für den Link und das Ergebnis, und Sie könnten diese Datenbank z.B. jeden Tag bereinigen.

0voto

Karoly Horvath Punkte 91548

Sie könnten die Ergebnisse zwischenspeichern (in einer DB, z. B. in einem Key-Value-Store), so dass Ihr Validator davon ausgeht, dass ein gültiger Link für 24 Stunden oder eine Woche oder etwas Ähnliches gültig sein wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X