Как я могу проверить действительные (не мертвые) ссылки программным образом с помощью 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 раз для временных ошибок и следует перенаправлениям.