RSS

Shift JISのHTMLを読む前に

引き続きHXTでスクレイピングの話。対象ファイルがShift JISなのでText Nodeの検索などを考えると素直にはいかない。結局IConvを使って変換することに。以下のようなコードになる。

import Codec.Binary.UTF8.String
import Codec.Text.IConv
import Data.List
import Text.XML.HXT.Core
import qualified Data.ByteString.Lazy as BSL

main = do
  cs <- BSL.readFile "shiftjis.html"
  let u8s  = convert "CP932" "UTF-8" cs
  let html = decode (BSL.unpack  u8s)
  let doc  = readString [withParseHTML yes, withWarnings no] html
  nodes <- runX $ doc //> hasText (isInfixOf  "日")
  mapM_ (putStrLn . show) nodes

GHCのString(=[Char])は内部エンコーディングにUCS-4が使われていらしいがソースコードがutf-8なら認識はしてくれる。

IConvはByteStringを直接扱っているがそのバイト列のエンコーディングをプログラマが意識しなければならない。この点はHaskellの型を使わない実装というのはあまり良くないと思う。UTF-8の入ったByteStringとEUC-JPの入ったByteStringを混ぜることができるなんて恐しい…。