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

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

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

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

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

script будет обрабатывать около 1000 URL-адресов в пути.

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

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

Ответы

Ответ 1

Используйте расширение 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.

Ответ 2

Посмотрите на cURL. Там есть библиотека для PHP.

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

Похоже, это может быть работа для curl.

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

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

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

Ответ 9

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