標籤:collect 進階 pcl 原因 ip地址 tor 常用 主機名稱 download
HttpClient的CircularRedirectException異常原因及解決辦法
這兩天在使用我自己爬蟲抓取網頁的時候總是出現
org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at ThreadPageDownload.run(DownPages.java:132)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to ‘http://XXXXXX/XXXXX‘
at org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(DefaultRedirectStrategy.java:183)
at org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(DefaultRedirectStrategy.java:217)
at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1105)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:548)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
... 5 more
------------------------
org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at ThreadPageDownload.run(DownPages.java:132)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to ‘http://XXXXXX/XXXXX‘
at org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(DefaultRedirectStrategy.java:183)
at org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(DefaultRedirectStrategy.java:217)
at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1105)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:548)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
... 5 more
看過網上的解決方案,後來在一個CSDN部落格中找到了答案,下面是我的解決方案
client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, false);
HttpUriRequest request = new HttpGet(url);
HttpEntity httpEntity = null;
request.addHeader("Accept-Charset", DEFAULT_CHARSET);
request.addHeader("Host", HOST);
request.addHeader("Accept", ACCEPT);
request.addHeader("User-Agent", USER_AGENT);
其中USER_AGENT的值為:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)
(有的網站會先判別使用者的請求是否是來自瀏覽器,如不是,則返回不正確的文本)
下面是別人的部落格原文,引用一下:
最近忙於一個項目,瞭解下httpclient,在這裡總結出來,和大家一起學習分享,希望各位朋友提出寶貴的意見。
首先介紹一下項目的背景:
目標:把國內一家保險公司的“WEB一賬通”改成“WAP一賬通”。
資源:客戶不提供任何的webservice介面。
本項目中用到的第三方組件是apache的httpclient,一個非常強大的網頁抓取工具(抓這個字用得可能不太好), 這裡和大家
一起討論下httpclient的一些常用用法和要注意的地方。
本文引用的資源清單:
httpclient入門: http://www.ibm.com/developerworks/cn/opensource/os-httpclient/
httpclient認證匯入:http://www.blogjava.net/happytian/archive/2006/12/22/89447.html
httpclient進階認識:http://laohuang.iteye.com/blog/55613
httpclient官方文檔:http://hc.apache.org/httpcomponents-client/index.html
httpclient資源關閉:http://www.iteye.com/topic/234759
上面的文章寫得很好,看完之後也就知道怎麼用httpclient這個很好的工具了,但是在這裡還是補充一些比較重要的東西,也是項目中經
常碰到的問題。
首先要注意的有以下幾點:
1、httpclient串連後資源釋放問題很重要,就跟我們用database connection要釋放資源一樣。
2、https網站採用ssl加密傳輸,認證匯入要注意。
3、做這樣的項目最好先瞭解下http協義,比如302,301,200,404傳回碼的含義(這是最基本的),cookie,session的機制。
4、httpclient的redirect狀態預設是自動的,這在很大程度上給開發人員很大的方便(如一些授權獲得cookie),但是有時要手動管理下,比如
有時會遇到CircularRedirectException異常,出現這樣的情況是因為返回的標頭檔中location值指向之前重複(連接埠號碼可以不同)地址,導致可能會出現死
迴圈遞迴重新導向,這時可以手動關閉:method.setFollowRedirects(false)
5、有的網站會先判別使用者的請求是否是來自瀏覽器,如不是,則返回不正確的文本,所以用httpclient抓取資訊時在頭部加入如下資訊:
header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");
6、當post請求提交資料時要改變預設編碼,不然的話提交上去的資料會出現亂碼。重寫postMethod的setContentCharSet()方法就可以了:
儘管像上面一樣修改了代碼,還是時常出現此異常,翻遍google才找到解決辦法:
就是設定【HttpClient參數】
這些是可以用於定製預設HttpClient實現行為的參數:
‘http.protocol.handle-redirects‘:定義了重新導向是否應該自動處理。這個參數期望得到一個java.lang.Boolean類型的值。如果這個參數沒有被設定,HttpClient將會自動處理重新導向。
‘http.protocol.reject-relative-redirect‘:定義了是否相對的重新導向應該被拒絕。HTTP規範需要位置值是一個絕對URI。這個參數期望得到一個java.lang.Boolean類型的值。如果這個參數沒有被設定,那麼就允許相對重新導向。
‘http.protocol.max-redirects‘:定義了要遵循重新導向的最大數量。這個重新導向數位限制意在防止由破碎的伺服器端指令碼引發的死迴圈。這個參數期望得到一個java.lang.Integer類型的值。如果這個參數沒有被設定,那麼只允許不多餘100次重新導向。
‘http.protocol.allow-circular-redirects‘:定義環形重新導向(重新導向到相同路徑)是否被允許。HTTP規範在環形重新導向沒有足夠清晰的允許表述,因此這作為可選的是可以開啟的。這個參數期望得到一個java.lang.Boolean類型的值。如果這個參數沒有被設定,那麼環形重新導向就不允許。
‘http.connection-manager.factory-class-name‘:定義了預設的ClientConnectionManager實現的類型。這個參數期望得到一個java.lang.String類型的值。如果這個參數沒有被設定,對於每個預設的將使用SingleClientConnManager。
‘http.virtual-host‘:定義了在頭部資訊Host中使用的虛擬機器主機名稱,來代替物理主機名稱。這個參數期望得到一個HttpHost類型的值。如果這個參數沒有被設定,那麼將會使用目標主機的名稱或IP地址。
‘http.default-headers‘:定義了每次請求預設發送的頭部資訊。這個參數期望得到一個包含Header對象的java.util.Collection類型值。
‘http.default-host‘:定義了預設主控件。如果目標主機沒有在請求URI(相對URI)中明確指定,那麼就使用預設值。這個參數期望得到一個HttpHost類型的值。
【解決辦法】
1234 |
HttpParams params = new BasicHttpParams(); HttpGet getMethod = new HttpGet(" http://XXXX.XXX");getMethod.getParams().setParameter("http.protocol.allow-circular-redirects", true);HttpResponse response = httpClient.execute(getMethod); |
HttpClient的CircularRedirectException異常原因及解決辦法