淺入深出 | 網站爬取時出現亂碼該怎麼辦

2021-02-14 CDA數據分析師

作者:丁彥軍

本文轉自公眾號:戀習Python(ID:sldata2017)

近日,有位粉絲向我請教,在爬取某網站時,網頁的原始碼出現了中文亂碼問題。之前關於爬蟲亂碼有很多粉絲的各式各樣的問題,今天與大家一起總結下關於網絡爬蟲的亂碼處理。注意,這裡不僅是中文亂碼,還包括一些如日文、韓文 、俄文、藏文之類的亂碼處理,因為他們的解決方式 是一致的,故在此統一說明。

一、亂碼問題的出現

就以爬取51job網站舉例,講講為何會出現「亂碼」問題,如何解決它以及其背後的機制。

代碼示例:

import requests

url = "http://search.51job.com"
res = requests.get(url)
print(res.text)

顯示結果:

列印res.text時,發現了什麼?中文亂碼!!!不過發現,網頁的字符集類型採用的gbk編碼格式。

我們知道Requests 會基於 HTTP 頭部對響應的編碼作出有根據的推測。當你訪問 r.text 之時,Requests 會使用其推測的文本編碼。你可以找出 Requests 使用了什麼編碼,並且能夠使用r.encoding 屬性來改變它。

接下來,我們一起通過resquests的一些用法,來看看Requests 會基於 HTTP 頭部對響應的編碼方式。

print(res.encoding)  #查看網頁返回的字符集類型
print(res.apparent_encoding) #自動判斷字符集類型

輸出結果為:

可以發現Requests 推測的文本編碼(也就是網頁返回即爬取下來後的編碼轉換)與源網頁編碼不一致,由此可知其正是導致亂碼原因。

二、亂碼背後的奧秘

當源網頁編碼和爬取下來後的編碼轉換不一致時,如源網頁為gbk編碼的字節流,而我們抓取下後程序直接使用utf-8進行編碼並輸出到存儲文件中,這必然會引起亂碼,即當源網頁編碼和抓取下來後程序直接使用處理編碼一致時,則不會出現亂碼,此時再進行統一的字符編碼也就不會出現亂碼了。最終爬取的所有網頁無論何種編碼格式,都轉化為utf-8格式進行存儲。

注意:區分源網編碼A-gbk、程序直接使用的編碼B-ISO-8859-1、統一轉換字符的編碼C-utf-8。

在此,我們拓展講講unicode、ISO-8859-1、gbk2312、gbk、utf-8等之間的區別聯繫,大概如下:

最早的編碼是iso8859-1,和ascii編碼相似。但為了方便表示各種各樣的語言,逐漸出現了很多標準編碼。iso8859-1屬於單字節編碼,最多能表示的字符範圍是0-255,應用於英文系列。很明顯,iso8859-1編碼表示的字符範圍很窄,無法表示中文字符。

1981年中國人民通過對 ASCII 編碼的中文擴充改造,產生了 GB2312 編碼,可以表示6000多個常用漢字。但漢字實在是太多了,包括繁體和各種字符,於是產生了 GBK 編碼,它包括了 GB2312 中的編碼,同時擴充了很多。中國又是個多民族國家,各個民族幾乎都有自己獨立的語言系統,為了表示那些字符,繼續把 GBK 編碼擴充為 GB18030 編碼。每個國家都像中國一樣,把自己的語言編碼,於是出現了各種各樣的編碼,如果你不安裝相應的編碼,就無法解釋相應編碼想表達的內容。終於,有個叫 ISO 的組織看不下去了。他們一起創造了一種編碼 UNICODE ,這種編碼非常大,大到可以容納世界上任何一個文字和標誌。所以只要電腦上有 UNICODE 這種編碼系統,無論是全球哪種文字,只需要保存文件的時候,保存成 UNICODE 編碼就可以被其他電腦正常解釋。UNICODE 在網絡傳輸中,出現了兩個標準 UTF-8 和 UTF-16,分別每次傳輸 8個位和 16個位。於是就會有人產生疑問,UTF-8 既然能保存那麼多文字、符號,為什麼國內還有這麼多使用 GBK 等編碼的人?因為 UTF-8 等編碼體積比較大,佔電腦空間比較多,如果面向的使用人群絕大部分都是中國人,用 GBK 等編碼也可以。

也可以這樣來理解:字符串是由字符構成,字符在計算機硬體中通過二進位形式存儲,這種二進位形式就是編碼。如果直接使用 「字符串↔️字符↔️二進位表示(編碼)」 ,會增加不同類型編碼之間轉換的複雜性。所以引入了一個抽象層,「字符串↔️字符↔️與存儲無關的表示↔️二進位表示(編碼)」 ,這樣,可以用一種與存儲無關的形式表示字符,不同的編碼之間轉換時可以先轉換到這個抽象層,然後再轉換為其他編碼形式。在這裡,unicode 就是 「與存儲無關的表示」,utf—8 就是 「二進位表示」。

