免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Python異常UnicodeEncodeError: ''gbk'' codec can''t encode character ''

問(wèn)題描述

在寫(xiě)爬蟲(chóng)爬取網(wǎng)頁(yè)信息時(shí),發(fā)生了以下錯(cuò)誤:

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

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

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

python版本為3.5,在cmd控制臺(tái)中運(yùn)行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)

錯(cuò)誤原因

  1. cmd默認(rèn)編碼是GBK,字符\ufffd不能編碼為GBK。

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

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

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

  5. 在寫(xiě)爬蟲(chóng)解析網(wǎng)頁(yè)時(shí)出現(xiàn)?字符,往往是因?yàn)闆](méi)有注意原網(wǎng)頁(yè)的編碼格式,全按照默認(rèn)編碼UTF-8轉(zhuǎn)化,導(dǎo)致有的字符轉(zhuǎn)化失敗。

在本問(wèn)題中,是由于在網(wǎng)頁(yè)上包含、這樣的中文,由于是生僻字沒(méi)有相應(yīng)的UTF-8編碼,所以以默認(rèn)UTF-8編碼格式轉(zhuǎn)化為Unicode時(shí),沒(méi)有對(duì)應(yīng)的字符,轉(zhuǎn)化出錯(cuò),得到\ufffd。又因?yàn)樵赾md運(yùn)行,因此報(bào)錯(cuò)UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'

解決辦法

寫(xiě)爬蟲(chóng)解析網(wǎng)頁(yè)時(shí),要注意原網(wǎng)頁(yè)的編碼格式和壓縮格式(Gzip等)

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


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

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

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

注意:本解決辦法適用于與本問(wèn)題描述完全相同的問(wèn)題,因?yàn)榭赡苁窍嗤腻e(cuò)誤原因?qū)е碌?。其它?bào)錯(cuò)信息可能與本問(wèn)題的情況不同,比如報(bào)錯(cuò)的為‘gbk’ codec can’t encode character ‘\xa0’,爬蟲(chóng)在寫(xiě)入文件時(shí)報(bào)錯(cuò)

以下是問(wèn)題的逐步分析解決過(guò)程。

解決過(guò)程

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

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

分析:這個(gè)解釋確實(shí)符合報(bào)錯(cuò)信息'gbk' codec can't encode character '\ufffd'的意思。

驗(yàn)證:編寫(xiě)python代碼

print('\ufffd')

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

解決辦法1:改變標(biāo)準(zhǔn)輸出的默認(rèn)編碼

在程序的開(kāi)始加入以下代碼

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

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

效果:運(yùn)行原來(lái)的爬蟲(chóng)代碼后,沒(méi)有了報(bào)錯(cuò),但原先報(bào)錯(cuò)的輸出位置顯示為??,中文仍沒(méi)有正確顯示。



而且還有不能即時(shí)輸出的問(wèn)題,類(lèi)似于python爬蟲(chóng)中文輸出問(wèn)題以及不即時(shí)輸出問(wèn)題

解決辦法2:輸出時(shí)忽略無(wú)法編碼的字符

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

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

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

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



總結(jié):由于\ufffd本身就沒(méi)有對(duì)應(yīng)的Unicode編碼,所以要在cmd中不報(bào)錯(cuò)輸出,只能把輸出編碼改為GBK或者在輸出時(shí)忽略無(wú)法編碼的字符,這樣就算可以不報(bào)錯(cuò)輸出,也不能正確顯示\ufffd字符。

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

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

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

運(yùn)行代碼

print('\ufffd')

輸出為: ?


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

進(jìn)一步分析

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

從以上解決辦法可以進(jìn)一步驗(yàn)證和推測(cè)一些問(wèn)題:

問(wèn)題

  1. 本來(lái)應(yīng)該顯示的漢字是什么

  2. ?是從哪來(lái)的

推測(cè)

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

驗(yàn)證

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

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

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

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

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

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

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

最終解決

在進(jìn)一步分析后,重新檢查解析過(guò)程,顯然是編碼問(wèn)題。

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


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

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

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

最后再次在cmd運(yùn)行代碼,、這樣的中文也成功顯示。

最終總結(jié),是由于在網(wǎng)頁(yè)上包含這樣的中文,由于、是生僻字沒(méi)有相應(yīng)的UTF-8編碼,所以以默認(rèn)UTF-8編碼格式轉(zhuǎn)化為Unicode時(shí),沒(méi)有對(duì)應(yīng)的字符,轉(zhuǎn)化出錯(cuò),得到\ufffd。又因?yàn)樵赾md運(yùn)行,因此報(bào)錯(cuò)UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'。

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

聯(lián)系客服