日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gb2312 requests乱码_不要相信requests返回的text

發布時間:2025/4/5 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gb2312 requests乱码_不要相信requests返回的text 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文投稿自公眾號:猿人學python

Python的requests庫是一個非常好用的庫,這應該已經是大多寫過爬蟲的人的共識了。它的簡潔易用給我們帶來很大方便。然而,它也并不是非常完美。今天我們就說說它在處理中文編碼方面的不足。

requests的使用非常簡單,如下:

一句函數調用,就可以獲得請求結果的對象response,通過response.content 可以得到原始的二進制數據,通過response.text可以得到解碼后的文本數據,解碼是根據response.encoding進行的。然而,requests對這個encoding(編碼)的獲取是有問題的。

它獲取編碼的過程分為兩步,不幸的是每一步都有問題:

第一步:從http返回的headers里面找編碼。

這一步的代碼在源文件utils.py里面是get_encoding_from_headers(headers)函數:

最后兩行代碼,它認為headers里面的‘Content-Type’包含‘text’就是‘ISO-8859-1’編碼。這種想法是不嚴謹的。

我們用chrome瀏覽器打開最開始代碼中的那個網址,這是一個中文網頁:

http://epaper.sxrb.com/

在用Chrome的F12查看http響應的頭,如下:

這個網站給出的Content-Type不是下面的正規格式:

Content-Type: text/html; charset=UTF-8

然后,requests的get_encoding_from_headers函數就得到了ISO-8859-1的編碼,再用這個編碼去解碼中文,當然就會出現亂碼。

第二步:如果不能從響應headers得到編碼,就用chardet從二進制的content猜測

嚴格講,這步出現的編碼問題不是requests的,而是chardet的,就判requests一個失察之責吧。

在requests的源碼models.py中定義了requests.get()返回的類Response。我們再看看其中text()的定義:

響應頭找不到編碼時,self.encoding就是None。它就會通過self.apparent_encoding獲得編碼,那就再看看這個apparent_encoding是怎么來的:

很簡單,就是通過chardet檢測的。問題就出現在這個chardet上面。那我們就打破砂鍋問到底,去看看chardet的代碼。

上圖是chardet的全部源代碼。其中處理國標中文編碼的gb2312開頭的兩個文件。我們用grep再看看全部代碼中含有gb的部分:

grep -i gb *py?

以上說明,chardet對國標中文編碼返回的就是(只是)GB2312。那么問題就來了,國標不只是GB2312,還有GBK,GB18030編碼。

(1)GB 2312 標準共收錄 6763 個漢字

(2)GBK 即漢字內碼擴展規范,共收入 21886 個漢字和圖形符號,兼容GB2312

(3)GB 18030 與 GB 2312-1980 和 GBK 兼容,共收錄漢字70244個

由此可知,三種國標中文編碼的漢字個數是如下關系:

GB2312 < GBK < GB18030

如果不屬于GB2312的漢字用GB2312去編解碼會出現上面問題呢?我們來做個實驗:

例子中的“镕”字不在GB2312中,用這個編碼時就會報錯,用GBK編碼后的二進制數據再用GB2312解碼時同樣會報錯,都是因為“镕”不是GB2312里面的漢字。

這時候,我們像requests那樣把errors設置為replace再用GB2312解碼得到的文本就會有亂碼出現,“镕”字變成亂碼了。

最后我們用chardet檢驗二進制數據的編碼,得到的是GB2312,但應該是GBK或GB18030編碼。當然,chardet的這個bug已經有人在github提出issues,最早是2014年的#33, 后來有#99,#168,但是不懂中文的老外一直沒有merge到master。

問題弄明白了,那么建議是什么呢?在爬蟲中,尤其是抓取中文網頁(非英文網頁)時用cchardet檢驗response.content,而不是直接用response.text。

cchardet是uchardet的Python綁定,后者是用C++實現的字符編碼檢測庫,來自Mozilla組織,質量過硬,速度更快,值得信賴。

望學有所獲 !每天進步一點點 !

總結

以上是生活随笔為你收集整理的gb2312 requests乱码_不要相信requests返回的text的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。