近期迷戀上httpclient模擬各種網(wǎng)站登陸,瀏覽器中的開(kāi)發(fā)者工具中查看請(qǐng)求頭信息,然后照葫蘆畫(huà)瓢寫(xiě)到httpclient的請(qǐng)求中去,requestheader中有這么一段設(shè)置:
Accept-Encoding gzip,deflate
之前模擬其他網(wǎng)站的時(shí)候這塊并沒(méi)有太在意,因?yàn)闊o(wú)論我在httpclient中添加上這段還是不添加,請(qǐng)求網(wǎng)站數(shù)據(jù)都沒(méi)有任何影響,也不影響網(wǎng)站的安全檢測(cè),所以當(dāng)時(shí)也就沒(méi)有特別關(guān)注這個(gè)設(shè)置,直到模擬登陸58同城網(wǎng)站的時(shí)候第一次遇到這個(gè)問(wèn)題,當(dāng)添加上以上的這行請(qǐng)求頭設(shè)置的時(shí)候,返回的網(wǎng)頁(yè)數(shù)據(jù)是亂碼,而且是那種各種粗體方塊的亂碼,經(jīng)驗(yàn)告訴我這種亂碼表現(xiàn)并不是簡(jiǎn)單的編碼錯(cuò)誤造成的,因?yàn)橹辽儆⑽牟粦?yīng)該出現(xiàn)亂碼..而且如果是簡(jiǎn)單的gbk,utf-8之間的亂碼也不會(huì)出現(xiàn)這種大面積的粗體方塊..
然后想到這個(gè)Accept-Encoding,百度后知道,這個(gè)是用來(lái)設(shè)置從網(wǎng)站中接收的返回?cái)?shù)據(jù)是否進(jìn)行g(shù)zip壓縮.這也就解釋了為何返回的數(shù)據(jù)是大面積的粗體方塊亂碼,因?yàn)槭菈嚎s過(guò)的數(shù)據(jù),也就不可能進(jìn)行正常解碼.
http://blog.csdn.net/zhangxinrun/article/details/5711307 這是一篇介紹gzip,deflate具體含義的博文
防止鏈接失效我直接摘抄一段:
gzip是一種數(shù)據(jù)格式,默認(rèn)且目前僅使用deflate算法壓縮data部分;deflate是一種壓縮算法,是huffman編碼的一種加強(qiáng)。deflate與gzip解壓的代碼幾乎相同,可以合成一塊代碼。區(qū)別僅有:deflate使用inflateInit(),而gzip使用inflateInit2()進(jìn)行初始化,比 inflateInit()多一個(gè)參數(shù): -MAX_WBITS,表示處理raw deflate數(shù)據(jù)。因?yàn)間zip數(shù)據(jù)中的zlib壓縮數(shù)據(jù)塊沒(méi)有zlib header的兩個(gè)字節(jié)。使用inflateInit2時(shí)要求zlib庫(kù)忽略zlib header。在zlib手冊(cè)中要求windowBits為8..15,但是實(shí)際上其它范圍的數(shù)據(jù)有特殊作用,見(jiàn)zlib.h中的注釋,如負(fù)數(shù)表示raw deflate。Apache的deflate變種可能也沒(méi)有zlib header,需要添加假頭后處理。即MS的錯(cuò)誤deflate (raw deflate).zlib頭第1字節(jié)一般是0x78, 第2字節(jié)與第一字節(jié)合起來(lái)的雙字節(jié)應(yīng)能被31整除,詳見(jiàn)rfc1950。例如Firefox的zlib假頭為0x7801,python zlib.comPRess()結(jié)果頭部為0x789c。deflate 是最基礎(chǔ)的算法,gzip 在 deflate 的 raw data 前增加了 10 個(gè)字節(jié)的 gzheader,尾部添加了 8 個(gè)字節(jié)的校驗(yàn)字節(jié)(可選 crc32 和 adler32) 和長(zhǎng)度標(biāo)識(shí)字節(jié)。
問(wèn)題到這里看似已經(jīng)清晰了,但是依然有一個(gè)疑點(diǎn),就是我之前模擬登陸網(wǎng)站的時(shí)候一直會(huì)設(shè)置這個(gè)header請(qǐng)求頭,但是返回的數(shù)據(jù)卻不是壓縮過(guò)的.這看起來(lái)有些矛盾,經(jīng)過(guò)進(jìn)一步收集資料得知,瀏覽器中的都是會(huì)自動(dòng)進(jìn)行解壓縮的,故請(qǐng)求頭中都會(huì)加入這么一個(gè)編碼設(shè)置,并且網(wǎng)站的服務(wù)端并不是都支持這個(gè)請(qǐng)求頭參數(shù),也就是說(shuō)即便在請(qǐng)求頭中加入這么一個(gè)壓縮設(shè)置,服務(wù)器端返回?cái)?shù)據(jù)的時(shí)候也不一定會(huì)進(jìn)行壓縮才返回..至此疑問(wèn)都清除..
然后接下來(lái)就好辦了,既然知道了問(wèn)題的原因,那么我們用httpclient進(jìn)行接收的時(shí)候也就好處理了,如果對(duì)方支持gzip壓縮處理且我們的請(qǐng)求頭中也加入的gzip壓縮請(qǐng)求頭,那么返回header中會(huì)有這么一個(gè)返回頭信息:
Content-Encoding gzip
我們?cè)诮邮辗祷匦畔⒌臅r(shí)候只需要稍微檢測(cè)一下返回頭中是否含有以上信息就可以進(jìn)行相應(yīng)的處理了,一段示例代碼如下:
HttpResponse rep = client.execute(post);Header[] headers = rep.getHeaders("Content-Encoding");boolean isGzip = false;for(Header h:headers){ if(h.getValue().equals("gzip")){ //返回頭中含有g(shù)zip isGzip = true; }}String responseString = null;if(isGzip){ //需要進(jìn)行g(shù)zip解壓處理 responseString = EntityUtils.toString(new GzipDecompressingEntity(rep.getEntity()));}else{ responseString = EntityUtils.toString(rep.getEntity());}至此那個(gè)讓人抓狂的粗體方塊亂碼問(wèn)題解決完畢..
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注