Funkcja pobierająca stronę www
02 lutego 2008
Właśnie coś sobie tworzę i zaszła potrzeba pobierania i obrabiania treści z pewnej strony www (nie chodzi o fotka.pl
). Problem w tym, że serwer na którym ta strona stoi jest bardzo kapryśny :/ Często bez powodu wywala błędy 4xx a jeszcze częściej 5xx. Niby obsługuje kompresję gzip ale zdarza się, że zwróci stronę nieskompresowaną :/
Potrzebowałem funkcji, która poradzi sobie z tym wszystkim. Oto ona:
-
<?php
-
function otworz_adres($adres, $post=false, $blad=3)
-
{
-
$header[]='Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
-
$header[]='Accept-Language: pl,en-us;q=0.7,en;q=0.3';
-
$header[]='Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.7';
-
$header[]='Keep-Alive: 300';
-
$header[]='Connection: keep-alive';
-
-
$ch=curl_init();
-
curl_setopt($ch, CURLOPT_URL, $adres);
-
curl_setopt($ch, CURLOPT_HEADER, 0);
-
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
-
curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
-
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11');
-
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
-
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
-
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
-
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
-
if($post!==false)
-
{
-
curl_setopt($ch, CURLOPT_POST, true);
-
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
-
}
-
$zwroc=curl_exec($ch);
-
-
if($blad>0)
-
{
-
if($zwroc=='' OR curl_error($ch)!='' OR $naglowek=='4' OR $naglowek=='5')
-
{
-
curl_close($ch);
-
return otworz_adres($adres, $post, --$blad);
-
}
-
}
-
else
-
return false;
-
-
curl_close($ch);
-
return gzdecode($zwroc);
-
}
-
-
function gzdecode($tresc)
-
{
-
return $tresc;
-
}
-
?>
Wywołujemy ją w bardzo prosty sposób:
-
<?php
-
$tresc=otworz_adres('http://onet.pl/');
-
?>
Można również wysłać coś metodą POST. Wygląda to tak:
-
<?php
-
$tresc=otworz_adres('http://onet.pl', 'login=abc&haslo=123');
-
?>
Funkcja radzi sobie z napotykanymi błędami. Gdy coś pójdzie nie tak to 3 razy (można to zmienić, odpowiada za to parametr $blad w wywołaniu funkcji) próbuje pobrać dany adres. Dopiero po trzech niepowodzeniach zwracamy false czyli nie dało się otworzyć adresu.
Funkcja obsługuje kompresję gzip przy czym rozpoznaje czy serwer zwrócił normalne dane czy skompresowane. Pomyślałem, że warto coś takiego dodać bo jak serwer obsługuje gzip to aplikacja zadziała nam szybciej i zjemy mniej transferu. Wszystko dzieje się automatycznie i nie musimy sobie zawracać tym głowy.
Jak ktoś ma jakieś specyficzne wymagania to polecam poczytać o możliwościach curl_setopt. Wspomnę jeszcze, że dodałem obsługę cookies, trzeba tylko pamiętać o stworzeniu pliku cookies.txt
Jak ktoś jest ciekaw jak to wszystko działa to zapraszam do manuala do części o CURL
Możliwości jest sporo, każdy może sobie łatwo przystosować tą funkcję do własnych potrzeb.
UWAGA
Oczywiście aby funkcja działała wymagana jest włączona obsługa CURL na serwerze. Na szczęście jest to już praktycznie standard.
EDIT 2008.10.08
Do funkcji dodałem jedną linijkę: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Powoduje ona, że możemy pobierać strony https:// i nie powoduje to żadnych błędów.
Blog przede wszystkim o Internecie i mojej pasji jaką jest tworzenie stron www. Ale nie ograniczam się do jednej tematyki, piszę o wszystkim o czym mam ochotę :-)
macem napisał: 08.03.08 o godzinie 15:19
Hehe jakie kombinacje, problem będzie kiedy zmienią stronę i strukturę html, lepiej ciągnać takie rzeczy przed rss w postaci xml jeśli oczywiście serwis to obsługuje (lepiej szukać takich własnie serwisów).
MariuszT napisał: 08.03.08 o godzinie 20:47
Zależy od Twoich potrzeb. Jak piszesz jakiś automat, który ma chodzić po stronie i coś robić to nie ma innego wyjścia jak tylko grzebać w html (no chyba, że jest jakieś API ale wiadomo, że to rzadkość). Albo np. czasami chcę coś ściągnąć to piszę skrypt, włączam go i chodzi godzinę, dwie, dzień albo tydzień aż się dociągnie. Oczywistym jest, że gdy jest taka możliwość to trzeba korzystać z narzędzi udostępnionych przez twórców strony (rss, api itd.).