Requests 亂碼

當使用Requests請求網頁時,出現下面圖片中的一些亂碼,我就一臉蒙逼。html

程序是這樣的。python

def getLinks(articleUrl):
    headers = {
        "Uset-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.108 Safari/537.36 2345Explorer/8.1.0.14126"
        }
    wb_data = requests.get(articleUrl,headers=headers)
    bsObj = BeautifulSoup(wb_data.text,"lxml")
    return bsObj

程序的中出現的亂碼圖片是這樣的。app

怎麼解決呢?好在有google大神,讓我找到了一些前輩寫的博客,拿去看吧,^_^。ui

http://blog.chinaunix.net/uid-13869856-id-5747417.htmlgoogle

http://blog.csdn.net/a491057947/article/details/47292923#t1編碼

還有官網連接。兩個地方都有講到。(偷偷告訴你有chinese版本的,本身去找吧)spa

http://docs.python-requests.org/en/latest/user/quickstart/#response-content.net

http://docs.python-requests.org/en/master/user/advanced/#complianceunix

英文很差,咱們來看看中文版的說的是什麼,見下圖。code

好了,資料看完了,總結一下吧。

解決思路:

1.見到有亂碼,不用怕,首先咱們來看看編碼方式是什麼?怎麼看?把編碼方式打印出來看看。

def getLinks(articleUrl):
    headers = {
        "Uset-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.108 Safari/537.36 2345Explorer/8.1.0.14126"
        }
    wb_data = requests.get(articleUrl,headers=headers)
    bsObj = BeautifulSoup(wb_data.text,"lxml")
    hrefs = bsObj.find("div",{"class":"booklist clearfix"})
    print(wb_data.headers['content-type'])     print(wb_data.encoding) # response的內容編碼
    print(wb_data.apparent_encoding) #response headers 裏設置的編碼
    print(requests.utils.get_encodings_from_content(wb_data.text)) #response返回的html header標籤裏設置的編碼
    return bsObj

返回的是這些個鬼東西。

text/html
ISO-8859-1  # response的內容編碼
UTF-8-SIG   #response headers 裏設置的編碼
['utf-8']   #response返回的html header標籤裏設置的編碼

這下知道爲啥亂碼了,原來是response的內容編碼和response headers 裏設置的編碼不同啊。

2.怎麼辦呢?不同,那咱們就改爲同樣的。改變response的內容編碼格式。

有兩種方法:

(1)使用.encoding屬性改變response的內容編碼,在代碼里加上下面一行代碼。

wb_data.encoding = 'utf-8' #手動指定編碼方式
def getLinks(articleUrl):
    headers = {
        "Uset-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.108 Safari/537.36 2345Explorer/8.1.0.14126"
        }
    wb_data = requests.get(articleUrl,headers=headers)
    wb_data.encoding = 'utf-8' #手動指定編碼方式
    bsObj = BeautifulSoup(wb_data.text,"lxml")
    return bsObj

(2)使用原始的Response.content

bsObj = BeautifulSoup(wb_data.text,"lxml")
#將wb_data.text改成wb_data.content
bsObj = BeautifulSoup(wb_data.content,"lxml") 

3.從前面連接裏就能夠看到,一位前輩寫出了下面代碼。解決這類問題,一勞永逸的方法。
我給應用到個人代碼裏,看看可行不?^_^。

原理是這樣的,當response內容的編碼是'ISO-8859-1',首先查找返回的Html的header標籤裏設置的編碼;若是此編碼不存在,查看response header設置的編碼

def getLinks(articleUrl):
    headers = {
        "Uset-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.108 Safari/537.36 2345Explorer/8.1.0.14126"
        }
    wb_data = requests.get(articleUrl,headers=headers)

    if wb_data.encoding == 'ISO-8859-1':
        encodings = requests.utils.get_encodings_from_content(wb_data.text)
        if encodings:
            encoding = encodings[0]
        else:
            encoding = wb_data.apparent_encoding
    encode_content = wb_data.content.decode(encoding,'replace').encode('utf-8','replace')
    
    bsObj = BeautifulSoup(encode_content,"lxml")    
    return bsObj

好了,這下就能解決這個問題了。哎,這個小鬼挺能折騰的。

相關文章
相關標籤/搜索