PHP / Curl: żądanie głowy zajmuje dużo czasu na niektórych stronach

Mam prosty kod, który wykonuje head request dla adresu URL, a następnie drukuje nagłówki odpowiedzi. Zauważyłem, że na niektórych stronach Może to zająć dużo czasu.

Na przykład żądanie http://www.arstechnica.com zajmuje około dwóch minut. Próbowałem tego samego żądania za pomocą innej strony internetowej, która wykonuje to samo podstawowe zadanie, i wraca natychmiast. Więc musi być coś, co ustawiłem nieprawidłowo, co powoduje to opóźnienie.

Oto kod, który mam:

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

$content = curl_exec ($ch);
curl_close ($ch);

Oto link do strona www pełniąca tę samą funkcję: http://www.seoconsultants.com/tools/headers.asp

Powyższy kod, przynajmniej na moim serwerze, zajmuje dwie minuty, aby odzyskać www.arstechnica.com, ale serwis pod linkiem powyżej zwraca go od razu.

Co mi umyka?
Author: bignose, 2009-04-21

5 answers

Spróbuj trochę uprościć:

print htmlentities(file_get_contents("http://www.arstechnica.com"));

Powyższe wyjście natychmiast na moim serwerze. Jeśli nie działa na Twoim, istnieje duża szansa, że Twój host ma jakieś ustawienie, aby ograniczyć tego rodzaju żądania.

EDIT :

Ponieważ powyższe dzieje się natychmiast dla ciebie, spróbuj ustawić to ustawienie curl na oryginalnym kodzie:

curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

Używając narzędzia, które napisałeś, zauważyłem, że http://www.arstechnica.com ma nagłówek 301 wysłany dla każdego żądania wysłanego do niego. Jest możliwe, że cURL dostaje to i nie podąża za nową wskazaną lokalizacją, powodując zawieszenie skryptu.

DRUGA EDYCJA :

Co ciekawe, wypróbowanie tego samego kodu, który masz powyżej, sprawiło, że mój serwer też się zawiesił. Podmieniłem ten kod:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

Z tym:

curl_setopt($ch, CURLOPT_NOBODY, true);

Czyli sposób Instrukcja zaleca wykonanie polecenia HEAD. To sprawiło, że działa natychmiast.

 43
Author: Paolo Bergantino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-20 21:49:23

Musisz pamiętać, że HEAD to tylko sugestia dla serwera www. Aby HEAD zrobił właściwą rzecz, często wymaga to wyraźnego wysiłku ze strony administratorów. Jeśli udasz plik statyczny, Apache (lub jakikolwiek serwer internetowy jest) często wkroczy do zrobienia właściwej rzeczy. Jeśli skierujesz stronę dynamiczną, domyślną dla większości konfiguracji jest uruchomienie ścieżki pobierania, zebranie wszystkich wyników i odesłanie nagłówków bez zawartości. Jeśli ta aplikacja znajduje się w konfiguracji warstwy 3 (lub więcej) , ten telefon może być potencjalnie bardzo drogi i niepotrzebny dla kontekstu głowy. Na przykład, na Serwletie Javy, domyślnie dohead() wywołuje doGet (). Aby zrobić coś nieco mądrzejszego dla aplikacji programista musiałby wyraźnie zaimplementować dohead () (i częściej nie będzie).

Natknąłem się na aplikację firmy z listy fortune 100, która służy do pobierania kilkuset megabajtów informacji o cenach. Sprawdzamy aktualizacje tych danych wykonując Szef prosi dość regularnie, aż do zmiany daty modyfikacji. Okazuje się, że to żądanie faktycznie będzie wywoływać back-end do generowania tej listy za każdym razem, gdy złożyliśmy żądanie, które wymagało gigabajtów danych na ich back-endzie i xfer go między kilkoma wewnętrznymi serwerami. Nie byli z nas strasznie zadowoleni, ale gdy wyjaśniliśmy przypadek użycia, szybko wymyślili alternatywne rozwiązanie. Gdyby zaimplementowali HEAD, zamiast polegać na swoim serwerze internetowym, aby go sfałszować, to nie było problemu.

 6
Author: Trey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-29 15:00:35

Jeśli moja pamięć nie zawiedzie mnie wykonanie HEAD request w CURL zmienia wersję protokołu HTTP na 1.0 (co jest powolne i prawdopodobnie winne tutaj) spróbuj zmienić to na:

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // ADD THIS

$content = curl_exec ($ch);
curl_close ($ch);
 3
Author: Alix Axel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-20 21:41:42

Użyłem poniższej funkcji, aby znaleźć przekierowany adres URL.

$head = get_headers($url, 1);

Drugi argument sprawia, że zwraca tablicę z kluczami. Na przykład poniżej podamy wartość Location.

$head["Location"]

Http://php.net/manual/en/function.get-headers.php

 3
Author: San,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-23 12:47:16

To:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
Nie próbowałem zdobyć nagłówków.
Po prostu starałem się, aby ładowanie strony niektórych danych nie trwało 2 minut, podobnie jak opisano powyżej.
Ta magiczna mała opcja spadła do 2 sekund.
 0
Author: Brad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-28 10:40:29