質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

VB.NET Web上のXML取得時の503エラーの回避

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,791

otojiro

score 23

現在Visual Studio 2015(VB)にてアプリケーションを作っており(自己使用目的)、その中でWEB上のXMLデータを取得しフォーム上のDataGridに入力しデータベースを更新しております。

上記一連の取得、データベース更新は動作しております。

ただ、WEB上のXMLデータ取得時に時折レスポンスとして503エラーが表示される場合があり、その場合は当然取得したいデータ項目もないわけでエラーとなります。

サイドXMLデータがあるURLにアクセスすると表示される場合があるので、503エラーの場合はもう一度リクエストをかけて取得するというプログラムにしたいのですが、上手くいきません。

現状はネット上で参考になるページを探してつぎはぎしたものですが、Form上のデータ取得用のボタンをクリックで、DateGridViewのカレント行のURL情報をもとにXMLデータのあるURLにアクセスし、指定の項目タグ内のテキストを取得。
その後同じカレント行のCells(1)に取得したデータを入力という流れです。

以下現状のコードです。
~ボタンクリック時~
Dim URL As String
Dim req As HttpWebReques
Dim res As WebResponse 
Dim stream As Stream
Dim streamReader As StreamReader
Dim xmlDoc As Xml.XmlDocument
Dim xmlStr As String
Dim dGrid As DataGridView

dGrid = Tbl_ItemDataGridView

’ポイントA
req = WebRequest.Create(URL)
res = req.GetResponse 'ポイントC 503エラーのときはここで引っかかる。
stream = res.GetResponseStream
xmlStr = streamReader.ReadToEnd()
xmlDoc = New XmlDocument()
xmlDoc.LoadXml(xmlStr)

'DateGridに入力(実際には10項目くらい取得しております)
dGrid.CurrentRow.Cells(1).Value=xmlDoc.Item("DATA").InnerText

'ポイントB

streamReader.Close()
stream.Close()
res.Close()


当初ポイントBのあたりで、xmlDoc.Item("DATA").InnerText の値がない場合(503エラー)にポイントAまで戻すようなループを考えていたのですが、そもそも503エラーのときはポイントCで引っかかるので、req.GetResponseが503という判定をどのようにしてよいかわからずという状況です。

宜しくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/04/24 11:04 編集

    自動アクセスしてデータを取得するのが目的のようですが、アクセスする Web サイトの管理者の方に許可は得ているのでしょうか? HTTP Status 503 (Server Too Busy) は Web サーバーが受け付けられる要求数を超えた要求があった場合のエラーメッセージですが、そういう状況の時ループで何度も要求を出すというのは問題がありそうです

    キャンセル

  • otojiro

    2017/04/24 11:21

    もちろんです。ただ、XML取得、API取得用のアカウントを得た正式なサービスですので問題はないと思います。ループに関しましても503エラーの際は既定の間隔をあけてリロードするという規定も守っております。今回の質問内容は解決することができましたが、ご意見参考にさせていただきます。

    キャンセル

回答 3

+1

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/24 11:04

    ご回答ありがとうございます。
    HttpStatusCode
    というものがあるのですね、エラーコード別に処理をしたいなどの場合に参考にさせていただきます。
    ありがとうございました。

    キャンセル

checkベストアンサー

0

try構文はご存知ですか?
「なにかエラーになった」ということを捕捉してくれるようなものと考えて下さい。
実際にはエラーが発生した瞬間にCatch文に飛びます。

自己使用のPGということであまり凝る必要もなさそうですし、以下のような感じでどうでしょうか。

何かエラーが発生したらwhile文を繰り返すようなコードです。
エラーが発生しなければExit Whileでループを抜けます。

すみません、下記コードで実際に動くかどうかは自信がありませんが参考になれば。。
VBではないようですが同様のロジックはこちらにも記載されています。

’ポイントA 
req = WebRequest.Create(URL) 


  While True
    try
      res = req.GetResponse 'ポイントC 503エラーのときはここで引っかかる。 

      Exit While

    Catch ex As Exception
        '何もしない=次のループが始まる

    End try
  End While

stream = res.GetResponseStream 

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/24 16:01

    SurferOnWww様
    ご回答ありがとうございます。
    ちなみに503のエラー判定ですが、Try catch で判定する場合、どのようなプログラムになるのでしょうか?何かアドバイスがございましたらご教授いただけますでしょうか?

    キャンセル

  • 2017/04/24 16:41

    紹介した記事の Part.2 の方の「Step 3. 間違って拾ってしまった SqlException への対処」のようにしてはいかがですか? 

    記事は SqlException をキャッチして PK 制約違反以外の場合は再スローしていますが、その応用で、質問者さんのケースでは WebException をキャッチして 503 エラーなら少し間を開けて再試行、503 エラー以外は再スローするという感じです。

    WebException をキャッチする方法や Status Code の取得方法は MSDN ライブラリの「WebException.Status プロパティ」の説明にサンプルコードがありますのでそれを見てください。

    https://msdn.microsoft.com/ja-jp/library/system.net.webexception.status(v=vs.110).aspx

    サンプルコードは Exception をキャッチしてますが、そこはマネしないようにしてください。

    また、VB.NET ですと、Visual Studio のエディタで Try とタイプすると Catch ex As Exception と出てきますが、それをそのままにすると例外を握りつぶしてなかったことになってしまうので、必ず削除してください。

    キャンセル

  • 2017/04/24 19:28

    わかりました、大変参考になりました。
    ベストアンサーは締め切ってしまいましたが、ありがとうございます。

    キャンセル

0

ポイントCでif、elseでreqの状態を見ればよいのではないでしょうか?

If (req IsNot Nothing) Then
  ' 正常
Else
  ' 取得しなおし
End If

VBやったことないので、書き方がおかしいかもしれませんが、、、

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/24 10:41

    ご回答ありがとうございます。
    質問文のポイントAの後を以下のように書き換えてみました.
    IfではなくDo Loopで対応してみました。
    503エラーの際は同じくプログラムが止まってしまします。

    Do
    req = WebRequest.Create(sURL)
    Loop Until req IsNot Nothing

    res = req.GetResponse 'ポイントC
    stream = res.GetResponseStream
    streamReader = New StreamReader(stream)
    xmlStr = streamReader.ReadToEnd()

    xmlDoc = New XmlDocument()
    xmlDoc.LoadXml(xmlStr)

    'DateGridに入力(実際には10項目くらい取得しております)
    dGrid.CurrentRow.Cells(1).Value=xmlDoc.Item("DATA").InnerText


    やはり503エラーの際はポイントCのところでエラーが出てしまいます。
    エラーは
    System.Net.WebException: 'リモート サーバーがエラーを返しました: (503) サーバーを使用できません'

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる