03-网页内容的编码检测 | 02.数据解析 | Python
2010-05-18 15:57
656 查看
03-网页内容的编码检测
郑昀 201005 隶属于《02.数据解析》小节我们需要确定网页的内容/标题等文字的编码格式,比如 utf-8 、gb2312 等。
通用检测顺序
一般来说,国内外类似服务的检测顺序是(参见参考资源A):charset parameter in HTTP
Content-typeheader.
<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-typeheader 与 meta charset 一致,比如新浪新闻、和讯、网易新闻的 html 里都会写明 meta charset 是 gb2312,但新浪新闻的 HTTP
Content-typeheader 里却只输出: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
fromEncodingargument to the soup constructor.
An encoding discovered in the document itself: for instance, in an XML declaration or (for HTML documents) an
http-equivMETA 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
chardetlibrary, 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 ;
相关文章推荐
- 02Python外部数据获取_解析网页
- python解析网页中javascript动态添加的内容(一)
- Python 爬虫 —— 网页内容解析(lxml)
- python爬虫解析网页编码问题
- 用python进行分布式网页数据抓取(三)—— 编码实现
- python 解析网页数据的几种方法简介
- perl post函数获取网页内容及解析数据的例子
- python解析网页中javascript动态添加的内容
- Scrapy:Python3版本上安装数据挖掘必备的scrapy框架详细攻略(二最完整爬取网页内容信息攻略)——Jason niu
- Python定时返回网址状态码&&网页内容是否为json数据
- Java HttpURLConnection 抓取网页内容 解析gzip格式输入流数据并转换为String格式字符串
- python读网页解析内容写入文件
- 02Python外部数据获取_下载网页
- java利用url解析网页内容并模拟手动form提交数据
- python获取网页内容的相关编码问题
- python解析网页中javascript动态添加的内容 一
- 【python】使用Python中的urlparse、urllib抓取和解析网页
- 20161229:for python网络数据采集03
- scrapy:python下的网页抓取及解析框架