首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Python 抓取 GB2312 編碼網頁亂碼解決:urllib3 + 顯式解碼

     編輯:程式設計綜合問答

問題現場

  • 目標頁面:https://esf.nanjing.fang.com/
  • 瀏覽器顯示 charset=gb2312。
  • chardet 檢測失敗:{'confidence': 0.0, 'encoding': None}。
  • page.decode('gb2312', 'ignore') 後打印仍亂碼。

根因分析

  • requests/urllib 默認不自動處理 GB2312,**需顯式指定編碼解碼**。
  • decode('gb2312', 'ignore') 會**靜默丟棄非法字節**,導致內容殘缺。應用 'replace' 或**不忽略錯誤**以暴露問題。
  • 部分網頁**聲明 GB2312 實際混雜 GBK/UTF-8**,需嘗試多編碼。

推薦方案:urllib3 + 顯式解碼(親測可用)

import urllib3

http = urllib3.PoolManager()
resp = http.request('GET', 'https://esf.nanjing.fang.com/')

# 關鍵:直接按 GB2312 解碼,錯誤用 replace 替換為  而非忽略
html = resp.data.decode('gb2312', errors='replace')
print(html[:2000])  # 正常輸出中文

進階:自動嘗試多編碼兜底

def decode_smart(data: bytes) -> str:
    for encoding in ('gb2312', 'gbk', 'gb18030', 'utf-8'):
        try:
            return data.decode(encoding)
        except UnicodeDecodeError:
            continue
    # 最後兜底:replace 非法字節
    return data.decode('gb2312', errors='replace')

html = decode_smart(resp.data)

requests 版本(同理)

import requests
resp = requests.get('https://esf.nanjing.fang.com/')
resp.encoding = 'gb2312'  # 強制指定,覆蓋自動檢測
html = resp.text  # 內部調用 resp.content.decode(resp.encoding)
print(html[:2000])

常見坑點對比

寫法結果原因
resp.text (無干預)亂碼requests 誤判編碼為 ISO-8859-1
resp.content.decode('gb2312', 'ignore')殘缺/亂碼非法字節被靜默丟棄,結構破壞
resp.content.decode('gb2312', 'replace')**正常(含 佔位符)**非法字節替換為替換字符,結構完整
resp.encoding = 'gb2312'; resp.text正常強制指定編碼,requests 內部正確解碼

調試技巧:查看原始字節

print(resp.data[:100])  # b'\xc4\xe3\xba\xc3...' 典型 GB2312/GBK 雙字節特徵
# 若見大量 \xe4\xb8\xad 等三字節序列 → 實為 UTF-8

總結

  1. **不信任自動檢測**,針對中文老站**強制指定 GB2312/GBK/GB18030**。
  2. 解碼錯誤策略用 errors='replace',**不可用 'ignore'**。
  3. urllib3 或 requests 均可,核心是 bytes.decode(encoding, errors='replace')。

一行 resp.encoding = 'gb2312' 或 .decode('gb2312', 'replace'),徹底告別中文網頁亂碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved