這兩天在使用我本身爬蟲抓取網頁的時候老是出現 html
org.apache.http.client.ClientProtocolException java
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909) web
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) apache
at ThreadPageDownload.run(DownPages.java:132) 瀏覽器
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 服務器
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) cookie
at java.lang.Thread.run(Unknown Source) session
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to 'http://XXXXXX/XXXXX' app
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這個很好的工具了,可是在這裏仍是補充一些比較重要的東西,也是項目中經
常碰到的問題。
首先要注意的有如下幾點:
一、httpclient鏈接後資源釋放問題很重要,就跟咱們用database connection要釋放資源同樣。
二、https網站採用ssl加密傳輸,證書導入要注意。
三、作這樣的項目最好先了解下http協義,好比302,301,200,404返回代碼的含義(這是最基本的),cookie,session的機制。
四、httpclient的redirect狀態默認是自動的,這在很大程度上給開發者很大的方便(如一些受權得到cookie),可是有時要手動管理下,好比
有時會遇到CircularRedirectException異常,出現這樣的狀況是由於返回的頭文件中location值指向以前重複(端口號能夠不一樣)地址,致使可能會出現死
循環遞歸重定向,這時能夠手動關閉:method.setFollowRedirects(false)
五、有的網站會先判別用戶的請求是不是來自瀏覽器,如不是,則返回不正確的文本,因此用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)");
六、當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類型的值。
【解決辦法】
1
2
3
4
|
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);
|