blog

Windows Phone 7でSgmlReaderを使ってHTMLページをスクレイピングする

2011.05.30

デバイスソリューション部 モバイルソフトウェアデザイングループの和田です。

プライベートでWindows Phone 7アプリケーションを何本か開発していますが、WebAPIが提供されていないサイトのアプリを作っていると、スクレイピングしなければいけない事が多々あります。

私は、neueccさんがSilverlight/Windows Phone 7向けにポーティングしてくださったsgmlreader.slを使っていましたが、以下の様なHTMLの文書型宣言があると、HTMLパースに失敗しまうのに少し悩んでいました。

どうしてもパースを通したいページがありましたので、forkして修正したコードをSgmlReader.SL / overview – Bitbucketへあげておきました。一応、SgmlReader本家の最新版とのマージを取っておきましたが、あまりテストしていませんので、正しくパース出来ないページがありましたらforkして修正して頂けると嬉しいです。

●使い方

SgmlReader.SL / overview – Bitbucketへアクセスして、プロジェクトを一式ダウンロードしてください。ビルドしたSgmlReader.WP7.dllとSystem.Xml.Linq.dllを開発中のプロジェクトへ参照追加します。

適当なボタンがタップされると、WebClientクラスのOpenReadAsyncメソッドを使用して非同期でHTMLを取得しにいきます。レスポンスが返ってくると完了通知のイベントハンドラのwc_OpenReadCompletedメソッドが呼ばれますので、StreamをSgmlReaderへ渡して、新しい XDocument を作成します。

あとは、XDocumentをLinq等を使って必要な要素を取り出して、ListBox等に表示すれば仕舞いです。

●もう少し現実に即した使い方

一通りの使い方としては、上記の通りなのですが、実際に表示させたわけではないので、本当にパース出来ているのか判りません。ListBoxにスクレイピングした情報を表示してみましょう。簡単なヘルパークラスを作ります。

次に表示を変更したいのでxamlの修正を行います。ListBoxのItemTemplateを定義します。簡易的なものということで書籍のサムネイル画像を表示させるImageと書籍のタイトルを表示させるTextBlockを横並びに配置しました。

最後に、取得したHTMLページをパースしたXDocumentから表示に使用する要素を探しBookクラスに詰めて行きます。最後にBookインスタンスの配列をListBox.ItemSourceへ設定します。

上記のコードをプロジェクトに組み込み、Windows Phone Emulator上で実行しました。