2010-11-15 12 views
5

Próbuję zrobić zrzut ekranu za pomocą biblioteki cUrl.php curl zwraca 400 Bad Request, jeśli działa w pętli

Udało mi się skutecznie skrobać, kilka adresów URL (5-10).

Jednak gdy uruchamiam go w pętli for skrobanie luzem (10-20) adresów URL

będzie osiągnąć punkt ostatnie kilka adresów URL powroty „HTTP/1.1 400 Bad Request”. Twoja przeglądarka wysłała żądanie, którego ten serwer nie mógł zrozumieć.
Liczba pól nagłówka żądania przekracza limit tego serwera.

Jestem prawie pewien, że adresy URL są poprawne i poprawnie przycięte, a długość nagłówków jest taka sama. Jeśli umieściłem kilka ostatnich adresów URL na górze listy, aby ją zeskrobać, przechodzi ona dalej, ale na ostatnich kilku listach ponownie pojawia się błąd 400 nieprawidłowych żądań. Jaki może być problem? Co może być przyczyną?

Dowolna porada?

coś takiego jak poniżej:

 

for($i=0;$i > sizeof($url);$i++)  
$data[$i] = $this->get($url[$i]); 



function get($url) { 

$this->headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg'; 
     $this->headers[] = 'Connection: Keep-Alive'; 
     $this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8'; 
     $this->user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 (.NET CLR 3.5.30729)'; 

set_time_limit(EXECUTION_TIME_LIMIT); 
     $default_exec_time = ini_get('max_execution_time'); 

     $this->redirectcount = 0; 
     $process = curl_init($url); 
     curl_setopt($process, CURLOPT_HTTPHEADER, $this->headers); 
     curl_setopt($process, CURLOPT_HEADER, 1); 
     curl_setopt($process, CURLOPT_USERAGENT, $this->user_agent); 
     if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEFILE, $this->cookie_file); 
     if ($this->cookies == TRUE) curl_setopt($process, CURLOPT_COOKIEJAR, $this->cookie_file); 

     //off compression for debugging's sake 
     //curl_setopt($process,CURLOPT_ENCODING , $this->compression); 

     curl_setopt($process, CURLOPT_TIMEOUT, 180); 
     if ($this->proxy) curl_setopt($process, CURLOPT_PROXY, $this->proxy); 
     if ($this->proxyauth){ 
      curl_setopt($process, CURLOPT_HTTPPROXYTUNNEL, 1); 
      curl_setopt($process, CURLOPT_PROXYUSERPWD, $this->proxyauth); 
     } 
     curl_setopt($process, CURLOPT_RETURNTRANSFER, 1); 
     curl_setopt($process, CURLOPT_FOLLOWLOCATION, TRUE); 
     curl_setopt($process,CURLOPT_MAXREDIRS,10); 

     //added 
     //curl_setopt($process, CURLOPT_AUTOREFERER, 1); 
     curl_setopt($process,CURLOPT_VERBOSE,TRUE); 
     if ($this->referrer) curl_setopt($process,CURLOPT_REFERER,$this->referrer); 

     if($this->cookies){ 
      foreach($this->cookies as $cookie){ 
       curl_setopt ($process, CURLOPT_COOKIE, $cookie); 
       //echo $cookie; 
      } 
     } 

     $return = $this->redirect_exec($process);//curl_exec($process) or curl_error($process); 
     curl_close($process); 
     set_time_limit($default_exec_time);//setback to default 

     return $return; 
    } 

    function redirect_exec($ch, $curlopt_header = false) { 

    //curl_setopt($ch, CURLOPT_HEADER, true); 
    //curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    $data = curl_exec($ch); 
    $file = fopen(DP_SCRAPE_DATA_CURL_DIR.$this->redirectcount.".html","w"); 
    fwrite($file,$data); 
    fclose($file); 

    $info = curl_getinfo($ch); 
    print_r($info);echo "
"; $http_code = $info['http_code']; if ($http_code == 301 || $http_code == 302 || $http_code == 303) { //list($header) = explode("\r\n\r\n", $data); //print_r($header); $matches = array(); //print_r($data); //Check if the response has a Location to redirect to preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches); $url = trim(array_pop($matches)); //print_r($url); $url_parsed = parse_url($url); //print_r($url_parsed); if (isset($url_parsed['path']) && isset($url) && !empty($url)) { //echo "
".$url; curl_setopt($ch, CURLOPT_URL, MY_HOST.$url); //echo "
".$url; $this->redirectcount++; return $this->redirect_exec($ch); //return $this->get(MY_HOST.$url); //$this->redirect_exec($ch); } } elseif($http_code == 200){ $matches = array(); preg_match('/(/i', $data, $matches); //print_r($matches); $url = trim(array_pop($matches)); //print_r($url); $url_parsed = parse_url($url); //print_r($url_parsed); if (isset($url_parsed['path']) && isset($url) && !empty($url)) { curl_setopt($ch, CURLOPT_URL, $url); //echo "
".$url; $this->redirectcount++; sleep(SLEEP_INTERVAL); return $this->redirect_exec($ch); //return $this->get($url); //$this->redirect_exec($ch); } } //echo "data ".$data; $this->redirectcount++; return $data ; // $info['url']; }

gdzie $ adresy URL są wszystkie adresy URL zawierające cały ciąg kwerendy dla żądania GET

zdałem sobie sprawę z curl_getinfo w [request_size] jest coraz większe i większe, które ją nie powinno być ... powinno być mniej więcej tego samego rozmiaru. Jak mogę wydrukować/echo moje informacje o żądaniu http do debugowania?

+0

Pokaż nam swój kod. Podejrzewam, że zachowujesz ustawienia parametrów, jeśli zresetujesz je dla każdej iteracji. – deceze

+1

Nie możemy powiedzieć czasu bez zegara, ale mówisz, że zegar jest zepsuty. pokaż nam zegar. – stillstanding

+0

zasadniczo, robię pętlę for curl_exec na $ url używając GET. $ url [0] .. $ url [99] ma tę samą długość, nie układa się w parametry.jednak jak z $ url [90] na oddziałach, ciągle trafiam 400 błędnych błędów w żądaniu. – flyclassic

Odpowiedz

5

Twój problem dotyczący nagłówków mnożących jest na górze metody get:

$this->headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg'; 
$this->headers[] = 'Connection: Keep-Alive'; 
$this->headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8'; 

Na każdej iteracji dodajesz te same nagłówki do tablicy instancji obiektu headers. (Mówiąc, że array[] dołącza do tablicy.) Musisz albo zresetować tablicę w każdej iteracji, albo przenieść ustawienie nagłówków do innej metody.

Jeśli headers jest zawsze i tylko ustawić w metodzie get, można zmienić go na to, aby rozwiązać ten problem:

$this->headers = array(
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg', 
    'Connection: Keep-Alive', 
    'Content-type: application/x-www-form-urlencoded;charset=UTF-8' 
); 

... ale jeśli nagłówki są zawsze takie same i nigdy nie zmienił między iteracjami można równie dobrze ustawić wartość nagłówków w konstruktorze obiektów i odczytać z niej tylko w metodzie get, ponieważ resetowanie tablicy do tej samej wartości przez cały czas jest zbędne.

+0

Myślę, że to był głupi błąd, który popełniłem .. dzięki! – flyclassic

+0

@fly: Moja przyjemność. –

0

Ustawienie CURLINFO_HEADER_OUT na true, jestem w stanie odzyskać wysłane informacje o żądaniu.

Rzeczywiście, nagłówki żądania dostaje coraz więcej informacji

Szczególnie jest to nagłówek zwiększając!

 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 
Connection: Keep-Alive 
Content-type: application/x-www-form-urlencoded;charset=UTF-8 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 
Connection: Keep-Alive 
Content-type: application/x-www-form-urlencoded;charset=UTF-8 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 
Connection: Keep-Alive 
Content-type: application/x-www-form-urlencoded;charset=UTF-8 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 
Connection: Keep-Alive 
Content-type: application/x-www-form-urlencoded;charset=UTF-8
+0

Ktoś wie, co się dzieje? jak to się dzieje, że nagłówki do akceptowania i typ zawartości są dodawane za każdym razem, gdy działa przez iterację ???? – flyclassic

+0

Należy zaktualizować pytanie, jeśli dodajesz do niego więcej informacji, a nie utwórz odpowiedź. Nie wszyscy widzą odpowiedzi uporządkowane według czasu. (AFAIK domyślna kolejność jest przez głosy.) –

Powiązane problemy