python3抓取網頁解碼問題!

Pop_Rain發表於2017-06-12

在網頁抓取時,經常遇到網頁編碼問題,以下是自己總結的乾貨

一、幾篇文章

字串編碼與Python 3編碼:http://blog.csdn.net/wangtaoking1/article/details/51326754  

python3 和 python2 的編碼與解碼差別很大嗎?:https://www.v2ex.com/t/343040

Python 3的bytes/str之別 codecs模組:http://blog.csdn.net/iamaiearner/article/details/9138865

自學Python八 爬蟲大坑之網頁亂碼:http://www.cnblogs.com/jixin/p/5141701.html

二、個人總結

Begin with Python 3, all string is unicode object.-->也就是說所有str字串已經是Unicode(utf8)了,不用再decode

python3中就是兩個東西:bytes與str(即二進位制與字串(其實可以理解就是utf8、unicode))

最終轉成UTF8輸出是毋庸置疑的。 
抓的如果是中文頁面的話,用GB18030來decode是比較正統的方法,gb2312是一個誤區,其實我們的頁面中使用的字元編碼已經早就超出2312的那些了。 
明明是中文頁面抓回來卻沒法用18030來decode的話,一般是因為頁面中混雜了非法字元的原因,可以用ignore忽略掉非法字元。

三、自己遇到的坑

有些網頁抓取並解碼後,英文正確顯示,中文還是出現亂碼,怎麼解碼都弄不好,以下解決方案完美解決了我的問題。

unicode中的‘\xa0’字元在轉換成gbk編碼時會出現問題,gbk無法轉換'\xa0'字元。所以,在轉換的時候必需進行一些前置動作: 

sting.replace('\xa0', ' ')  #將'\xa0'替換成' '空格。

這個坑解決問題的示例:

import urllib.request

url = "http://www.ebay.com/sch/TShirts-/15687/i.html?Style=Basic%2520Tee&_dcat=15687&Color=Black&_pgn=1"
req = urllib.request.Request(url)
html_open = urllib.request.urlopen(req)
html_data = html_open.read()
html = str(html_data.decode("utf8"))  #先read再decode

html = html.replace("\xa0"," ")
html = html.replace("\xa9"," ")
html.encode("utf8")

file_name = "f:/test/1.txt"
file_open = open(file_name, "a") #將網頁原始碼寫入1.txt中
file_open.write(html)
file_open.close()

這個方法在實際問題中解決了問題:

#本程式碼解決解碼後亂碼或者其他部分英文都正確但網頁中文仍然亂碼的問題
import re
import urllib.request

def getPage(url):     
    request = urllib.request.Request(url)  
    response = urllib.request.urlopen(request)
    data = response.read()
    return data.decode("utf8")  #這裡建議網頁抓取下來都進行decode原網頁的編碼格式,utf8也不例外。這裡的例項網頁編碼格式為utf8
       
urls = open("f:/4.txt") #從4.txt中提取urls,一共兩個url,都為utf8編碼方式
for url in urls:
    url = url.replace("\n","")  

    result=getPage(url)
    result = str(result)
    
    result = result.replace("\xa0"," ") #這裡是關鍵中重點,就是因為'\xa0'是個空格符的問題造成中文出現亂碼
    result.encode("gbk") #上行程式碼將空格符去掉後,再encode成支援中文的編碼就可以看到中文了,當然這行程式碼可以省略,因為預設是可以顯示的
    
    rule = re.compile("http://(.*?)/") #以下程式碼:將原始碼寫入檔案中,這裡把檔名http等前字尾去掉
    new_url = re.findall(rule, url) 
    save_name = "f:/savepages/" + new_url[0] + ".txt"
    file_open = open(save_name, "a")
    file_open.write(result)
    file_open.close()

相關文章