python 解決抓取網頁中的中文顯示亂碼問題


關於爬蟲亂碼有很多各式各樣的問題,這里不僅是中文亂碼,編碼轉換、還包括一些如日文、韓文 、俄文、藏文之類的亂碼處理,因為解決方式是一致的,故在此統一說明。

網絡爬蟲出現亂碼的原因

源網頁編碼和爬取下來后的編碼格式不一致。
如源網頁為gbk編碼的字節流,而我們抓取下后程序直接使用utf-8進行編碼並輸出到存儲文件中,這必然會引起亂碼 即當源網頁編碼和抓取下來后程序直接使用處理編碼一致時,則不會出現亂碼; 此時再進行統一的字符編碼也就不會出現亂碼了

注意區分

  • 源網編碼A、
  • 程序直接使用的編碼B、
  • 統一轉換字符的編碼C。

亂碼的解決方法

確定源網頁的編碼A,編碼A往往在網頁中的三個位置

1.http header的Content-Type
獲取服務器 header 的站點可以通過它來告知瀏覽器一些頁面內容的相關信息。 Content-Type 這一條目的寫法就是 "text/html; charset=utf-8"。 

2.meta charset

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  

3.網頁頭中Document定義

<script type="text/javascript"> 
if(document.charset){ 
 alert(document.charset+"!!!!"); 
 document.charset = 'GBK'; 
 alert(document.charset); 
} 
else if(document.characterSet){ 
 alert(document.characterSet+"????"); 
 document.characterSet = 'GBK'; 
 alert(document.characterSet); 
} 

在獲取源網頁編碼時,依次判斷下這三部分數據即可,從前往后,優先級亦是如此。
以上三者中均沒有編碼信息 一般采用chardet等第三方網頁編碼智能識別工具來做

安裝: pip install chardet

官方網站: http://chardet.readthedocs.io/en/latest/usage.html

Python chardet 字符編碼判斷

使用 chardet 可以很方便的實現字符串/文件的編碼檢測 雖然HTML頁面有charset標簽,但是有些時候是不對的。那么chardet就能幫我們大忙了。
chardet實例

import urllib 
rawdata = urllib.urlopen('http://www.baidu.com/').read() 
import chardet 
chardet.detect(rawdata) 
{'confidence': 0.99, 'encoding': 'GB2312'} 

chardet可以直接用detect函數來檢測所給字符的編碼。函數返回值為字典,有2個元素,一個是檢測的可信度,另外一個就是檢測到的編碼。

在開發自用爬蟲過程中如何處理漢字編碼?
下面所說的都是針對python2.7,如果不加處理,采集到的都是亂碼,解決的方法是將html處理成統一的utf-8編碼 遇到windows-1252編碼,屬於chardet編碼識別訓練未完成

import chardet 
a='abc'
type(a) 
str
chardet.detect(a) 
{'confidence': 1.0, 'encoding': 'ascii'} 
  
  
a =""
chardet.detect(a) 
{'confidence': 0.73, 'encoding': 'windows-1252'} 
a.decode('windows-1252') 
u'\xe6\u02c6\u2018'
chardet.detect(a.decode('windows-1252').encode('utf-8')) 
type(a.decode('windows-1252')) 
unicode
type(a.decode('windows-1252').encode('utf-8')) 
str
chardet.detect(a.decode('windows-1252').encode('utf-8')) 
{'confidence': 0.87625, 'encoding': 'utf-8'} 
  
  
a ="我是中國人"
type(a) 
str
{'confidence': 0.9690625, 'encoding': 'utf-8'} 
chardet.detect(a) 
# -*- coding:utf-8 -*- 
import chardet 
import urllib2 
#抓取網頁html 
html = urllib2.urlopen('http://www.baidu.com/').read() 
print html 
mychar=chardet.detect(html) 
print mychar 
bianma=mychar['encoding'] 
if bianma == 'utf-8' or bianma == 'UTF-8': 
 html=html.decode('utf-8','ignore').encode('utf-8') 
else: 
 html =html.decode('gb2312','ignore').encode('utf-8') 
print html 
print chardet.detect(html) 

python代碼文件的編碼
py文件默認是ASCII編碼,中文在顯示時會做一個ASCII到系統默認編碼的轉換,這時就會出錯:SyntaxError: Non-ASCII character。需要在代碼文件的第一行添加編碼指示:

# -*- coding:utf-8 -*- 
  
print '中文'

像上面那樣直接輸入的字符串是按照代碼文件的編碼'utf-8'來處理的
如果用unicode編碼,以下方式:

s1 = u'中文' #u表示用unicode編碼方式儲存信息

decode是任何字符串具有的方法,將字符串轉換成unicode格式,參數指示源字符串的編碼格式。
encode也是任何字符串具有的方法,將字符串轉換成參數指定的格式。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM