requests和BeautifulSoup中文編碼轉換心得

最近在自學用python進行網(wǎng)頁數(shù)據(jù)抓取坦辟,結果被中文亂碼的問題折騰了好久刊侯。網(wǎng)上google了各種解決方案都無法解決我遇到的問題,索性自己深入的研究了下锉走,終于把這難題給解決了滨彻。在此梳理下整個分析過程。

網(wǎng)站&開發(fā)工具

遇到的問題

一開始我的代碼是這樣寫的:
<pre><code>response = requests.get('http://www.jjwxc.net/fenzhan/noyq/')
soup = bs4.BeautifulSoup(response.text, "html.parser")
print soup.title
</code></pre>
執(zhí)行后返回的結果中文部分都變成了亂碼挪蹭。很顯然亭饵,是中文編碼在轉換過程中出現(xiàn)了問題。

分析

查看jjwxc.net的源碼梁厉,可以得知該網(wǎng)站的中文編碼是gb18030
<pre><code><meta http-equiv="Content-Type" content="text/html; charset=gb18030" /></code></pre>
查閱requestes以及BeautifulSoup的相關文檔辜羊,可知requests會自動將從服務器端獲取到的內容自動轉換成unicode, 而beauifulsoup也會將獲取到內容自動解碼成unicode。既然response.text已經是unicode形式词顾,那么再傳遞給beautifulsoup八秃,是unicode->unicode之間的直接傳遞,應該不存在編碼轉換錯誤的情況肉盹,那么為什么最后print出來的會是亂碼呢昔驱?

于是進一步查閱requests和bs4的官方文檔,發(fā)現(xiàn)了這樣兩段描述:

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骤肛。大多數(shù)時候猜測出來的編碼都是正確的,但也有猜錯的情況窍蓝,如果猜錯了可以指定原文的編碼腋颠。
OK,那讓我們看一下requests和beautifulsoup是否猜對了原文編碼吓笙。
<pre><code>response = requests.get('http://www.jjwxc.net/fenzhan/noyq/')
print response.encoding
soup = bs4.BeautifulSoup(response.text, "html.parser")
print soup.original_encoding
<br />運行結果:
ISO-8859-1
None</code></pre>
可以發(fā)現(xiàn)是由于requests這里對原文的編碼猜錯了導致亂碼的出現(xiàn)淑玫,所以我們需要在response.text傳給beautifulsoup之前指定編碼:
<pre><code>response = requests.get('http://www.jjwxc.net/fenzhan/noyq/')
response.encoding = 'gb18030'
soup = bs4.BeautifulSoup(response.text, "html.parser")
print soup.title</code></pre>
但是運行后發(fā)現(xiàn)輸出的結果還是亂碼。
繼續(xù)查閱上述語句的相關官方文檔观蓄,發(fā)現(xiàn)beautifulsoup對于輸出內容的編碼方式有這樣一段介紹:

BS_encoding.png

意即beautifulsoup在輸出文本時默認以UTF-8的方式編碼混移,無論原文是否以它進行編碼的。如果你不希望以UTF-8的方式編碼侮穿,可以用prettify()或則encode()方式來指定編碼歌径。
所以我們將代碼更改下:
<pre><code>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')
<br />運行結果:
<title>
非言情小說網(wǎng)|同人小說|古代純愛小說|現(xiàn)代純愛小說|同人純愛小說|動漫同人小說【晉江文學城】bl小說站
</title>
<title>非言情小說網(wǎng)|同人小說|古代純愛小說|現(xiàn)代純愛小說|同人純愛小說|動漫同人小說【晉江文學城】bl小說站</title></code></pre>
可以看到兩種指定方式都可以獲得無亂碼的中文內容。
這里再介紹下prettify()的功能亲茅,prettify()除了可以制定輸出的編碼方式回铛,它的最主要功能是對beautifulsoup的k語法分析樹重新排版狗准,使輸出的內容整潔易讀。這里用一段代碼說明:

BS_prettify.png

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仆抵,隨后出現(xiàn)的幾起案子跟继,更是在濱河造成了極大的恐慌,老刑警劉巖镣丑,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舔糖,死亡現(xiàn)場離奇詭異,居然都是意外死亡传轰,警方通過查閱死者的電腦和手機剩盒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門谷婆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慨蛙,“玉大人,你說我怎么就攤上這事纪挎∑谄叮” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵异袄,是天一觀的道長通砍。 經常有香客問我,道長烤蜕,這世上最難降的妖魔是什么封孙? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮讽营,結果婚禮上虎忌,老公的妹妹穿的比我還像新娘。我一直安慰自己橱鹏,他們只是感情好膜蠢,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布堪藐。 她就那樣靜靜地躺著,像睡著了一般挑围。 火紅的嫁衣襯著肌膚如雪礁竞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天杉辙,我揣著相機與錄音模捂,去河邊找鬼。 笑死蜘矢,一個胖子當著我的面吹牛枫绅,可吹牛的內容都是我干的。 我是一名探鬼主播硼端,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼并淋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了珍昨?” 一聲冷哼從身側響起县耽,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镣典,沒想到半個月后兔毙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡兄春,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年澎剥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赶舆。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡哑姚,死狀恐怖,靈堂內的尸體忽然破棺而出芜茵,到底是詐尸還是另有隱情叙量,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布九串,位于F島的核電站绞佩,受9級特大地震影響,放射性物質發(fā)生泄漏猪钮。R本人自食惡果不足惜品山,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烤低。 院中可真熱鬧肘交,春花似錦、人聲如沸拂玻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至魄懂,卻和暖如春沿侈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背市栗。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工缀拭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人填帽。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓蛛淋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親篡腌。 傳聞我的和親對象是個殘疾皇子褐荷,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內容