#php #curl
#php #curl
Вопрос:
На сервере ubuntu я запускаю следующий PHP-код, и иногда он работает, а иногда нет. Части кода, которые прокомментированы, уже протестировали все возможные варианты и не увенчались успехом.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.americanas.com.br/');
//curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
//curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 0);
//curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_STDERR, fopen(dirname(__FILE__).'/errorlog.txt', 'w'));
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
//curl_setopt($ch, CURLOPT_SSLVERSION, 4);
$result = curl_exec($ch);
curl_exec($ch);
print_r(curl_getinfo($ch));
print_r(curl_error($ch));
Ниже приведен его снимок, который я смог сделать с возвратом двух запросов, одного, который сработал, а другого — нет. Я заметил, что каждый запрос направляется на другой IP, и сертификат сервера также меняется.
На том же сервере выполнение соответствующего запроса через командную строку всегда работает:
curl --verbose https://www.americanas.com.br
Может кто-нибудь объяснить, почему?
Ответ №1:
После многих тестов я прихожу к некоторым выводам.
Похоже, что каждая структура сайта находится за кластером серверов, что объясняет большое количество IP-адресов при разрешении его DNS в различных службах DNS.
Эта моя конкретная проблема была вызвана DNS-сервером, используемым моим хостингом. Он возвращал IP-адрес на сайт, который не работал с моими запросами cURL через PHP.
Я смог обойти эту проблему, изменив DNS-сервер запросов:
curl_setopt($ch, CURLOPT_DNS_SERVERS, '1.1.1.1,8.8.8.8');
Ручной выбор IP-адреса также работал.
curl_setopt($ch, CURLOPT_RESOLVE, ['www.americanas.com.br:443:23.36.73.68']);
Я узнал много нового об этой проблеме, надеюсь, это может быть полезно для кого-то еще.
Ответ №2:
Это не связано с сервером, который выполняет запросы curls, а связано с самим доменом и dns домена, например cloudflare, также, если на веб-сайте есть проверка запросов http и https, поэтому он может частично блокировать запросы, поэтому вы делаете запрос, и он дает ответ, в то время как другой заблокирован
Ответ №3:
On the same server, executing a corresponding request via the command line always works
единственным отличием должен быть пользовательский агент..
curl программа cli всегда добавляет user-agent, libcurl — нет, и многие веб-сайты блокируют запросы без заголовка user-agent. GoogleDNS знает о 3 разных серверах для www.americanas.com.br , и я предполагаю, что НЕКОТОРЫЕ из их серверов разрешают запросы без заголовка user-agent, а некоторые из их серверов — нет.
$ nslookup www.americanas.com.br
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
www.americanas.com.br canonical name = wildsan.b2wdigital.com.edgekey.net.
wildsan.b2wdigital.com.edgekey.net canonical name = e6654.dscg.akamaiedge.net.
Name: e6654.dscg.akamaiedge.net
Address: 23.52.34.144
Name: e6654.dscg.akamaiedge.net
Address: 2a02:26f0:e2:48c::19fe
Name: e6654.dscg.akamaiedge.net
Address: 2a02:26f0:e2:4a1::19fe
если я прав, то решение состоит в том, чтобы добавить заголовок User-Agent, если вы хотите быть универсальным, тогда что-то вроде
curl_setopt($ch,CURLOPT_USERAGENT,'libcurl/' . (curl_version()['version']) . ' php/' . PHP_VERSION);
- редактировать: первоначально у меня закончилось время в середине написания этого поста, и первоначальная версия не имела особого смысла, теперь она должна иметь смысл.
Комментарии:
1. Спасибо за ответ. Хотя я не включил это в приведенный выше пример кода, я протестировал код, указав полный http-заголовок, имитирующий доступ к браузеру, также безуспешно.
Accept text/html,application/xhtml xm…plication/xml;q=0.9,*/*;q=0.8 Accept-Encoding gzip, deflate, br Accept-Language pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3 Cache-Control no-cache Connection keep-alive Host www.americanas.com.br User-Agent Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/60.0
Ответ №4:
Теперь все становится яснее. Сайт использует сервисы Akamai, похожие на cloudflare.
Некоторые из различных серверов блокируют запросы в соответствии с пользовательским агентом, например, те, которые используются стандартными браузерами.
Решение, указанное вышеупомянутым другом, будет работать так же хорошо, как и запуск через терминал, потому что User-Agent: curl / 7.50.3 не заблокирован.
Я только что отправил запрос со случайным пользовательским агентом и …. бинго. Сработало отлично.