關於Python文檔讀取UTF-8編碼文件問題

近來接到一個小項目,讀取目標文件中每一行url,並逐個請求url,拿到想要的數據。html

#-*- coding:utf-8 -*-
class IpUrlManager(object):
    def __init__(self):
        self.newipurls = set()
        #self.oldipurls = set()

    def Is_has_ipurl(self):
        return len(self.newipurls)!=0

    def get_ipurl(self):
        if len(self.newipurls)!=0:
            new_ipurl = self.newipurls.pop()
            #self.oldipurls.add(new_ipurl)
            return new_ipurl
        else:
            return None

    def download_ipurl(self,destpath):
        try:
            f = open(destpath,'r')
            iter_f = iter(f)
            lines = 0
            for ipurl in iter_f:
                lines = lines + 1
                self.newipurls.add((ipurl.rstrip('\r\n'))
            #log記錄讀取了多少行IP url
            #print lines
        finally:
            if f:
                f.close()    

咋一眼看code寫的沒問題,每個url 增長進newipurls set集合中。可是請求的過程當中,requests.get後,會出現以下錯誤:python

raise InvalidSchema("No connection adapters were found for '%s'" % url)web

後來發現每次都是第一行的url請求失敗。而後打印print 請求的url。也沒發現異常。而後從根源上去找,好吧,print打印newipurls set集合看看。編碼

果真,問題就在這裏。url

奇怪,爲何這個URL前面爲默認加上了\xef\xbb\xbf 這幾個字符呢?spa

 

上網看了一些資料,原來在python的file對象的readline以及readlines程序中,針對一些UTF-8編碼的文件,開頭會加入BOM來代表編碼方式。3d

何爲BOM?

所謂BOM,全稱是Byte Order Mark,它是一個Unicode字符,一般出如今文本的開頭,用來標識字節序(Big/Little Endian),除此之外還能夠標識編碼(UTF-8/16/32)。code

其實若是你們有UltraEdit tool能夠發現,在另存爲文件的時候,能夠保存爲UTF-8 和UTF-8 無BOM的文件。htm

若是將文件另存在UTF-8的格式,則文件的開頭默認會增長三個字節\xef\xbb\xbf。對象

怎麼檢測該文件是否爲UTF-8 帶BOM的呢?

import codecs
def download_ipurl(self,destpath):
    try:
        f = open(destpath,'r')
        iter_f = iter(f)
        lines = 0
        for ipurl in iter_f:
            lines = lines + 1
            if ipurl[0:3] == codecs.BOM_UTF8:    
                self.newipurls.add((ipurl.rstrip('\r\n')).lstrip('\xef\xbb\xbf'))
        #print self.newipurls
        #log記錄讀取了多少行IP url
        #print lines
    finally:
        if f:
            f.close()    

引用codecs模塊,來判斷前三個字節是否爲BOM_UTF8。若是是,則剔除\xef\xbb\xbf字節。

其實你們能夠經過其餘方式剔除BOM字節,我寫的比較粗糙。

相關文章
相關標籤/搜索