zaLinux.ru

PHP cURL как установить значение User Agent ИЛИ как сделать так, чтобы сервера не блокировали запросы cURL?


Некоторые сайты нормально открываются в браузере, но при попытке получить исходный HTML код с помощью cURL эти запросы могут отклоняться. Могут возвращаться коды ответов, например, 403, то есть доступ запрещён.

Чтобы понимать, как это исправить, нужно понимать причины, которых может быть несколько.

Программа cURL делает обычные HTTP запросы, которые не отличаются от запросов, которые делает ваш веб-браузер. Тем не менее веб-браузер может получить исходный код страницы, а запрос от cURL может быть отвернут. Обычно такое поведение веб серверов связано с защитой от ботов — программ, которые запрашивают страницы не для пользователя (как веб браузер), а для иных целей, например, инструментами для парсинга с целью сбора контента страницы, инструментами для поиска уязвимостей, инструментами для анализа содержимого и так далее. Некоторые веб мастера не заинтересованы в этих ботах, которые не несут никакой пользы, но при этом как минимум создают нагрузку на сервер, а в некоторых случаях используются для воровства контента или иной вредоносной активности.

Для этого они настраивают защиту от ботов, как правило, защита бывает двух видов:

  • запрет на основе User Agent (агента пользователя). Очень простые защиты, которые очень легко можно обойти
  • проверки на поддержку технологий JavaScript (боты очень часто не умеют работать с JavaScript — это же относится и к cURL), а также поддержку кукиз (хотя cURL может работать с кукиз, но если её специально на это не настроить, то она провалит тест). Такие тесты могут быть весьма сложные, код JavaScript устанавливает и проверяет кукиз и другие свойства браузера, содержимое веб страницы может быть загружено асинхронно средствами JavaScript и так далее — обычно такие защиты непросто обойти.

Начнём со случая, когда происходит блокировка на уровне пользовательского агента. На самом деле, cURL устанавливает своё значение User Agent, но в отправляемой на сервер строке указано, что запрос делает cURL, а также номер cURL.

С помощью curl_setopt можно установить произвольный User Agent примерно следующим образом:

$agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)';
$curl=curl_init();
curl_setopt($curl, CURLOPT_USERAGENT, $agent);

Пример реального кода:


        $link = 'https://zalinux.ru'; 
        $agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'; 
        $ch = curl_init($link);
        curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response_data = curl_exec($ch);
        if (curl_errno($ch) > 0) {
            die('Ошибка curl: ' . curl_error($ch));
        }
        curl_close($ch);
        echo $response_data;

Возможны ситуации, когда сервер не принимает запросы по той причине, что в качестве реферера (страницы с которой пришёл пользователь, делающий запросы) ничего не указано. В этом случае вы можете настроить значение REFERER следующим образом:

curl_setopt($curl, CURLOPT_REFERER, 'https://www.domain.com/');

Пример рабочего кода:

        $link = 'https://zalinux.ru'; 
        $agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'; 
        $ch = curl_init($link);
        curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_REFERER, 'https://zalinux.ru');
        $response_data = curl_exec($ch);
        if (curl_errno($ch) > 0) {
            die('Ошибка curl: ' . curl_error($ch));
        }
        curl_close($ch);
        echo $response_data;

Некоторые простейшие защиты, основанные на установке веб-приложением (сервером) кукиз и затем последующей их проверке, можно обойти установив следующие опции:

$dir = dirname(__FILE__);
$config['cookie_file'] = $dir . '/cookies/' . md5($_SERVER['REMOTE_ADDR']) . '.txt';

curl_setopt($curl, CURLOPT_COOKIEFILE, $config['cookie_file']);
curl_setopt($curl, CURLOPT_COOKIEJAR, $config['cookie_file']);

Примечание: В текущей директории у вас должна быть создана папка COOKIES

Значение опции:

  • CURLOPT_COOKIEFILE: Имя файла, содержащего cookies. Данный файл должен быть в формате Netscape или просто заголовками HTTP, записанными в файл. Если в качестве имени файла передана пустая строка, то cookies сохраняться не будут, но их обработка все еще будет включена.
  • CURLOPT_COOKIEJAR: Имя файла, в котором будут сохранены все внутренние cookies текущей передачи после закрытия дескриптора, например, после вызова curl_close.

Если ничего из вышеприведённого не помогло, то попробуйте настроить cURL так, чтобы она следовала перенаправлениям. Это может помочь, если страница, к которой обращается ваша программа, перемещена и от вас требуется перейти по новому адресу. В веб браузере это происходит автоматически и для большинства пользователей незаметно. По умолчанию cURL не выполняет редиректов, чтобы cURL переходила по редиректам используйте опции:

curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

Опция CURLOPT_FOLLOWLOCATION означает: TRUE для следования любому заголовку "Location: ", отправленному сервером в своем ответе (учтите, что это происходит рекурсивно, PHP будет следовать за всеми посылаемыми заголовками "Location: ", за исключением случая, когда установлена константа CURLOPT_MAXREDIRS).


Рекомендуемые статьи:

3 Комментарии

  1. Алексей

    Прошу помощи.
    Есть адрес: https://new.faberlic.com/ru/search/autocomplete/SearchBox?term=502422
    Он легко открывается вручную в браузере и выдает полную информацию.
    Но при попытке открыть его с помощью php, например через file_get_contents или cURL, серевер возвращает по минимуму: {"suggestions":[],"products":[]} 

    Впервые с таким сталкиваюсь.
    Что еще интересно, немного другой запрос, с другим продуктом, открывается без проблем везде: https://new.faberlic.com/ru/search/autocomplete/SearchBox?term=545915

    1. Alexey (Автор записи)

      Приветствую! Первая ссылка даже в браузере мне показывать только {"suggestions":[],"products":[]}.

  2. Алексей

    Очень странно, у меня теперь тоже не открывается )

    Возможно из кэша грузилось. Спасибо за быстрый ответ.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *