Как максимально быстро получить разметку сайта по ссылке?

У меня есть следующий код:

<?php
session_start();
function startsWith ($string, $startString) 
{ 
    $len = strlen($startString); 
    return (substr($string, 0, $len) === $startString); 
} 
function endsWith($string, $startString) 
{
    $length = strlen($startString);
    if( !$length ) {
        return true;
    }
    return substr($string, -$length ) === $startString;
}
function file_get_contents_socket($host,$path)
{
    $g = stream_context_create(array("ssl" => array("capture_peer_cert" => true)));
    $r = stream_socket_client("ssl://".$host.":443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $g);
    //$r = fsockopen("ssl://".$host,443, $errno, $errstr, 30);
    fwrite($r, "GET ".$path." HTTP/1.0\r\nhost:".$host."\r\nAccept: */*\r\n\r\n");
    $variable = stream_get_contents($r);
    stream_socket_shutdown($r, STREAM_SHUT_WR);
    return $variable;
}
function get_url_data($url)
{
    $extractedLinks = array();
    $domain = 'https://'.parse_url($url, PHP_URL_HOST);
    $html = file_get_contents_socket(parse_url($url, PHP_URL_HOST),parse_url($url, PHP_URL_PATH));
    $htmlDom = new DOMDocument;
    libxml_use_internal_errors(true);
    $htmlDom->loadHTML($html);
    $links = $htmlDom->getElementsByTagName('a');
    libxml_clear_errors();
    $extractedLinks = array();
    foreach($links as $link){
        $linkHref = $link->getAttribute('href');
        if(strlen(trim($linkHref)) == 0){
            continue;
        }
        if($linkHref[0] == '#'){
            continue;
        }
        if(startsWith($linkHref, '//')){
            $linkHref = 'https:'.$linkHref;
        }
        if(startsWith($linkHref, '/') && !startsWith($linkHref, '//')){
            $linkHref = $domain.$linkHref;
        }
        if(!endsWith($linkHref, '/')){
            $linkHref = $linkHref.'/';
        }
        //Поиск названия страницы
        $urlHref = file_get_contents_socket(parse_url($linkHref, PHP_URL_HOST),parse_url($linkHref, PHP_URL_PATH));
        $doc = new DOMDocument();
        libxml_use_internal_errors(true);
        $doc->loadHTML('<?xml encoding="utf-8" ?>' . $urlHref);
        libxml_clear_errors();
        $nodes = $doc->getElementsByTagName('title');
        if ($nodes->length>0) {
            $title = $nodes->item(0)->nodeValue;
        }
        $extractedLinks[] = array(
            'text' => $title,
            'href' => $linkHref
        );
    }
    return $extractedLinks;
}
?>

Вызывая функцию get_url_data(), я получаю массив со всеми ссылками, которые содержит выбранная страница($url), а также title этих страниц. Проблема в том, что когда этот скрипт ищет кроме ссылок ещё и title, то загрузка страницы занимает много времени. К примеру, если закомментировать часть кода, отвечающую за поиск названия(//Поиск названия страницы), то загрузка страницы с данным скриптом занимает около 1-2 секунд(на локальном сервере). Но, если же добавить к этому ещё и поиск title страниц, то код загружается около 10-15 секунд. Мой знакомый выполняет ту же самую задачу, но у него загрузка стабильно 2-3 секунды.
Знаю, что для считывания разметки, в данном коде происходит переход на каждую из найденных страниц. Из-за этого такая долгая загрузка(интернет-соединение у меня очень плохое). Есть ли способ побыстрее, чем тот, что я использовал? На других сайтах, которые выполняют ту же задачу, даже у меня загрузка занимает мало(3-7 секунд) времени. Может я что-то не так написал?
К тому же, когда я добавляю сайт с данным скриптом на хостинг(медленный), то загрузка тоже долгая. Может ли быть так, что, если я загружу сайт с этим скриптом на быстрый хостинг, то загрузка уменьшится хотя бы до 5 секунд? Это же по идее хостинг открывает все эти страницы?
Просто, мне нужно потом открыть каждую из найденных страниц ещё раз, чтобы также найти на них ссылки, и повторить это ещё хотя бы один раз.(В итоге, должно получиться что-то наподобие дерева с ссылками и названиями их страниц).
П.с. Пробовал через file_get_contents(), cURL, fsockwrite() - вместо stream_socket_client() и Simple DOM Parser - результат тот же. Нужно делать эту задачу именно на php, желательно используя сокеты.


Ответы (0 шт):