03-網頁內容的編碼檢測 | 02.資料解析 | Python

來源:互聯網
上載者:User
03-網頁內容的編碼檢測

鄭昀 201005 隸屬於《02.資料解析》小節

我們需要確定網頁的內容/標題等文字的編碼格式,比如 utf-8 、gb2312 等。

通用檢測順序

一般來說,國內外類似服務的檢測順序是(參見參考資源A):

  • charset parameter in HTTP Content-type header.
  • <meta http-equiv="content-type"> element in the <head> of a web page for HTML documents.
  • encoding attribute in the XML prolog for XML documents.
  • Auto-detect the character encoding as a last resort.

也就是,HTTP Response 的 header 裡 content-type 如果指定 charset 的話,優先順序是高於 HTML 裡的 content-type 的。

 

由於我國網路服務商不一定保持 HTTP Content-type header 與 meta charset 一致,比如新浪新聞、和訊、網易新聞的 html 裡都會寫明 meta charset 是 gb2312,但新浪新聞的 HTTP Content-type header 裡卻只輸出:Content-Type: text/html ,並沒有給出 charset 參數。網易新聞則 HTTP Header 中指定 GBK ,而 HTML 裡卻指定 GB2312 。

國外的一些服務探測我國網站時,容易因此得到亂碼,如我的文章《Yahoo! Pipe的charset問題之解決方案》所說的。

 

這樣帶來的一個問題就是:

當 HTTP Content-type header 與 meta charset 不一致時,到底採信誰的聲明?

當然也可以用 chardet 來檢測內容,但 chardet 非常消耗資源,在網路爬蟲中頻繁調用 chardet 吞吐大量 html 字串,會降低抓取效率。

 

BeautifulSoup 自動探測機制

BeautifulSoup 會自動判斷頁面編碼,如果判斷不出來就調用 chardet 探測。它的探測順序是:

Beautiful Soup tries the following encodings, in order of priority, to turn your document into Unicode:

  • An encoding you pass in as the fromEncoding argument to the soup constructor.
  • An encoding discovered in the document itself: for instance, in an XML declaration or (for HTML documents) an http-equiv META tag. If Beautiful Soup finds this kind of encoding within the document, it parses the document again from the beginning and gives the new encoding a try. The only exception is if you explicitly specified an encoding, and that encoding actually worked: then it will ignore any encoding it finds in the document.
  • An encoding sniffed by looking at the first few bytes of the file. If an encoding is detected at this stage, it will be one of the UTF-* encodings, EBCDIC, or ASCII.
  • An encoding sniffed by the chardet library, if you have it installed.
  • UTF-8
  • Windows-1252

BeautifulSoup 優先用 meta charset 指示的編碼進行探測,但未必對。

舉一個異常的例子,http://www.miniclip.com/games/cn/ ,它的 HTTP Content-type header 是 utf-8,而 meta charset 卻是 iso-8859-1,實際上它的編碼是 utf-8 。

對於這種情況,怎麼辦?

可以讓 BeautifulSoup 強制按照 HTTP Content-type 聲明的編碼做轉換:

from BeautifulSoup import BeautifulSoup
from urllib import urlopen
response=urlopen('http://www.miniclip.com/games/cn/')
charset=BeautifulSoup.CHARSET_RE.search(response.headers['content-type'])
charset=charset and charset.group(3) or None
page=BeautifulSoup(response.read(),fromEncoding=charset)

 

 

參考資源:

A、 Encoding detection library in python ;

B、 [CPyUG:76548] 關於正確的判斷頁面編碼 ;

C、 Beautifulsoup 分析網頁亂碼問題解決辦法 ;

D、 Python中文問題研究 ;

E、 BeautifulSoup處理gb2312編碼網頁的一個bug ;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.