5倍速!メールマガジン
外部アカウントで登録
受講生の声
新着の講座投稿
新着の講座コメント
新着のノート投稿
投稿一覧へ新着のノートコメント
表示できる投稿はありません。
サイト運営者紹介
小川 慶一講師/教材/システム開発者紹介
この学習サイトの教材制作、サポート、システム開発をすべてやっています。
表示できる投稿はありません。
この学習サイトの教材制作、サポート、システム開発をすべてやっています。
受講生さんの投稿
(投稿ID: 4694)
お世話になっております。
本日は少し長いですが、よろしくお願いいたします。
DOMとして取得したレスポンスボディの文字化けに関する質問です。
以下のコードは本講座のエクセルテキストの01_WinHttp_基本の中にあるm01010_getモジュールのGetRequestSimple1()サブプロシージャです。
Sub GetRequestSimple1()
Dim url As String
url = "http://www.exvba.com/ws/dombasic.html"
Dim xh As New WinHttp.WinHttpRequest 'HTTPリクエストを制御するクラスのインスタンスを生成
xh.Open "GET", url, False
xh.send
Dim sCode As String
sCode = xh.Status
If sCode <> 200 Then 'ステータスコードを調べる
MsgBox "リクエストに失敗しました" & vbNewLine & sCode
End If
'まずは、レスポンスヘッダー、レスポンスボディをざっくり取得してみよう
Dim sHead As String
Dim sBody As String
sHead = xh.GetAllResponseHeaders
sBody = xh.ResponseText
Worksheets("response").Range("B1").Value = sHead
Worksheets("response").Range("B2").Value = sBody
'レスポンスヘッダーの所定の項目を取得したいときは以下の要領
Debug.Print xh.GetResponseHeader("Content-Length")
End Sub
当然問題なく動いてレスポンスヘッダ、ボディともにちゃんと取れます。
しかし、対象のurlをShift_JISで記載されているページにしたら、とれてきたレスポンスボディの日本語部分が文字化けしていました。
そこで自分なりに調べて、
sBody = xh.ResponseText の部分を
→ sBody = StrConv(xh.ResponseBody, vbUnicode) に変更したら
文字化けが解消しました。
ここまでだったらよかったのですが、次に、本講義テキストの02_WinHttp_DOM解析ファイルのm02010_get_DOMモジュールの
GetRequestSimple1()プロシージャを使って、上記と同じようにurlを
Shift_Jisで記載されているページにしたら、取得したレスポンスはやはり文字化けします。
しかし、こちらは自力では解決できませんでした。上記で解決したコードも試しましたが、よけい変な文字になってしまいました。
たとえば以下のようにしてみました。
本講義のテキストのコード
Sub GetRequestSimple1()
Dim url As String
url = "http://www.exvba.com/ws/dombasic.html"
Dim xh As New WinHttp.WinHttpRequest
xh.Open "GET", url, False
xh.send
Dim sCode As String
sCode = xh.Status
If sCode <> 200 Then
MsgBox "リクエストに失敗しました" & vbNewLine & sCode
End If
'htmlをDOMとして取得する。そのための変数を宣言。
Dim oHTml As New MSHTML.HTMLDocument
oHTml.body.innerHTML = xh.ResponseText 'htmlボディーをDOMとして取得
'所定のIDの要素を取得します
Dim oH1 As MSHTML.HTMLHeadElement
Set oH1 = oHTml.getElementById("h1_01")
Debug.Print oH1.outerHTML
Debug.Print oH1.innerHTML
Debug.Print oH1.innerText
'所定の要素の次の要素を取得します
Debug.Print oH1.NextSibling.outerHTML
Debug.Print oH1.NextSibling.innerHTML
Debug.Print oH1.NextSibling.innerText
'HTMLBody全体を取得します
Dim oH As MSHTML.HTMLBody
Set oH = oHTml.getElementsByTagName("body")(0)
Debug.Print oH.outerHTML
Debug.Print oH.innerHTML
Debug.Print oH.innerText
'HtmlBodyの子要素のうち4番目のものを取得します
Debug.Print oH.ChildNodes(3).outerHTML
Debug.Print oH.ChildNodes(3).innerHTML
Debug.Print oH.ChildNodes(3).innerText
'H2タグのついた要素すべてを順番に調べます
Dim oH2 As MSHTML.HTMLHeadElement
For Each oH2 In oHTml.getElementsByTagName("h2")
Debug.Print oH2.outerHTML
Debug.Print oH2.innerHTML
Debug.Print oH2.innerText
Next
End Sub
上記テキストコードの中で以下の部分を
'HTMLBody全体を取得します
Dim oH As MSHTML.HTMLBody
Set oH = oHTml.getElementsByTagName("body")(0)
Debug.Print oH.outerHTML
↓
変更後
'HTMLBody全体を取得します
Dim oH As MSHTML.HTMLBody
Set oH = oHTml.getElementsByTagName("body")(0)
Debug.Print StrConv(oH.outerHTML, vbUnicode)
としましたが、余計、文字化けがひどくなってしまった例です。
根本的なところが分かっていないと思いますが、ご指導いただけますと幸いです。
よろしくお願いいたします。
小川 慶一さんのコメント
(コメントID: 6528)
がんばってますね。
対処法のひとつは、StrConv関数を実行する対象を変更することです。
以下を参考にしてください。
使いこなすために必要な知識が高度(発展編2レベル+外部連携レベル+さらにα)なので講座では紹介していませんが、ADODB.Stream のインスタンスを使って文字コードを変更して出力することもできます。
これだと、種々の文字コードに対して対応できます。
以下はサンプルです。
冗長だとかえって分かりにくいので、受講生さんの現状のスキルで全体を追えるかということは考えず、サンプルコードでは構造化にあまり遠慮をしていません。追いかけるのは大変かもしれませんが、まずは読み込んで動作確認してみて、としてみてください。
上で示したような小手先の方法では対処できないという場合は僕も ADODB.Stream を使います。
こういうコーディングは日常的にやるようなことではないので、細かいオプションの指定については僕も脳内には入れていません。僕が書く場合も、調べ物をしつつ、試行錯誤しつつ、(あるいは、過去に自分が書いたコードを参考にしつつ)という感じです。
> 小川さん
>
> お世話になっております。
> 本日は少し長いですが、よろしくお願いいたします。
> DOMとして取得したレスポンスボディの文字化けに関する質問です。
>
> 以下のコードは本講座のエクセルテキストの01_WinHttp_基本の中にあるm01010_getモジュールのGetRequestSimple1()サブプロシージャです。
受講生さんのコメント
(コメントID: 6530)
お世話になっております。
講義内容を超えるご回答に大変恐縮しておりますと同時に大変感謝しております。
> 受講生 さん:
> 'ADODB.Stream オブジェクトを使って文字化けを解消する
教えていただいたというか、わざわざ作ってくださったマクロで見事に
文字化けせず、DOMとしてHTMLボディを取得できました。理解するのはだいぶ先になりそうですが、とにかく実装して利用させていただきます。
> 対処法のひとつは、StrConv関数を実行する対象を変更することです。
こちらに関しては、自分なりにいろいろ試しましたが、解消しませんでしたが、もしこちらで解消するなら'ADODB.Stream オブジェクトを
利用するよりも自分では理解しやすいですし、コードも単純になりそうですので、マクロ全体の理解が深まったところで、もう一度チャレンジしたいと思います。今回は、いただいたマクロで解決しましたので、チャレンジはしばらく後になりそうですが。
最後に確認のための質問です。
今回DOMとしてレスポンスを取得(1)しようとして、文字化けの問題に遭遇しました。DOMを使わずに取得したHTMLコンテンツ(2)の場合は、文字化けの問題があったとしてもStrConv関数でなんとかなりました。ということは、DOMを使った場合(1)と、使わない場合(2)で、大きな違いがあるということでしょうか。とすれば、何が違うのか。ご指導いただけますと幸いです。
小川 慶一さんのコメント
(コメントID: 6533)
こんにちは。
> > 対処法のひとつは、StrConv関数を実行する対象を変更することです。
> こちらに関しては、自分なりにいろいろ試しましたが、解消しませんでしたが、
解消しませんでしたか...。
念のため書きますが、以下のとおり、 GetRequestSimple1_revised でのStrConvの対象は、responseBodyのほうです。それでもダメでしたでしょうか。(僕の環境ではうまくいきます)
「Web連携」の「基礎」の講座ですので。
お伝えできる内容には限界があります。
今回紹介したスクリプトのようなものを自力でなんとか作れるようになるには、前のコメントでも書きましたが、それなりに事前知識が必要です。
(あと、試行錯誤をいとわないで済むだけのPC操作スキルも)
> 今回DOMとしてレスポンスを取得(1)しようとして、文字化けの問題に遭遇しました。
「DOMとしてレスポンスを取得」はしていません。
以下の[1]→[2]の手順で仕事が進みます。そして、[2]より以前に、[1]の段階で文字化けしています。
[1] レスポンスを取得する
[2] レスポンスのDOMを解析する
各行で行っている作業に対して、日本語でご自身でコメントをつけてみてください。
全体の流れを頭の中で理解するのに良いかと思います。
あと、前回投稿の2つ目で示したモジュールのように、機能ごとに複数のプロシージャに分割してみるとかもよい学びになります。
受講生さんのコメント
(コメントID: 6539)
お世話になっております。
> 「DOMとしてレスポンスを取得」はしていません。
> 以下の[1]→[2]の手順で仕事が進みます。そして、[2]より以前に、[1]の段階で文字化けしています。
>
> [1] レスポンスを取得する
> [2] レスポンスのDOMを解析する
以上を意識して再度挑戦しまして、どうにか解消できました。
関連する箇所のコードを以下のようにしました。
' sBody = xh.ResponseText' ←とにかくこれだと文字化け
sBody = StrConv(xh.ResponseBody, vbUnicode) 'ここを変更した
Dim oHTml As New MSHTML.HTMLDocument
oHTml.body.innerHTML = sBody '←文字化け解消後のsBodyを左辺に格納
> 各行で行っている作業に対して、日本語でご自身でコメントをつけてみてください。
これも今後行っていこうと思います。
ありがとうございました。
小川 慶一さんのコメント
(コメントID: 6541)
無事解決したようで良かったです。
複数の手順や機能組み合わせになっているものについては、なるべくそれぞれ分離して取り扱える状態にするのが理解のコツです。
今回僕が示したプロシージャ分割の粒度も参考にしてください。
ひきつづき、よい学びを (^^
> 小川慶一さん:
>
> お世話になっております。
>
> > 「DOMとしてレスポンスを取得」はしていません。
> > 以下の[1]→[2]の手順で仕事が進みます。そして、[2]より以前に、[1]の段階で文字化けしています。
> >
> > [1] レスポンスを取得する
> > [2] レスポンスのDOMを解析する
>
> 以上を意識して再度挑戦しまして、どうにか解消できました。
> 関連する箇所のコードを以下のようにしました。
>
> ' sBody = xh.ResponseText' ←とにかくこれだと文字化け
> sBody = StrConv(xh.ResponseBody, vbUnicode) 'ここを変更した
>
> Dim oHTml As New MSHTML.HTMLDocument
> oHTml.body.innerHTML = sBody '←文字化け解消後のsBodyを左辺に格納
>
> > 各行で行っている作業に対して、日本語でご自身でコメントをつけてみてください。
>
> これも今後行っていこうと思います。
> ありがとうございました。