php curl возвращает 400 Bad Request, если делает в цикле - PullRequest
5 голосов
/ 15 ноября 2010

Я пытаюсь очистить экран с помощью библиотеки cUrl.

Мне удалось успешно очистить скрин, несколько URL (5-10).

Однако всякий раз, когда я запускаю его в цикле очистки больших (10-20) URL,

он достигнет точки, которую последние несколько URL вернут "HTTP / 1.1 400 Bad Request". Ваш браузер отправил запрос, который этот сервер не может понять.
Количество полей заголовка запроса превышает ограничение этого сервера.

Я почти уверен, что URL-адреса правильные и правильно обрезаны, а длина заголовков индивидуальна. Если я помещу эти последние несколько URL-адресов в верхнюю часть списка для очистки, он пройдет, но последние несколько из списка снова получат ошибку 400 Bad request. В чем может быть проблема? В чем может быть причина?

Любой совет?

Примерно так:


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 "<br/>";

    $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 "<br/>".$url;
            curl_setopt($ch, CURLOPT_URL, MY_HOST.$url);
            //echo "<br/>".$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 "<br/>".$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'];
    } 

где $ urls - это все URL-адреса, содержащие всю строку запроса для запроса get

Я понял из curl_getinfo, что [request_size] становится все больше и больше, чего не должно быть .. оно должно быть примерно одинакового размера. Как я могу распечатать / отослать мою информацию http-запроса для отладки?

Ответы [ 2 ]

6 голосов
/ 15 ноября 2010

Ваша проблема с умножением заголовков находится в верхней части метода 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';

На каждой итерации вы добавляете одинаковые заголовки в массив headers экземпляра объекта.(Например, array[] добавляет к массиву.) Вам нужно либо сбрасывать массив на каждой итерации, либо, возможно, перемещать настройку заголовков в другой метод.

Если headers всегда и только установлен в get Метод, вы можете изменить его на это, чтобы решить проблему:

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

... но если заголовки всегда одинаковы и никогда не менялись между итерациями, вы могли бы также установить заголовки 'значение в конструкторе объекта и считывается только из него в методе get, поскольку сброс массива на одно и то же значение все время является избыточным.

0 голосов
/ 15 ноября 2010

Если для CURLINFO_HEADER_OUT установлено значение true, я могу получить отправленную информацию запроса.

Действительно, заголовки запросов получают все больше и больше информации

У меня, в частности, этот заголовок увеличивается!

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...