1. 程式人生 > >python BeautifulSoup亂碼問題

python BeautifulSoup亂碼問題

用爬蟲爬取天氣資料,需要先獲得原網站上城市中文名稱與漢語拼音的對應關係。
在編寫如下程式碼進行處理的時候,出現中文亂碼。
在這裡插入圖片描述

查了很多blog發現方法並不好使。除了這位大神。。。。。
這位出現問題就去閱讀文件的大神。。。。

https://www.jianshu.com/p/69401b84419e

查閱requests和bs4的官方文件,發現了這樣兩段描述:

When you make a request, Requests makes educated guesses about the encoding of the response based on the HTTP headers. The text encoding guessed by Requests is used when you access r.text. You can find out what encoding Requests is using, and change it, using the r.encoding property.

Beautiful Soup uses a sub-library called Unicode, Dammit to detect a document’s encoding and convert it to Unicode. The autodetected encoding is available as the .original_encoding attribute of the BeautifulSoup object.Unicode, Dammit guesses correctly most of the time, but sometimes it makes mistakes. Sometimes it guesses correctly, but only after a byte-by-byte search of the document that takes a very long time. If you happen to know a document’s encoding ahead of time, you can avoid mistakes and delays by passing it to the BeautifulSoup constructor as from_encoding.

大意是requests和beautifulsoup都會自行猜測原文的編碼方式,然後用猜測出來的編碼方式進行解碼轉換成unicode。大多數時候猜測出來的編碼都是正確的,但也有猜錯的情況,如果猜錯了可以指定原文的編碼。
OK,那讓我們看一下requests和beautifulsoup是否猜對了原文編碼。

response = requests.get('http://www.jjwxc.net/fenzhan/noyq/')
print response.encoding
soup = bs4.BeautifulSoup(response.text, "html.parser")
print soup.original_encoding

執行結果: ISO-8859-1 None

可以發現是由於requests這裡對原文的編碼猜錯了導致亂碼的出現,所以我們需要在response.text傳給beautifulsoup之前指定編碼

response = requests.get('http://www.jjwxc.net/fenzhan/noyq/')

*response.encoding = 'gb18030'

soup = bs4.BeautifulSoup(response.text, "html.parser")
print soup.title

但是執行後發現輸出的結果還是亂碼。
繼續查閱上述語句的相關官方文件,發現beautifulsoup對於輸出內容的編碼方式有這樣一段介紹:
在這裡插入圖片描述

意即beautifulsoup在輸出文字時預設以UTF-8的方式編碼,無論原文是否以它進行編碼的。如果你不希望以UTF-8的方式編碼,可以用prettify()或則==encode()==方式來指定編碼。
所以我們將程式碼更改下:

response = requests.get('http://www.jjwxc.net/fenzhan/noyq/')
response.encoding = 'gb18030'
soup = bs4.BeautifulSoup(response.text, "html.parser")
print soup.title.prettify('gb18030')
print soup.title.encode('gb18030')

可以看到兩種指定方式都可以獲得無亂碼的中文內容。
這裡再介紹下prettify()的功能,prettify()除了可以制定輸出的編碼方式,它的最主要功能是對beautifulsoup的k語法分析樹重新排版,使輸出的內容整潔易讀。

至此,中文亂碼的問題解決了。在查詢解決方案的過程中,我另外查了下unicode、byte、以及編碼和解碼方面的知識點。這一塊的東西解釋起來一時半會兒說不完,而且有些細節的地方我也沒完全搞懂,暫時就不賣弄了。對這塊內容感興趣的可以先看下下面這兩位大牛的文章,寫得非常通俗易懂:

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets
字元編碼筆記:ASCII,Unicode和UTF-8