三、亂碼的解決方法

 根據原因來找解決方法,就非常簡單了。

方法一:直接指定res.encoding

import requests

url = "http://search.51job.com"
res = requests.get(url)
res.encoding = "gbk"
html = res.text
print(html)

方法二:通過res.apparent_encoding屬性指定

import requests

url = "http://search.51job.com"
res = requests.get(url)
res.encoding = res.apparent_encoding
html = res.text
print(html)

方法三:通過編碼、解碼的方式

import requests

url = "http://search.51job.com"
res = requests.get(url)
html = res.text.encode('iso-8859-1').decode('gbk')
print(html)

輸出結果:

基本思路三步走:確定源網頁的編碼A---gbk、程序通過編碼B---ISO-8859-1對源網頁數據還原、統一轉換字符的編碼C-utf-8。至於為啥為出現統一轉碼這一步呢? 網絡爬蟲系統數據來源很多,不可能使用數據時,再轉化為其原始的數據,假使這樣做是很廢事的。所以一般的爬蟲系統都要對抓取下來的結果進行統一編碼,從而在使用時做到一致對外,方便使用。

比如如果我們想講網頁數據保存下來,則會將起轉為utf-8,代碼如下:

with open("a.txt",'w',encoding='utf-8') as f:
    f.write(html)

四、總結

關於網絡爬蟲亂碼問題,本文不僅給出了一個解決方案,還深入到其中的原理,由此問題引申出很多有意思的問題,如,utf-8、gbk、gb2312的編碼方式怎樣的?為什麼這樣轉化就可以解決問題?

最後,多動腦,多思考,多總結,致每一位碼農!

