- PR -

[C#2005/Windowsアプリ]WEBページをローカル保存する方法

投稿者投稿内容
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-08-19 02:39
引用:

HttpWebRequestで保存できるなら、
あとは取得したHTMLをパースして
足りない画像など外部ファイルも
ダウンロードすればいいだけだと思いますが。



汎用なモノを作るのはかなり大変ですよね?

画像込みとなると、昨今は HTML 解析だけでなく CSS まで解析しない駄目です。ダウンロードしたファイルを解析するにはコード判定もしなくてはならないし。。。

最近新作を見かけませんが、ホームページ巡回ツールみたいなものが実在する以上、不可能とは言いませんが、1から全部作るとなるとかなりぞっとしないボリュームがあるように思います。

れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-08-19 14:02
引用:

渋木宏明(ひどり)さんの書き込み (2007-08-19 02:39) より:
汎用なモノを作るのはかなり大変ですよね?



本当に汎用的なのは大変だと思います。

今回は対象ページが決まってるようなので、
必要なものだけ実装すれば、簡単にできるのではないでしょうか。
技術的にも難しいことはないですし。

特定のページを対象にした「動けばいい」レベルのものなら
テストとか遊びでたまに作りますが、かなり簡単にできます。
ちづる
ベテラン
会議室デビュー日: 2004/07/27
投稿数: 72
投稿日時: 2007-08-19 14:38
渋木宏明様、れい様、hei様
ご教示ありがとうございます。
HTMLで保存する事は諦めました(画像が多用されてること、CSSを外部ファイルで読み込んでる事などから、HTML単体での保存は難しいようです)。

Cookie経由で受信したHTMLの相対パスを絶対パスに変換して保存したらどうか?と思ったのですが
保存したいHTMLの構文が改行せず組まれている為変換の時点で全ての行も読み込めませんでした(多分これを別のやり方をすれば可能だと思うのですが、処理自体が重くなりそうなので、現在は保留です)

今のところBページだけ、というものなのですがいずれ他のページも同様に保存する、という事になりそうな気配があります・・・。
しかも3日でモノを作ってくれ、という無茶な御願いもあり、HTML保存はやめました。

hei様が提案してくださった「HTMLを画像で保存」という方法をやってみたところ、
保存まで無事作成することができたので、こちらの方法で問題をクリアしてみようと思います。

有難うございました。
ちづる
ベテラン
会議室デビュー日: 2004/07/27
投稿数: 72
投稿日時: 2007-08-19 15:47
たびたびすみません。
画像保存はできるようになったのですが、やはり全てを自動で行う事ができませんでした・・・。

処理A(){
  A画面アクセス
  B画面アクセス
  処理B呼び出し
}

処理B(){
  キャプチャ処理
}

キャプチャの段階でエラーで落ちます。

予想ですが、処理Aを完全に抜けないと、キャプチャ処理でwebBrowserの内容を取得できない状態になってるんだと思います。
処理Aにて処理Bをcallしないで、処理B自体個別に呼ぶ(ボタン押下等)場合はスムーズに行えます。
やはり全てを自動化するのは無理なのでしょうか・・・。
IIJIMAS
ベテラン
会議室デビュー日: 2006/12/06
投稿数: 77
投稿日時: 2007-08-19 16:06
引用:

キャプチャの段階でエラーで落ちます。

予想ですが、処理Aを完全に抜けないと、キャプチャ処理でwebBrowserの内容を取得できない状態になってるんだと思います。
処理Aにて処理Bをcallしないで、処理B自体個別に呼ぶ(ボタン押下等)場合はスムーズに行えます。


まだHTMLドキュメントを読み終わっていない時に処理しようとしているからではないでしょうか。
処理Aから処理Bを呼ぶのではなく、
DocumentCompleteイベント
http://msdn2.microsoft.com/ja-jp/library/aa768329.aspx
のハンドラを作成してそこから処理Bを呼ぶようにすればよいのでないでしょうか。
hei
ベテラン
会議室デビュー日: 2006/09/07
投稿数: 78
投稿日時: 2007-08-19 16:30
引用:

やはり全てを自動化するのは無理なのでしょうか・・・



できますよ。
私も先ほどのサイトを参考にしてやってますから。
ただ、私の用途では問題になりませんが、
たまにIEで表示した場合と全く同じようにはならないこともあります。

ちづるさんができない原因はIIJIMASさんのおっしゃっているとおりだと思いますが、
処理Bの後でもDocumentCompletedイベントが発生してからでないと
失敗するかキャプチャできないと思います。

読み込み完了を待つには
DocumentCompletedイベントをハンドルする方がいいようですが、

Application.DoEvents()
While browser.IsBusy OrElse browser.ReadyState <> WebBrowserReadyState.Complete
Application.DoEvents()
End While

という方法もあります。

#これVBのコードです。
#ポーリング中は適当にThread.Sleep(arg)を入れた方がいいでしょう。

[ メッセージ編集済み 編集者: hei 編集日時 2007-08-19 16:39 ]
ちづる
ベテラン
会議室デビュー日: 2004/07/27
投稿数: 72
投稿日時: 2007-08-19 18:24
IIJIMAS様、hei様

DocumentCompletedイベントを追加し、その中で処理Bをcallするようにしたところ
エラーにならず無事
画面A→画面B→キャプチャ
を行う事ができました!!!
ありがとうございます!!!

一番つまづいていた所が無事解決できました!
YAS
ベテラン
会議室デビュー日: 2006/02/15
投稿数: 59
投稿日時: 2007-08-30 00:31
YASと申します。
「Webページをビットマップで取得する」のページを使っていただきありがとうございます。
ビットマップ化の難点は,ページの大きさを正確につかむことが難しいことです。特にフレームを使っていたりするとややこしくなり,しばらく考えたのですが結局どんなページでも全体が入りきるようにビットマップにする方法はわかりませんでした。
そこで,CDO.Messageオブジェクトを使ってmhtファイルに保存するのはどうでしょう。
あちこちのページで紹介されていますが,VB2005だと以下のようになります。C#でないのが申し訳ありませんが,参考にしてください。

Const adSaveCreateOverWrite = 2
Dim CDO As Object = CreateObject("CDO.Message")
CDO.CreateMHTMLBody("http://www.yahoo.co.jp")
CDO.GetStream.SaveToFile("D:\www.yahoo.co.jp.mht", adSaveCreateOverWrite)

C#では遅延バインディングができませんので,このままでは使えませんが...

スキルアップ/キャリアアップ(JOB@IT)