精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Python異常UnicodeEncodeError: ''gbk'' codec can''t encode character ''

問題描述

在寫爬蟲爬取網(wǎng)頁信息時,發(fā)生了以下錯誤:

UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'

意思大致是Unicode編碼錯誤,gbk編解碼器不能編碼\ufffd字符。

爬蟲程序爬取的是課程信息,包含中文。使用requests庫訪問網(wǎng)頁,使用BeautifulSoup庫解析網(wǎng)頁,用get_text()方法獲取標簽內(nèi)的文本信息。

python版本為3.5,在cmd控制臺中運行python腳本。

代碼大致如下:

import requestsfrom bs4 import BeautifulSoupr = requests.get(url,cookies=cookies,headers=headers)soup = BeautifulSoup(r.text,"lxml")lesson_data_list = soup.find_all(id="xjs_table")[0].find_all("tr")[1:]for lesson_data in lesson_data_list:    td = lesson_data.find_all("td")    name = td[0].get_text()    credit = td[1].get_text()    teacher = td[2].get_text()    time = td[5].get_text()    total = td[11].get_text()    print(name,credit,teacher,time,total)

錯誤原因

  1. cmd默認編碼是GBK,字符\ufffd不能編碼為GBK。

  2. 查閱Unicode編碼表或者使用Python自帶的集成開發(fā)環(huán)境IDLE(可以輸出),可知\ufffd其實是?字符。

  3. Python3的字符串以Unicode編碼,也就是解析網(wǎng)頁時,需要將字符串從網(wǎng)頁原來的編碼格式轉(zhuǎn)化為Unicode編碼格式。

  4. 出現(xiàn)?字符的原因:從某編碼向Unicode編碼轉(zhuǎn)化時,如果沒有對應的字符,得到的將是Unicode的代碼\ufffd,也就是?字符。

  5. 在寫爬蟲解析網(wǎng)頁時出現(xiàn)?字符,往往是因為沒有注意原網(wǎng)頁的編碼格式,全按照默認編碼UTF-8轉(zhuǎn)化,導致有的字符轉(zhuǎn)化失敗。

在本問題中,是由于在網(wǎng)頁上包含這樣的中文,由于是生僻字沒有相應的UTF-8編碼,所以以默認UTF-8編碼格式轉(zhuǎn)化為Unicode時,沒有對應的字符,轉(zhuǎn)化出錯,得到\ufffd。又因為在cmd運行,因此報錯UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'

解決辦法

寫爬蟲解析網(wǎng)頁時,要注意原網(wǎng)頁的編碼格式和壓縮格式(Gzip等)

查看原網(wǎng)頁的編碼格式,為’gb2312’。


所以要按照gb2312編碼向Unicode編碼轉(zhuǎn)化。

r = requests.get(url,cookies=cookies,headers=headers)# 指定網(wǎng)頁的編碼格式r.encoding = 'gbk'# r.encoding = 'gb2312' 仍然會報錯soup = BeautifulSoup(r.text,"lxml")

最后再次在cmd運行代碼,這樣的中文也成功顯示。

注意:本解決辦法適用于與本問題描述完全相同的問題,因為可能是相同的錯誤原因?qū)е碌摹F渌鼒箦e信息可能與本問題的情況不同,比如報錯的為‘gbk’ codec can’t encode character ‘\xa0’爬蟲在寫入文件時報錯

以下是問題的逐步分析解決過程。

解決過程

cmd顯示編碼是GBK,而有些Unicode字符不能編碼成GBK

對于Unicode字符,需要print出來的話,由于本地系統(tǒng)是Windows中的cmd,默認codepage是CP936,即GBK的編碼,所以python解釋器需要先將上述的Unicode字符編碼為GBK,然后再在cmd中顯示出來。但是由于該Unicode字符串中包含一些GBK中無法顯示的字符,導致此時提示'gbk' codec can’t encode的錯誤的。

分析:這個解釋確實符合報錯信息'gbk' codec can't encode character '\ufffd'的意思。

驗證:編寫python代碼

print('\ufffd')

在cmd下運行,出現(xiàn)相同的報錯信息'gbk' codec can't encode character '\ufffd'

解決辦法1:改變標準輸出的默認編碼

在程序的開始加入以下代碼

import sysimport iosys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') 

由于我輸出的包含中文,所以使encoding='gb18030',這段代碼的作用就是把標準輸出的默認編碼修改為gb18030,也就是與cmd顯示編碼GBK相同。

效果:運行原來的爬蟲代碼后,沒有了報錯,但原先報錯的輸出位置顯示為??,中文仍沒有正確顯示。



而且還有不能即時輸出的問題,類似于python爬蟲中文輸出問題以及不即時輸出問題

解決辦法2:輸出時忽略無法編碼的字符

在對Unicode字符編碼時,添加ignore參數(shù),可以忽略無法編碼的字符

print 你的字符串.encode(“GBK“, ‘ignore’).decode

這句代碼的作用為,把字符串以GBK編碼,并忽略無法編碼的字符,再以GBK解碼,再輸出。

效果:在解決辦法1的效果基礎上,??不再顯示,但中文仍沒有正確顯示。



總結:由于\ufffd本身就沒有對應的Unicode編碼,所以要在cmd中不報錯輸出,只能把輸出編碼改為GBK或者在輸出時忽略無法編碼的字符,這樣就算可以不報錯輸出,也不能正確顯示\ufffd字符。

