Ⅰ php Curl出現403錯誤怎麼辦
使用curl抓網頁下來處理,為了穿牆方便,使用Privoxy作為代理,便於選擇哪些網站使用proxy、哪些不用。但今天卻遇到了奇怪的問題,訪問google這些網站居然都返回403錯誤,而訪問其他的一些網站沒事,如果設置為不使用proxy則都能正常訪問。
難道google就不讓用proxy連接么?顯然不可能,所以打開curl的信息輸出(curl_setopt($this->mSh,CURLOPT_VERBOSE,1);)看看,得到以下結果:
.代碼如下:
*Trying127.0.0.1...*connected
*Connectedto127.0.0.1(127.0.0.1)port8118(#0)
*EstablishHTTPproxytunneltowww..com:80
>CONNECTwww..com:80HTTP/1.0
Host:www..com:80
User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)
Proxy-Connection:Keep-Alive
<HTTP/1.0403Connectionnotallowable
<X-Hint:,thenyouknowwhythishappens,-)
<
*TherequestedURLreturnederror:403
*
*Closingconnection#0
...Failed.
可以看到proxy伺服器工作正常,的確是返回了403錯誤,但原因肯定還在我這邊。終於,從網上(1of2,2of2)得到了點啟發──我使用的是proxytunnel而非proxy。
在代碼中,有這么一句:
.代碼如下:
curl_setopt($this->mSh,CURLOPT_HTTPPROXYTUNNEL,true);
curl_setopt($this->mSh,CURLOPT_PROXY,$phost);
php文檔中沒有詳細說明,不過mancurl中有詳細解釋,兩者都是代理,proxytunnel(-p參數)允許其他協議通過http代理傳輸,而proxy(-x參數)則只能走http協議。所以我猜測,google的伺服器和curl的proxytunnel不和,所以返回403。
禁用掉上面2行代碼的第一句後,curl訪問恢復正常。
比較奇怪的是,幾種操作系統下還不一樣,一台MACOSX就要顯式的禁用proxytunnel才可以,curl版本:
.代碼如下:
$curl--version
curl7.16.3(powerpc-apple-darwin9.0)libcurl/7.16.3OpenSSL/0.9.7lzlib/1.2.3
Protocols:
Features:GSS-
而另外一台ubuntu則完全不受影響,怎麼都能用,curl版本:
.代碼如下:
$curl--version
curl7.18.2(i486-pc-linux-gnu)libcurl/7.18.2OpenSSL/0.9.8gzlib/1.2.3.3libidn/1.10
Protocols:
Features:GSS-
MT主機上的centos也沒事,curl版本:
.代碼如下:
$curl--version
curl7.15.5(i686-redhat-linux-gnu)libcurl/7.15.5OpenSSL/0.9.8bzlib/1.2.3libidn/0.6.5
Protocols:
Features:GSS-
看來不完全是curl版本問題,MACOSX的確與眾不同啊。
還有一個原因也會導致curl返回403錯誤,如果設置了:
.代碼如下:
curl_setopt($ch,CURLOPT_NOBODY,true);
則需要緊跟著設置:
.代碼如下:
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,'GET');
不然會因為http伺服器不允許HEAD命令而返回403錯誤。參考:TroublewithacURLrequestinPHP(forums.devshed.com/php-development-5/trouble-with-a-curl-request-in-php-445222.html)。MACOSX上curl之所以特殊,也不排除是這種原因