Сканирование сайта с помощью PHP

Иногда требуется посканировать сайт "снаружи", т.е. посмотреть на него так, как видят его роботы. Для этого можно воспользоваться уже готовыми программами, а можно написать свою.

Чаще всего готовые программы многого не умеют, либо делают что-то не так, как хочется.

Собственная программа на php сделает все именно так как задумано.

Когда может пригодиться сканирование сайта

Создание карты сайта

Это может потребоваться если используется какая-нибудь нестандартная CMS, у которой нет модуля для создания карты сайта. Или модуль выдает не то что хочется, например, добавляет лишние ссылки или не добавляет страницы, которые на сайте видны, но модуль о них не знает. Или нет времени, сил или знаний чтобы чинить или дорабатывать этот модуль. А может быть карта нужна разово и нет смысла разбираться с модулями.

Поиск ссылок ведущих на чужие сайты

Если сайт наполняли путем копирования-вставки, то есть вероятность того что с текстом были скопированы ссылки, которые в лучшем случае будут отдавать "вес" вашего сайта чужому, а в худшем по ним уйдут ваши посетители. Или можно опозориться, когда хозяева сайта с которого вы копировали текст вместе с сылками на картинки обнаружат это и заменят картинки на что-нибудь неприличное и ваши посетители это увидят.

Проверка html-кода

Иногда бывают ситуации когда в нескольких разных статьях используется одинаковая разметка и когда статьи выводятся блогом, то на одной странице могут оказаться теги с одинаковыми id. Большинство CMS не проводят валидацию получившихся страниц, а одинаковые id могут вызвать неработоспособность js-скриптов.

Поиск битых картинок

В случаях когда картинки отсутствуют на диске, но в базе данных есть записи об этих картинках, возникает эффект битых ссылок. Ссылка есть, а файла нет. Это тоже труднообнаружимая проблема на сайте с огромным количеством страниц.

---

Из всего вышеперечисленного наш скрипт будет создавать только карту сайта. А уже в последующих статьях мы будем добавлять другой функционал. Если вам это нужно и вы попросите доработать скрипт. Пишите об этом в комментариях.

Установка интерпретатора php

Для работы скрипта, как можно догадаться, понадобится установить php в Windows. Делается это очень просто. Скачиваем дистрибутив PHP в виде zip-архива отсюда https://windows.php.net/download/

Распаковываем архив в папочку C:\php и добавляем ее в переменную окружения PATH, чтобы в командной строке не набирать каждый раз полный путь к php.exe.

Скрипт сканирования сайта

А это собственно сам скрипт, который скачивает главную страницу сайта, ищет на ней все ссылки и добавляет их в очередь на сканирование.

Для уже проверенных страниц и очереди используются два массива. Третий массив используется для хранения регулярных выражений, описывающих адреса страниц, которые нужно пропустить. На большинстве сайтов таких страниц очень много, и если их не просеивать, то процесс сканирования может затянуться надолго.

Поскольку в задачи нашего скрипта входит построить "карту сайта", то адреса страниц мы будем просто скидывать в файл sitemap.txt.

<?php

// адрес сайта c закрывающим слешем
$site = "https://coffee-cms.ru/";

// массив для очереди обрабатываемых страниц
$queue[] = $site; // стартуем с главной

// массив для уже скачанных, чтобы не повторяться
$checked = array();

// массив для учета где найдена ссылка
$found = array();

// максимальное количество проверяемых
$limit = 10000;

$ignored = array(
    "/\/sites\//", // drupal
    "/\/misc\//", // drupal
    "/\/flag\//", // drupal
    "/\/christmas\//", // coffee-cms.ru
    "/\/baseBlog\//", // coffee-cms.ru
    "/\/jquery/", // coffee-cms.ru
    "/\/\\\$\{src\}/", // in js coffee-cms.ru
    "/&lt;\?php/", // in examples coffee-cms.ru
    //"/\.zip\$/", // не искать битые ссылки
    //"/\.png\$/", // не искать битые ссылки
    //"/\.svg\$/", // не искать битые ссылки
    //"/\.xml\$/", // не искать битые ссылки
    //"/\.mp4\$/", // не искать битые ссылки
    //"/\.jpg\$/", // не искать битые ссылки
);
 

file_put_contents( "sitemap.txt", "" ); // очистить файл
file_put_contents( "error.txt", "" ); // очистить файл

while ( count( $queue ) > 0 && $limit > 0 ) {
    
    $page = array_shift( $queue );
    
    if ( ! in_array( $page, $checked ) ) {
    
        // качаем только с нашего сайта
        if ( substr( $page, 0, strlen( $site ) ) == $site ) {
            $content = @file_get_contents( $page );
            if ( $content === false ) {
                file_put_contents( "error.txt",
                	"page: {$page}\n", FILE_APPEND );
                foreach( $found[ $page ] as $f ) {
                    file_put_contents( "error.txt",
                    	" found: {$f}\n", FILE_APPEND );
                }
                continue;
            }
        }

        // ищем все ссылки на странице
        preg_match_all( "#(src|href)=[\"'](?!//|\#|mailto:)(.*?)[\"']#",
        	$content, $matches, PREG_SET_ORDER );
 
        // добавляем найденные ссылки в очередь
        foreach ( $matches as $match ) {
        
            $link = $match[2];
            
            // корректируем относительные ссылки
            if ( substr( $link, 0, 7 ) != "http://"
            && substr( $link, 0, 8 ) != "https://" )
            {
                if ( $link[0] == "/" ) {
                    $link = substr( $link, 1 ); // убрать ведущий слеш
                }
                $link = $site . $link;
            }

            $found[ $link ][] = $page;
            
            if ( ! in_array( $link, $queue ) && // не в очереди
            ! in_array( $link, $checked ) &&   // не проверена
            substr( $link, 0, strlen( $site ) ) == $site ) // с нашего сайта
            {
                $ignore = false;
                
                foreach ( $ignored as $regex ) {
                    $ignore = $ignore || preg_match( $regex, $link );
                    if ( $ignore ) { break; } // не проверять остальные
                }
                
                if ( ! $ignore ) { $queue[] = $link; } // ставим в очередь
            }
        }
 
        $checked[] = $page; // добавляем в массив проверенных
        file_put_contents( "sitemap.txt", $page . "\n", FILE_APPEND );

        // отображаем какая ссылка обработана
        echo "checked " . count( $checked ) .
        	", queue " . count( $queue ) . ", page $page\n";

        $limit--;
    }
}
27 января 2023, 20:15
Ник
Спасибо!
Ответить
27 января 2023, 20:19
Олег
Ник
Спасибо!
Пожалуйста.
Ответить
Комментировать
Закрыть
Сумма:
0 ₽
После согласования условий заказа мы Вам отправим счёт или ссылку c удобным способом оплаты.
Оформить заказ