相關焦點

  • 淺入深出:一次提問引發的深思,從此再也不怕「亂碼」問題
    (點擊上方公眾號,可快速關注一起學Python)來自:戀習Python  連結:https://mp.weixin.qq.com/s/wv0nWKPNQhyqmYCamEdNGQ近日,有位粉絲向我請教,在爬取某網站時
  • iPhone郵件亂碼怎麼辦_iPhone郵件亂碼解決教程
    iPhone郵件亂碼怎麼辦_iPhone郵件亂碼解決教程 2014-07-31 10:24 | 作者:SORA | 來源:265G QQ群號:624022706 | 我要分享:
  • python爬蟲實戰:爬取全站小說排行榜
    我們本文就爬取這個網站的上千本小說。重點在和大家一起分享一些爬蟲的思路和一些很常遇到的坑。 一、爬取單本小說爬取該網站相對來講還是很容易的,打開編輯器(推薦使用PyCharm,功能強大),首先引入模塊urllib.request(Python2.x的引入urllib和urllib2即可,待會我把2.x的也寫出來給大家看看),給出網站URL,寫下請求,再添加請求頭(雖然這個網站不封號,但作者建議還是要養成每次都寫請求頭的習慣,萬一那天碰到像豆瓣似的網站
  • 日文遊戲亂碼怎麼辦 亂碼轉換工具下載及使用
    很多日文遊戲會有地區限制,尤其是Win 7、Win8玩日文遊戲亂碼情況經常出現,那麼遇到這種日文遊戲亂碼情況該怎麼辦呢,這裡我們需要一個亂碼轉換工具,此類軟體有不少,比如applocale亂碼轉換工具,NTLEA等。
  • 《王國風雲3》字體亂碼怎麼辦 字體亂碼解決辦法
    導 讀 王國風雲3字體亂碼怎麼辦?
  • Python爬取某個18禁網站的電影資源
    最近在想著爬一些有趣的網站,豆瓣淘寶京東,這些網站大多都被爬爛了,然後就想著爬點簡單點的,例如某色網站啥的是吧,男生一般都會有幾個自己知道的網站
  • U盤盤符及文件無故出現文件亂碼,找回文件並修復U盤.
    棟哥 教你 免費教你修電腦 昨天 手機閱讀今天客戶一個U盤盤符和裡面的文件出現亂碼故障
  • 【亂碼賤聞】普天同慶,丘咲愛米莉下馬了!
    事後,該女子獨自回到家中,在微信聊天中向男子討要說法,但該男子卻不承認這一回事,還說想跟她談戀愛。第二天,該女子向派出所報案。 目前,該男子因涉嫌強姦罪被警方刑拘。But,戴完之後,這位哥發現自己沒鑰匙,手銬取不下來了。 不得已只能向警方求助,但警方也沒有那副手銬的鑰匙啊。最後在該縣公安消防大隊的幫助下,消防官兵用絕緣剪連剪兩個口,手銬才被取下。
  • 用Python爬取B站、騰訊視頻、芒果TV和愛奇藝視頻彈幕
    那麼,我們該如何獲取彈幕數據呢?本文運用Python爬取B站視頻、騰訊視頻、芒果TV和愛奇藝視頻等彈幕,讓你輕鬆獲取主流視頻網站彈幕數據。 一、B站視頻彈幕1.網頁分析本文以爬取up主硬核的半佛仙人發布的《你知道奶茶加盟到底有多坑人嗎?》視頻彈幕為例,首先通過以下步驟找到存放彈幕的真實url。
  • 網站被黑怎麼辦?網站被黑解決方法有哪些?
    當然網站被黑「可遇而不可求」大家都不希望自己的網站遇到被黑的情況,因為這不僅會影響到自己網站的收錄、流量,還需要花時間去處理,但是如果遇到了網站被黑大家要怎麼辦呢?這對於一些新手seoer來說這就是需要大家能夠掌握到的技能。
  • 關於上期推送的亂碼文章
    上次推送中出現了一篇亂碼文章,其實那不是亂碼,而是摩斯電碼,高中生現有的知識存量應該很容易就想得到,後臺有評論說將摩斯電碼轉化之後是一串毫無規律的數字
  • 【冷知識大講堂】AV下載一半卡住了怎麼辦?
    小電影下載一半卡住了怎麼辦?身份證最後一位的X到底是什麼意思?嬰兒學步車真的有用麼?關燈一小時到底環不環保?什麼是二簡字?無碼的A片是怎麼來的?西遊記一共多少集?我賭你知道的不超過2個!【亂碼點評】說!是不是非常有用?  2.身份證號最後一位如果出現X,該X並不是英文字母X,而是羅馬字母X,代表數字10。
  • 爬取123粉絲網明星數據榜單,看看你的愛豆現在排名變化情況
    以下文章來源於雲+社區,作者 深霧轉載地址https://blog.csdn.net/fei347795790?本文和你一起爬取娛樂圈的排行榜數據,來看看你的愛豆現在排名變化情況,有幾次登頂,幾次進了前十名呀。
  • 【神奇】趙家務網友查話費卻收到一堆亂碼 這是咋回事?
    當他像往常一樣查話費時,收到的回覆簡訊竟然是一對亂碼加數字。因為平時從來沒有出現過這種情況,這讓人感到非常詫異。於是他又重新試了一遍,結果仍舊收到一堆亂碼。亂碼簡訊上日期和機型都顯示的十分正確,使用和未使用的流量有多少也有明確的數字標識,不過套餐的名稱全部變成了問號、括號、加減號……這叫人真心看不懂啊。
  • 百度搜索網站出現安全中心提醒怎麼辦「一招解決」
    你在百度上搜索關鍵詞時,看到自己的網站被百度提示:「百度網址安全中心提醒您:該頁面可能存在違法信息」,你會不會嚇一跳?百度搜索網站出現安全中心提醒怎麼辦百度網址安全中心提醒您:該頁面可能存在違法信息很多站長看到這樣的提示,都會驚訝自己網站昨天還好好的
  • 映月城與電子姬劇情亂碼解決方法介紹
    許多玩家都想知道映月城與電子姬劇情亂碼解決方法介紹,畢竟映月城與電子姬劇情亂碼怎麼辦的確很傷神的,很多玩家都遇到了開局劇情顯示亂碼的情況,非常影響玩家的遊戲體驗,那麼遇上劇情亂碼怎麼辦呢?想知道的就和小編一起來看看吧。
  • 我用Python爬取美食網站3032個菜譜並分析,真香!
    於是,J哥默默打開了各大美食網站,如豆果美食、下廚房、美食天下等。經過甄選,最終爬取了豆果網最新發布的中國菜系共3032個菜譜,然後清洗數據並做可視化分析,試圖走上美食博主的康莊大道。豆果美食網的數據爬取比較簡單,如果您對爬蟲感興趣,可查看J哥往期原創文章「實戰|手把手教你用Python爬蟲(附詳細源碼)」,思路一致。
  • Python爬取視頻之愛情電影及解密TS文件和兩種合併ts
    so結合興趣的學習才能事半功倍,更加努力專心,apparently本次任務是在視頻網站爬取一些好看的小電影,地址不放(狗頭保命)只記錄過程。實現功能:從網站上爬取採用m3u8分段方式的視頻文件,對加密的 "ts"文件解密,實現兩種方式合併"ts"文件,為防止IP被封,使用代理,最後刪除臨時文件。
  • 【亂碼賤聞】變態男戴假髮穿女內衣,潛入大學女浴室偷窺
    一聽對方錢不夠,冉某「噗」的一下笑出了聲。「來把微信加起,我給你發紅包,你們快點打車過來。」【亂碼點評】小夥子趙信玩多了吧? 先別急著為該男子抱不平,據亂碼了解,國內很多報導都忽略了一個事實,該男子之所以會被抓,其實是因為下載的部分影片當中存在「虐待兒童」的情節。他不僅下載了大量兒童色情的圖片,還有如何虐待兒童但不會留下證據的資料。
  • 嗜欲深者天機淺
    是故莊子云:嗜欲深者天機淺(出自《莊子·大宗師》)。這與今人價值觀念不同。今人謂若「一事無成、一無所長」,那便「一錢不值」了。      弘一法師一生涵括無數成就,少年時即已才華橫溢,深獲諸方仰敬,人謂「無數奇珍供世眼」。