偶然發現個別特俗的HTML編碼錯亂的例子。字符集編碼設置在HTML header和response headers,charset是GB2312,啓用gzip壓縮。
通過代碼獲取原始數據流:
>>from self_defined_http_connection import *
>>response = connect(“https://www.***.com”)
>>statuscode = getcode(response)
>>statuscode
>>rawdata = response.read()
>>rawdata
可以看到是顯示的是二進制的十六進制表現編碼(representation)。現在就開始解碼。
如果直接decode解碼會怎麼樣?
出現錯誤提示:
“UnicodeDecodeError: ‘gb2312’ codec can’t decode byte 0x8b in position 1: illegal multibyte sequence”
“UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x8b in position 1: illegal multibyte sequence”
“UnicodeDecodeError: ‘gb18030’ codec can’t decode byte 0x8b in position 1: illegal multibyte sequence”
從第一幅圖片可以看到採用的是gzip壓縮編碼。所以先進行gzip解壓縮。
>>from io import BytesIO
>>buffer = BytesIO(rawdata)
>>f = gzip.GzipFile(mode=”rb”, fileobj=buffer)
>>decompressrawdata = f.read()
由於其字符集編碼設置是“GB2312”,所以先用該字符集解碼。
>>decompressrawdata.decode(“gb2312”)
結果出現“UnicodeDecodeError: ‘gb2312’ codec can’t decode byte 0x85”的錯誤:
這有點詭異:定義的字符集與表現的編碼不一致。 不管如何,進行到這裏,試試其他字符集。
>>decompressrawdata.decode(“gbk”)
竟然成功了!再試
>>decompressrawdata.decode(“gb18030”)
也成功了!(字符集編碼數量排序:GB2312 < GBK < GB18030)
試試另一個相同字符集的網站,先看看配置
獲取原始數據流並直接解碼。
>>response = connect(“http://www.***.com.cn”)
>>rawdata = response.read()
>>rawdata.decode(“GB2312”)
>>rawdata.decode(“GBK”)
結果看下圖:
解碼直接成功!
如果按照前一例子的方法試試?
錯誤提示:“raise BadGzipFile(‘Not a gzipped file (%r)’ % magic)
gzip.BadGzipFile: Not a gzipped file (b’CT’)”
(What could I say?:)(這一定是幻覺???)
筆者能想到的可靠的解釋是gzip level(待驗證)或bug。
注:測試環境Windows10 + Python3.8.*