Как мне проверить наличие действительных (не мертвых) ссылок программно с помощью PHP?
Вопрос
Учитывая список 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, поскольку вы включаете несколько файлов и используете одну функцию для получения обратно целочисленного кода.
- fopen() поддерживает http URI.
- Если вам нужно больше гибкости (например, тайм-аут), загляните в расширение 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 попыток для выявления временных ошибок и следует за перенаправлениями.