zoukankan      html  css  js  c++  java
  • 03网页内容的编码检测 | 02.数据解析 | Python

    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

  • 相关阅读:
    Java多线程简介
    Java同步简介
    java enum的用法详解
    Instrumentation(3)
    持久化类的三种实例状态
    依赖注入和控制反转
    事务的4个要素及其工作原理
    mysql创建表与索引
    SpringAOP所支持的AspectJ切点指示器
    使用Spring的命名空间p装配属性-摘自《Spring实战(第3版)》
  • 原文地址:https://www.cnblogs.com/zhengyun_ustc/p/1738340.html
Copyright © 2011-2022 走看看