php curl 如果在循环中返回 400 Bad Request

Posted

技术标签:

【中文标题】php curl 如果在循环中返回 400 Bad Request【英文标题】:php curl returns 400 Bad Request if does in a loop 【发布时间】:2011-05-10 02:35:08 【问题描述】:

我正在尝试使用 cUrl 库进行屏幕抓取。

我成功筛选了抓取,几个网址(5-10)。

但是,每当我在 for 循环中运行它时,会抓取大量 (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]); 函数获取($url) $this->headers[] = '接受:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg , 图像/pjpeg'; $this->headers[] = '连接:保持活动'; $this->headers[] = '内容类型:应用程序/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)'; 设置时间限制(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); //为了调试而关闭压缩 //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); //添加 //curl_setopt($process, CURLOPT_AUTOREFERER, 1); curl_setopt($process,CURLOPT_VERBOSE,TRUE); if ($this->referrer) curl_setopt($process,CURLOPT_REFERER,$this->referrer); 如果($this->cookies) foreach($this->cookies as $cookie) curl_setopt ($process, CURLOPT_COOKIE, $cookie); //回声$cookie; $return = $this->redirect_exec($process);//curl_exec($process) 或 curl_error($process); curl_close($过程); set_time_limit($default_exec_time);//恢复默认值 返回 $return; 函数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($文件,$数据); fclose($文件); $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 = 数组(); //print_r($data); //检查响应是否有要重定向到的位置 preg_match('/(位置:|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++; 返回 $this->redirect_exec($ch); //return $this->get(MY_HOST.$url); //$this->redirect_exec($ch); elseif($http_code == 200) $matches = 数组(); 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_INTERVAL); 返回 $this->redirect_exec($ch); //返回 $this->get($url); //$this->redirect_exec($ch); //回显“数据”。$数据; $this->redirectcount++; 返回$数据; // $info['url'];

其中 $urls 是包含获取请求的所有查询字符串的所有 url

我从 curl_getinfo 意识到,[request_size] 变得越来越大,它不应该是.. 它应该是大约相同的大小。如何打印/回显我的 http 请求信息以进行调试?

【问题讨论】:

请向我们展示您的代码。如果每次迭代都重置它们,我怀疑你会继续堆积参数。 没有时钟我们无法判断时间,但您是说时钟坏了。给我们看时钟。 基本上,我正在使用 GET 在 $url 上的 curl_exec 上执行 for 循环。 $url[0] .. $url[99] 的长度相同,不会堆积在参数上。但是,就像病房的 $url[90] 一样,我一直遇到 400 错误请求错误。 我从 curl_getinfo 意识到,[request_size] 在每次迭代后变得越来越大,它不应该是......它应该是大约相同的大小。如何打印/回显我的 http 请求信息以进行调试? 怀疑每个循环的请求大小都在增加,因此越来越大,我该如何克服这个问题? CURLOPT_FRESH_CONNECT 会解决问题还是关闭并重新打开 exec 连接有帮助?克服这个问题的最佳方法是什么?任何人?还有我怎样才能打印出请求http? 【参考方案1】:

CURLINFO_HEADER_OUT设置为true,我可以检索发送的请求信息。

确实,请求头得到的信息越来越多

我特别有这个标题递增!

接受:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 连接:保持活动状态 内容类型:application/x-www-form-urlencoded;charset=UTF-8 接受:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 连接:保持活动状态 内容类型:application/x-www-form-urlencoded;charset=UTF-8 接受:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 连接:保持活动状态 内容类型:application/x-www-form-urlencoded;charset=UTF-8 接受:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, image/gif, image/x-bitmap, image/jpeg, image/pjpeg 连接:保持活动状态 内容类型:application/x-www-form-urlencoded;charset=UTF-8

【讨论】:

有人知道发生了什么吗?为什么每次通过迭代运行时都会添加接受和内容类型的标头???? 如果您要向其添加更多信息,则应该更新您的问题,而不是创建答案。不是每个人都会查看按时间排序的答案。 (AFAIK 默认排序是投票。)【参考方案2】:

您关于乘法标头的问题位于 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 方法中从中读取,因为将数组重置为始终相同的值是多余的。

【讨论】:

以上是关于php curl 如果在循环中返回 400 Bad Request的主要内容,如果未能解决你的问题,请参考以下文章

OAuth、PHP、Rest API 和 curl 给出 400 Bad Request

Python post 请求在请求库中引发 400 'Bad Request' 错误,但适用于 cURL

Ajax 返回 400 Bad Request (xhr),admin-ajax.php 返回 '0'?

RPC 失败; HTTP 400 curl 22 The requested URL returned error: 400 Bad Request

通过表单在 Flask 上发布数据给出 400 Bad Request

Wordpress 在使用 fetch API 的 ajax 调用上返回 400 Bad Request