2010-11-15 44 views
5

Estoy tratando de hacer un raspado de pantalla usando la biblioteca cUrl.php curl devuelve 400 Bad Request si lo hace en un bucle

Me las arreglé para eliminar con éxito raspado, algunas urls (5-10).

Sin embargo cada vez que corro en un bucle for raspar una mayor (10-20) URLs,

se llegará a un punto de los últimos direcciones URL devuelve "HTTP/1.1 400 Bad Request". Su navegador envió una solicitud que este servidor no pudo entender.
El número de campos de encabezado de solicitud excede el límite de este servidor.

Estoy bastante seguro de que las direcciones URL son correctas y están correctamente recortadas y la longitud de los encabezados es la misma de forma individual. Si puse estas últimas urls en la parte superior de la lista para raspar, se pasa, pero las últimas pocas de la lista obtienen el error de 400 Bad request. ¿Cual podría ser el problema? ¿Qué podría ser la causa?

¿Algún consejo?

algo parecido a continuación:

 

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']; }

donde $ URL son todas las URL que contengan toda la cadena de consulta para una petición GET

me di cuenta de curl_getinfo, el [request_size] es cada vez más y más grande que se no debería ser .. debería ser del mismo tamaño. ¿Cómo puedo imprimir/hacer eco de mi información de solicitud http para depurar?

+0

Por favor, muéstranos tu código. Sospecho que sigues acumulando parámetros en lugar de restablecerlos para cada iteración. – deceze

+1

no podemos decir la hora sin reloj, pero estás diciendo que el reloj está roto. muéstranos el reloj – stillstanding

+0

básicamente, estoy haciendo un bucle for en curl_exec en un $ url usando GET. $ url [0] .. $ url [99] tiene la misma longitud, no acumula los parámetros.sin embargo, como desde $ url [90] en wards, sigo golpeando 400 error de solicitud incorrecta. – flyclassic

Respuesta

5

Su problema con respecto a los encabezados de multiplicadores es en la parte superior del método 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'; 

En cada iteración se están añadiendo las mismas cabeceras al headers conjunto de la instancia del objeto. (Se agrega array[] a la matriz). Debe restablecer la matriz en cada iteración o quizás mover la configuración de encabezados a otro método.

Si headers siempre y sólo se fija en el método get, puede cambiarlo a esto con el fin de solucionar el problema:

$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' 
); 

... pero si los encabezados son siempre los mismos y nunca cambiado entre iteraciones, también podría establecer el valor de los encabezados en el constructor del objeto y solo leer de él en el método get, ya que reiniciar la matriz con el mismo valor todo el tiempo es redundante.

+0

creo que fue un error estúpido que hice ... ¡gracias! – flyclassic

+0

@fly: Mi placer. –

0

Configuración CURLINFO_HEADER_OUT en true, soy capaz de recuperar la información solicitada enviada.

De hecho, las cabeceras de petición se vuelve más y más información

particular me ha incrementando esta cabecera!

 
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

¿Alguien sabe lo que está pasando? ¿Cómo es que los encabezados para accept y content-type se agregan cada vez que se ejecuta a través de una iteración ???? – flyclassic

+0

Debe actualizar su pregunta si le está agregando más información, no crea una respuesta. No todos ven las respuestas ordenadas por tiempo. (AFAIK el orden predeterminado es por votos.) –

Cuestiones relacionadas