Как мне проверить наличие действительных (не мертвых) ссылок программно с помощью PHP?

StackOverflow https://stackoverflow.com/questions/244506

  •  05-07-2019
  •  | 
  •  

Вопрос

Учитывая список URL-адресов, я хотел бы проверить, что каждый URL-адрес:

  • Возвращает код состояния 200 OK
  • Возвращает ответ в течение X промежутка времени

Конечной целью является система, способная помечать URL-адреса как потенциально поврежденные, чтобы администратор мог их просмотреть.

Скрипт будет написан на PHP и, скорее всего, будет запускаться ежедневно через cron.

Скрипт будет обрабатывать примерно 1000 URL-адресов одновременно.

Вопрос состоит из двух частей:

  • Есть ли какие-то серьезные проблемы с подобной операцией, с какими проблемами вы столкнулись?
  • Каков наилучший метод для проверки состояния URL-адреса в PHP с учетом как точности, так и производительности?
Это было полезно?

Решение

Используйте расширение PHP cURL.В отличие от fopen(), он также может отправлять HTTP-запросы HEAD, которых достаточно для проверки доступности URL-адреса, и экономит вам массу пропускной способности, поскольку вам не нужно загружать весь текст страницы для проверки.

В качестве отправной точки вы могли бы использовать какую-нибудь функцию, подобную этой:

function is_available($url, $timeout = 30) {
    $ch = curl_init(); // get cURL handle

    // set cURL options
    $opts = array(CURLOPT_RETURNTRANSFER => true, // do not output to browser
                  CURLOPT_URL => $url,            // set URL
                  CURLOPT_NOBODY => true,         // do a HEAD request only
                  CURLOPT_TIMEOUT => $timeout);   // set timeout
    curl_setopt_array($ch, $opts); 

    curl_exec($ch); // do it!

    $retval = curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200; // check if HTTP OK

    curl_close($ch); // close handle

    return $retval;
}

Тем не менее, существует множество возможных оптимизаций:Возможно, вам захочется повторно использовать экземпляр cURL и, при проверке более одного URL-адреса на хост, даже повторно использовать соединение.

О, и этот код строго проверяет наличие кода ответа HTTP 200.Он не следует за перенаправлениями (302) - но для этого также есть опция cURL.

Другие советы

Загляните в cURL.Есть библиотека для PHP.

Существует также исполняемая версия cURL, так что вы даже можете написать скрипт на bash.

На самом деле я написал кое-что на PHP, что делает это через базу данных из более чем 5 тысяч URL-адресов.Я использовал класс PEAR HTTP_Request, который имеет метод , называемый Получаем ответсекод().Я просто перебираю URL-адреса, передавая их в getResponseCode и оцениваю ответ.

Однако это не работает для FTP-адресов, URL-адресов, которые не начинаются с http или https (неподтверждено, но я полагаю, что это так), и сайтов с недействительными сертификатами безопасности (0 не найден).Кроме того, для server-not-found возвращается значение 0 (для этого нет кода состояния).

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

  1. fopen() поддерживает http URI.
  2. Если вам нужно больше гибкости (например, тайм-аут), загляните в расширение cURL.

Похоже, это может быть работа для завиток.

Если вы не застряли на PHP, LWP от Perl тоже может быть ответом.

Вы также должны быть осведомлены о URL-адресах, возвращающих 301 или 302 HTTP-ответа, которые перенаправляют на другую страницу.Как правило, это не означает, что ссылка недействительна.Например, http://amazon.com возвращает 301 и перенаправляет на http://www.amazon.com/.

Простого возврата ответа в размере 200 недостаточно;многие действительные ссылки будут продолжать возвращать "200" после того, как они перейдут на порнографические / игорные порталы, если прежний владелец не продлит их.

Скваттеры доменов обычно гарантируют, что каждый URL-адрес в их доменах возвращает 200.

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

Вероятно, было бы лучше, если бы ваш скрипт сохранял какой-то тип истории и сообщал о сбое только через 5 дней после сбоя.

Кроме того, скрипт должен каким-то образом самоконтролироваться (например, проверять известный хороший веб-сайт [Google?]), прежде чем продолжить стандартные проверки.

Для этого вам нужен только скрипт bash.Пожалуйста, проверьте мой ответ на аналогичный пост здесь.Это однострочник, который повторно использует HTTP-соединения для значительного повышения скорости, повторяет n попыток для выявления временных ошибок и следует за перенаправлениями.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top