做了個網路爬蟲抓取網頁,但如果網頁是gbk/gb2312編碼,則會出現亂碼問題,如下:取得文字後,直接列印,輸出結果str如下:1ó?Yè?ê???ê?D??¢í?_1ó?Yè?ê???ê?í?_1ó?Y1????±??ê?í?_1ó?Y?D1?

這個問題困擾我好長時間,baidu,google了一番也沒有找到完全可行的方法,繼續瞎折騰,最後居然搞出來了!編碼轉換來轉換去的,還是得不到解決。特意把問題總結下來,分享給大家,互相學習!(有時問題不複雜很容易解決,如果沒有找到問題的突破口的話,那麼通向解決問題的路程就很遙遠了)總之,遇到問題時,多選擇幾種方法試試,總有一種方法可以解決的。

1.改變網頁源代碼的編碼格式

[python] view plain copy

  1. #-*-coding:utf8-*-
  2. importurllib2
  3. req=urllib2.Request("http://www.baidu.com/")
  4. res=urllib2.urlopen(req)
  5. html=res.read()
  6. res.close()
  7. html=unicode(html,"gb2312").encode("utf8")#gb2312--->utf-8
  8. printhtml

2.python抓取網頁時字符集轉換問題處理方案

有時候我們採集網頁,處理完畢後將字元串保存到文件或者寫入資料庫,這時候需要制定字元串的編碼,如果採集網頁的編碼是gb2312,而我們的資料庫是utf-8的,這樣不做任何處理直接插入資料庫可能會亂碼(沒測試過,不知道資料庫會不會自動轉碼),我們需要手動將gb2312轉換成utf-8。首先我們知道,Python裏的字元默認是ascii碼,英文當然沒問題啦,碰到中文的時候立馬給跪。不知道你還記不記得,python裏列印中文漢字的時候需要在字元串前面加 u:print u"來搞基嗎?"這樣子中文才能顯示,這裡面的u的作用就是將後面的字元串轉換為unicode碼,這樣中文才能得到正確的顯示。這裡與之相關的有一個unicode()函數,用法如下str="來搞基"str=unicode(str,"utf-8")print str與u的區別是,這裡用unicode將str轉換為unicode編碼,需要正確指定第二個參數,這裡的utf-8是我test.py腳本自身的文件字符集,默認的可能是ansi。unicode這是一個關鍵,下面繼續我們開始抓取百度首頁,注意,遊客訪問百度首頁,查看網頁源代碼,它的charset=gb2312。import urllib2def main(): f=urllib2.urlopen("http://www.baidu.com") str=f.read() str=unicode(str,"gb2312") fp=open("baidu.html","w") fp.write(str.encode("utf-8")) fp.close()if __name__ == "__main__" : main()解釋:我們首先用urllib2.urlopen()方法將百度首頁抓取到,f是句柄 ,用str=f.read()將所有源代碼讀入str中搞清楚,str裡面就是我們抓取的html源代碼,由於網頁默認的字符集是gb2312,所以如果我們直接保存到文件中,文件編碼將是ansi。對於大部分人來說,其實這就足夠了,但是有時候我就想把gb2312轉換成utf-8的該怎麼辦呢?首先: str=unicode(str,"gb2312") #這裡的gb2312就是str的實際字符集,我們現在將其轉換成unicode然後: str=str.encode("utf-8") #將unicode的字元串重新編碼成utf-8最後: 將str寫入到文件中,打開文件看一下編碼屬性,發現是utf-8的了,把<meta charset="gb2312"改成<meta charset="utf-8" ,就是一個utf-8的網頁了。做了這麼多其實就完成了一個gb2312->utf-8的轉碼。總結: 我們回顧一下,如果需要將字元串按照指定的字符集保存,有以下幾個步驟: 1:用unicode(str,"原來的編碼")將str解碼成unicode字元串 2:將unicode字元串str 使用 str.encode("指定的字符集") 轉換成你指定的字符集 3:將str保存文件,或者寫入資料庫等操作,當然,編碼你已經指定了,不是嗎?

3.用lxml解析html

用lxml.etree做網路爬蟲抓取網頁,但如果網頁是gbk/gb2312編碼,則會出現亂碼問題,如下:取得文字後,直接列印,輸出結果v如下:1ó?Yè?ê???ê?D??¢í?_1ó?Yè?ê???ê?í?_1ó?Y1????±??ê?í?_1ó?Y?D1?這個v的類型又是<type"lxml.etree._ElementUnicodeResult">該如何解決啊?可以修改源代碼的編碼格式:response.encoding="utf-8"page=etree.HTML(response.content)nodes_title=page.xpath("//title//text()")這樣列印出來的nodes_title[0]就為正常的中文顯示了。特別注意的是,response.text很容易出現編碼問題的,以後用response.content。
推薦閱讀:

查看原文 >>
相關文章