使用Python自帶的集成開發(fā)環(huán)境IDLE

cmd的顯示編碼是GBK,要想正確顯示\ufffd字符,就要使用支持多種輸出編碼的運行環(huán)境。Python自帶的集成開發(fā)環(huán)境IDLE就對GBK、UTF-8、Unicode都支持。其實,Pycharm、jupyter notebook、sublimeREPL配置的python運行環(huán)境也支持多種輸出編碼。

IDLE打開方法:在python的安裝目錄下,打開lib/idlelib/idle.bat,就進入了IDLE環(huán)境

運行代碼

print('\ufffd')

輸出為: ?


看到?這個結果,開始以為仍沒有正確顯示。但查詢Unicode字符表,發(fā)現(xiàn)?字符的Unicode的值正是fffd。說明\ufffd字符已經(jīng)正確顯示了。

進一步分析

以上分析的原因和解決辦法都是從最后顯示輸出的角度去考慮的,雖然一些方法不再報錯,但仍然顯示不正確,并沒有真正解決。然后在IDLE中正確顯示了字符,證明了\ufffd就是?字符。

從以上解決辦法可以進一步驗證和推測一些問題:

問題

  1. 本來應該顯示的漢字是什么

  2. ?是從哪來的

推測

對照原網(wǎng)頁,發(fā)現(xiàn)是字沒有正確顯示,而變成了\fffd?字符。這說明從一開始解析網(wǎng)頁,就被解析成了?字符。

驗證

如果從報錯信息找問題,報錯原因是部分Unicode字符不能正確轉(zhuǎn)碼成GBK,所以無法顯示。根據(jù)推測,原網(wǎng)頁上的字沒有正確顯示,而運行以下代碼:

str = '珺玥'str = str.encode('unicode_escape')print(str)# 輸出 b'\\u73fa\\u73a5'

可知的Unicode分別為73fa73a5。而不是fffd

經(jīng)驗證,print('\u73a5')是可以輸出的字的。這說明并不是的Unicode轉(zhuǎn)碼為gbk失敗,而是解析得到的Unicode都不正確,變成了\ufffd?字符。

使用爬蟲 ?作為關鍵字搜索,就找到了出現(xiàn)?字符的原因:

從某編碼向Unicode編碼轉(zhuǎn)化時,如果沒有對應的字符,得到的將是Unicode的代碼“\uffffd”,也就是?這個字符。這個是你的爬蟲根本不識別原網(wǎng)頁的編碼格式(ASCII或者GB2312等)和壓縮格式(Gzip等),全都無腦轉(zhuǎn)成UTF-8字符串導致的,出現(xiàn)這個字符說明轉(zhuǎn)換失敗,數(shù)據(jù)已經(jīng)丟失了,這個字符本身并沒什么實際意義。

出自鏈接:在處理一些爬下來的網(wǎng)頁時,經(jīng)常發(fā)現(xiàn)會存在?這個字符

最終解決

在進一步分析后,重新檢查解析過程,顯然是編碼問題。

最后發(fā)現(xiàn)確實是因為沒有注意到網(wǎng)頁編碼問題,網(wǎng)頁編碼是gb2312,而用requests請求的網(wǎng)頁,如果不聲明encoding值,默認是用UTF-8解析的。UTF-8編碼支持大部分中文字,但不支持這樣的生僻字,這樣轉(zhuǎn)成UTF-8就轉(zhuǎn)化失敗。


原網(wǎng)頁的編碼格式為’gb2312’

所以要按照gb2312編碼向Unicode編碼轉(zhuǎn)化:

r = requests.get(url,cookies=cookies,headers=headers)# 指定網(wǎng)頁的編碼格式r.encoding = 'gbk'# r.encoding = 'gb2312' 仍然會報錯soup = BeautifulSoup(r.text,"lxml")

最后再次在cmd運行代碼,這樣的中文也成功顯示。

最終總結,是由于在網(wǎng)頁上包含這樣的中文,由于是生僻字沒有相應的UTF-8編碼,所以以默認UTF-8編碼格式轉(zhuǎn)化為Unicode時,沒有對應的字符,轉(zhuǎn)化出錯,得到\ufffd。又因為在cmd運行,因此報錯UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JSP中文亂碼問題解決方法詳解
[Python]MySQL中文字符與Python中文字符
JAVA中文字符編碼問題詳解 控制臺輸出,字符編碼格式轉(zhuǎn)換
小結Python的中文處理
Python 字符編碼 轉(zhuǎn)換
從漢化到國際化
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服

主站蜘蛛池模板: 德钦县| 佳木斯市| 六盘水市| 慈利县| 榆中县| 秭归县| 同德县| 岱山县| 西宁市| 方正县| 武陟县| 二手房| 阿城市| 牡丹江市| 容城县| 项城市| 仙桃市| 布拖县| 当雄县| 建始县| 通化县| 阜新市| 营口市| 东乡族自治县| 宁夏| 吴江市| 铜山县| 堆龙德庆县| 柳江县| 洛宁县| 苍南县| 平乡县| 彰化市| 云龙县| 成都市| 武城县| 阜宁县| 阳高县| 疏勒县| 六盘水市| 铁岭市|