本文將根據(jù)實踐經(jīng)驗說明python中使用requests庫編寫爬蟲程序時,出現(xiàn)【中文亂碼】的原因及解決辦法。
首先,本文的【中文亂碼】情況,指的是原網(wǎng)頁中的中文內(nèi)容在使用requests獲取后,中文完全無法識別的情況,區(qū)別于\x、\u等編碼情況。如下圖中的例子:
導(dǎo)致上圖中【中文亂碼】的原因:
使用requests庫時,選擇使用的文本響應(yīng)方法不合適,且沒有在代碼中添加設(shè)置合適的編碼,以致于使用【response.text】自動獲取到的網(wǎng)頁編碼,與實際網(wǎng)頁的編碼不一致,進(jìn)而產(chǎn)生【中文亂碼】。
使用requests庫時,可能已經(jīng)形成了一個習(xí)慣,常用【response.text】進(jìn)行文本響應(yīng),而【response.content】常用于圖片、視頻等。
這兩者,最大的一個區(qū)別就是:
1、【response.text】會自動根據(jù)HTTP頭部去推測網(wǎng)頁的編碼,解碼并返回解碼后的文本。
2、【response.content】不會解碼,直接以二進(jìn)制形式返回。
兩種文本響應(yīng)方法,如下表:
response.text | 服務(wù)器響應(yīng)的內(nèi)容,會自動根據(jù)響應(yīng)頭部的字符編碼進(jìn)行解碼。根據(jù)HTTP頭部對響應(yīng)的編碼做出有根據(jù)的推測,推測文本編碼。返回類型:str;常用于:響應(yīng)文本 |
response.content | 字節(jié)方式的響應(yīng)體,不會根據(jù)HTTP頭部對響應(yīng)的編碼做出有根據(jù)的推測。返回類型:bytes(二進(jìn)制);常用于:圖片、視頻 |
最有效的解決方法:
使用response的encoding、apparent_encoding,得到網(wǎng)頁編碼。
encoding、apparent_encoding兩者最大的區(qū)別:
encoding是從header中去提取,而apparent_encoding是從網(wǎng)頁源碼去解析,apparent_encoding得到的結(jié)果更準(zhǔn)確。
詳細(xì)如下表:
response.encoding | 從網(wǎng)頁響應(yīng)的header中,提取charset字段中的編碼。若header中沒有charset字段,則默認(rèn)為ISO-8859-1編碼模式,ISO-8859-1編碼無法解析中文,這也是中文亂碼的原因。 |
response.apparent_encoding | 從網(wǎng)頁的內(nèi)容中(html源碼)中分析網(wǎng)頁編碼的方式。所以apparent_encoding比encoding更加準(zhǔn)確,獲取到的才是原網(wǎng)頁的實際編碼。 |
print(response.apparent_encoding)
print(response.encoding)
使用encoding、apparent_encoding兩種方法,所得的結(jié)果是不一致的,apparent_encoding才是原網(wǎng)頁實際編碼。如下圖
根據(jù)上述方法,獲得原網(wǎng)頁的實際編碼后,手動在代碼中指定文本編碼格式,即可解決【中文亂碼】問題。如下圖:
response.encoding=response.apparent_encoding
以上就是使用requests爬蟲解決中文亂碼的方法,如那位老師有更好的方法還望賜教,謝謝!
多網(wǎng)站前端設(shè)計師在設(shè)計網(wǎng)站的時候,都會碰到網(wǎng)站在快速瀏覽器下顯示正常,在ie下可能就會出現(xiàn)錯位的情況!所以我們在設(shè)計網(wǎng)站之前一定要先了解IE兼容性問題。
關(guān)于CSS對IE的兼容問題一直是DIV+CSS的一個大問題,因為不通瀏覽器識別代碼產(chǎn)生的效果是不同的,所以造成了很多瀏覽器對相同的CSS,產(chǎn)生不同的效果,這樣就產(chǎn)生了網(wǎng)站的錯位,個人理解是這樣的。
網(wǎng)站設(shè)計
先來了解下瀏覽器的內(nèi)核:
瀏覽器內(nèi)核又可以分成兩部分:渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。它負(fù)責(zé)取得網(wǎng)頁的內(nèi)容(HTML、XML、圖像等等)、整理訊息(例如加入 CSS 等),以及計算網(wǎng)頁的顯示方式,然后會輸出至顯示器或打印機。瀏覽器的內(nèi)核的不同對于網(wǎng)頁的語法解釋會有不同,所以渲染的效果也不相同。所有網(wǎng)頁瀏覽器、電子郵件客戶端以及其它需要編輯、顯示網(wǎng)絡(luò)內(nèi)容的應(yīng)用程序都需要內(nèi)核。JS 引擎則是解析 Javascript 語言,執(zhí)行 javascript 語言來實現(xiàn)網(wǎng)頁的動態(tài)效果。
最開始渲染引擎和 JS 引擎并沒有區(qū)分的很明確,后來 JS 引擎越來越獨立,內(nèi)核就傾向于只指渲染引擎。有一個網(wǎng)頁標(biāo)準(zhǔn)計劃小組制作了一個 ACID 來測試引擎的兼容性和性能。內(nèi)核的種類很多,如加上沒什么人使用的非商業(yè)的免費內(nèi)核,可能會有 10 多種,但是常見的瀏覽器內(nèi)核可以分這四種:Trident、Gecko、Blink、Webkit。
各個瀏覽器內(nèi)核不同,就可能造成不兼容的情況出現(xiàn)。
常見的兼容性問題:
1、不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補丁( margin )和內(nèi)補丁(padding)不同
解決方案: css 里增加通配符 * { margin: 0; padding: 0; }
2、IE6雙邊距問題;在 IE6中設(shè)置了float , 同時又設(shè)置margin , 就會出現(xiàn)邊距問題
解決方案:設(shè)置display:inline;
3、當(dāng)標(biāo)簽的高度設(shè)置小于10px,在IE6、IE7中會超出自己設(shè)置的高度
解決方案:超出高度的標(biāo)簽設(shè)置overflow:hidden,或者設(shè)置line-height的值小于你的設(shè)置高度
4、圖片默認(rèn)有間距
解決方案:使用float 為img 布局
5、IE9一下瀏覽器不能使用opacity
解決方案:
opacity: 0.5;filter: alpha(opacity = 50);filter: progid:DXImageTransform.Microsoft.Alpha(style = 0, opacity = 50);
6、邊距重疊問題;當(dāng)相鄰兩個元素都設(shè)置了margin 邊距時,margin 將取最大值,舍棄最小值;
解決方案:為了不讓邊重疊,可以給子元素增加一個父級元素,并設(shè)置父級元素為overflow:hidden;
7、cursor:hand 顯示手型在safari 上不支持
解決方案:統(tǒng)一使用 cursor:pointer
8、兩個塊級元素,父元素設(shè)置了overflow:auto;子元素設(shè)置了position:relative ;且高度大于父元素,在IE6、IE7會被隱藏而不是溢出;
解決方案:父級元素設(shè)置position:relative
關(guān)于瀏覽器兼容性的這種錯位,因為瀏覽器的種類越來越多,從IE5,6,7,8,9,10這些都是比較常用的瀏覽器,但是正因為各種瀏覽器的出現(xiàn),為了更好的兼容各個版本的瀏覽器,我們就需要學(xué)習(xí)如何來處理IE的兼容問題。從而網(wǎng)絡(luò)上出現(xiàn)了很多所謂的HACK ,其實也就是針對各個瀏覽器的特點,來對各種瀏覽器的不同嗜好,產(chǎn)生的不同效果,實現(xiàn)的一種兼容各個版本瀏覽器的效果。
這個地方我們我們不是來講各種可見的HACK效果,這些大家,可以在百度上來一下,就能找到我們所要的結(jié)果。
因為IE從6開始為了適應(yīng)各個版本,就自身有了一個兼容性,所以我們可以指定給網(wǎng)頁一個兼容特性;
比如 網(wǎng)頁在IE7下無錯位,但在IE6 和 IE8下有錯位,那么我們就可以指定當(dāng)用戶使用IE6和IE8的時候直接指定給IE6 和 IE8采用IE7的兼容模式來實現(xiàn)網(wǎng)頁的不錯位。
但是這樣一來,網(wǎng)頁的兼容特性只是實現(xiàn)了,IE6,IE7,IE8的一個兼容,為了同時兼容FF,我們這個時候就需要使用HACK來達(dá)到兼容FF的效果。
這樣我們使用IE自身的特性和HACK之間的特性就達(dá)到了網(wǎng)頁的兼容效果,我認(rèn)為這樣實現(xiàn)兼容效果是最簡單最方便的。這樣我們其實就是對一種IE和FF之間的HACK在起作用,相對的寫了很少的代碼,也很實用和方便。
兼容性的問題越來越重要了,特別是IE8的出現(xiàn)讓當(dāng)時大半的網(wǎng)頁都出現(xiàn)錯位等現(xiàn)象,而解決的辦法,我們來看一個網(wǎng)上的例子:
“css兼容IE8
微軟在IE8提供三種解析頁面的模式:
IE8 Standard Modes :默認(rèn)的最標(biāo)準(zhǔn)的模式,嚴(yán)格按照W3C相關(guān)規(guī)定
IE7 Standards Modes :IE7現(xiàn)在用的解析網(wǎng)頁的模式,開起機關(guān)是在<head>中加入 <meta http-equiv="X-UA-Compatible" content="IE=7">
Quirks Modes :IE5用的解析網(wǎng)頁的模式,開起機關(guān)是刪除HTML頂部的DOCTYPE聲明
注意:不同模式間的網(wǎng)頁在IE8中可以互相 frame ,因此因不會模式下的DOM和CSS渲染不一樣,所以會引發(fā)很多問題,務(wù)必注意如果你的頁面對IE7兼容沒有問題,又不想大量修改現(xiàn)有代碼,同時又能在IE8中正常使用,微軟聲稱,開發(fā)商僅需要在目前兼容IE7的網(wǎng)站上添加一行代碼即可解決問題,此代碼如下:
<meta http-equiv="x-ua-compatible" content="ie=7" />”
加了以上這個代碼,就可以比較完美的解決一般的兼容性問題了。
位小伙伴今天我們來了解
JavaWeb 中的 Response
1)HttpServletResponse 概述
我們在創(chuàng)建 Servlet 時會覆蓋 service() 方法,或 doGet()/doPost(),這些方法都有兩個參數(shù),分別是代表請求的 request 和代表響應(yīng) response。(今天我們主要來說說 response)
service 方法中的 response 的類型是 ServletResponse,而 doGet/doPost 方法的 response 的類型是 HttpServletResponse,HttpServletResponse 是ServletResponse 的子接口,功能和方法更加強大,所以今天我們來學(xué)習(xí)的就是 HttpServletResponse。
2)response 的運行流程
當(dāng)我們通過頁面請求 web 應(yīng)用的時候,Tomcat 就會創(chuàng)建一個 request 對象,和一個 response 對象一起傳進(jìn) Servlet 中,然后 Tomcat 會把response 緩沖區(qū)中的內(nèi)容取出來 包裝成一個 http 響應(yīng)返回頁面~
因為 response 代表響應(yīng),所以我們可以通過該對象分別設(shè)置 Http 響應(yīng)的響應(yīng)行,響應(yīng)頭和響應(yīng)體
3)通過response設(shè)置響應(yīng)行
常用的狀態(tài)碼如下:
200 :請求成功。
302 :請求重定向。
304 :請求資源沒有改變,訪問本地緩存。
404 :請求資源不存在。
500 :服務(wù)器內(nèi)部錯誤。
通過 setStatus(int sc)方法可以設(shè)置響應(yīng)行的狀態(tài)碼。
4)通過 response 設(shè)置響應(yīng)頭
方法:
addHeader(String name, String value)
addIntHeader(String name, int value)
addDateHeader(String name, long date)
setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)
其中,add表示添加,而set表示設(shè)置(會替換掉先前的內(nèi)容)
5)重定向
重定向的意思:就好像我們?nèi)フ覐埲桢X,張三沒錢,然后告訴我們李四有,讓我們?nèi)フ依钏摹N覀兪盏竭@個消息之后,就去找李四了。這就是一個重定向的過程。
下面用代碼來演示一下:
首先設(shè)置狀態(tài)碼302,然后設(shè)置頁面的路徑~
這樣在我們訪問 Servlet1 的時候,頁面就會跳轉(zhuǎn)到 Servlet2 。
這個就是重定向了~我們也可以把 Servlet1 中的兩句代碼簡化成為一行
這個是Sun公司為我們封裝好玩的呦~
6)通過 response 設(shè)置響應(yīng)體
響應(yīng)體設(shè)置文本
PrintWriter getWriter()
獲得字符流,通過字符流的 write(String s) 方法可以將字符串設(shè)置到 response 緩沖區(qū)中,隨后 Tomcat 會將 response 緩沖區(qū)中的內(nèi)容組裝成 Http 響應(yīng)返回給瀏覽器端。
關(guān)于設(shè)置中文的亂碼問題
response 緩沖區(qū)的默認(rèn)編碼是 iso8859-1,此碼表中沒有中文,可以通過 setCharacterEncoding(String charset) 設(shè)置 response 的編碼。但是這樣客戶端還是不能正常顯示文字。
因為瀏覽器的默認(rèn)編碼是本地系統(tǒng)的編碼,因為我們都是中文系統(tǒng),所以客戶端瀏覽器的默認(rèn)編碼是 GBK。
我們可以通過 response 的 setContentType(String type) 方法指定頁面解析時的編碼是UTF-8。
因為該方法含有 setCharacterEncoding 的功能,所以在實際開發(fā)中只要編寫 response.setContentType("text/html;charset=UTF-8");就可以解決頁面輸出中文亂碼問題了。
那么今天就到這里了
伙伴們再見了
我是萌新娜娜
立志做一個不翻車的老司機
學(xué)習(xí)Java的路上請多多指教
大家如果想要更深入了解java相關(guān)知識,私信我回復(fù):【Java】 即可知道你們想要知道的java相關(guān)問題
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。