« 天気晴朗ナレドモ波タカシ | トップページ | 神無月の巫女 »

2005年5月28日

HTML の文字コードを調べる

Pythn スクリプト。これを元に unicode(object, encoding) かけて html2text.py に通す前に使ったりするユーティリティー的なものです。微妙に大げさな感じのスクリプトになってしまいましたが使う側としては HTML を文字列として取って来て get_encoding(html) と関数を呼べばいいだけなので、使うだけなら簡単。

HTML ファイル内でちゃんと文字コードの指定がされている事が大前提ではありますが。(日本語の文書 だと確実に分かっているのならば指定が無かったとしてもそれなりにやりようがありますけれども、それはもはや HTML だからどうこうという話ではないですし)

ちなみに "Shift-JIS" が返って来たからといって馬鹿正直にそのまま適用すると機種依存文字でコケると思いますので、例えば unicode(html, 'cp932', 'replace') くらいの要領はこらしましょう。

u'''
htmlencoding.py

HTML の文字コード指定を調べる。
'''
import HTMLParser
import codecs

__author__ = 'kadotanimitsuru' __date__ = '2005-05-28' __license__ = 'public domain' __version__ = '1.0.0' class _encodingParser(HTMLParser.HTMLParser):
    def reset(self):
        HTMLParser.HTMLParser.reset(self)
        self.htmltype = None         self.encoding = None     def handle_starttag(self, tag, attributes):
        if not self.encoding and tag == 'meta':
            a = dict(attributes)
            if a.get('http-equiv', '').lower() == "content-type":
                try:
                    content = a['content']
                except KeyError:
                    return                 for i in content.split(';'):
                    try:
                        start = i.lower().index('charset=')
                    except ValueError:
                        continue                     start += len('charset=')
                    self.encoding = i[start:].strip()
                    break     def handle_decl(self, decl):
        d = decl.split()
        if len(d) > 1 and d[0] == 'DOCTYPE':
            if d[1] == 'HTML':
                self.htmltype = 'HTML'             elif d[1] == 'html':
                self.htmltype = 'XHTML'            
    def handle_pi(self, data):
        if not self.encoding and data.split()[0] == 'xml':
            try:
                start = data.index('encoding="')
            except ValueError:
                return             start += len('encoding="')
            end = data.index('"', start)
            self.encoding = data[start:end]
def get_encoding(html):
    u'''
    HTML の文字コード指定を返す。不明の時は None を返す。
    '''
    for codec, name in (
        (codecs.BOM_UTF8, 'utf_8'),
        (codecs.BOM_BE, 'utf_16_be'),
        (codecs.BOM_LE, 'utf_16_le')):
        if html.startswith(codec):
            return name

    # iso-2022-jp 等の '<' を含む漢字コードでエラーが出るので
    # 漢字の出現する可能性のある <title> 前で切る。
    try:
        n = html.lower().index('<title>')
    except ValueError:
        pass     else:
        html = html[:n]

    p = _encodingParser()
    p.feed(html)
    p.close()
    encoding = p.encoding
    if encoding is None and p.htmltype == 'XHTML':
        encoding = 'UTF-8'     return encoding
if __name__=='__main__':
    import urllib
    url = 'http://tuchinoko.moe-nifty.com/oboegaki/'     html = urllib.urlopen(url).read()     print url
    print get_encoding(html)

# 好きに流用してください。

« 天気晴朗ナレドモ波タカシ | トップページ | 神無月の巫女 »

パソコン・インターネット」カテゴリの記事

Python」カテゴリの記事

トラックバック


この記事へのトラックバック一覧です: HTML の文字コードを調べる:

« 天気晴朗ナレドモ波タカシ | トップページ | 神無月の巫女 »

他のアカウント

ブログ妖精

  • ココロ

Affiliate

無料ブログはココログ