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

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

新規登録して質問してみよう
ただいま回答率
85.50%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

3回答

4986閲覧

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

otojiro

総合スコア35

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2017/04/24 01:21

現在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という判定をどのようにしてよいかわからずという状況です。

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/04/24 02:05 編集

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

2017/04/24 02:21

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

回答3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otojiro

2017/04/24 02:04

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

0

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

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

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

投稿2017/04/24 01:26

編集2017/04/24 01:28
s.t.

総合スコア2021

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otojiro

2017/04/24 01: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) サーバーを使用できません'
guest

0

ベストアンサー

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

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

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

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

VB

1’ポイントA 2req = WebRequest.Create(URL) 3 4 5 While True 6 try 7 res = req.GetResponse 'ポイントC 503エラーのときはここで引っかかる。 8 9 Exit While 10 11 Catch ex As Exception 12 '何もしない=次のループが始まる 13 14 End try 15 End While 16 17stream = res.GetResponseStream

投稿2017/04/24 01:42

編集2017/04/24 01:44
akabee

総合スコア1947

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otojiro

2017/04/24 01:54

akabee様 少し前まではAccessを使用しており、現在VB.NETを勉強中で書籍を一通り流し読みした程度で、文法などがACCESS VBAと違うところをネットや書籍で調べて作業を進めておりました。 Try~Catchも書籍では読んで理解はしたつもりでしたが、なかなか実践では出てきませんでした。 回答いただきましたコードをもとに書き直し見事うまく動作してくれました。 今まで条件分岐で回避していたエラーもTryに置き換えられそうな箇所がいろいろありそうです。 本当にありがとうございました。
akabee

2017/04/24 02:06 編集

上手く動いたようでよかったです。 今気づいたのですが、今回のコードのままですと場合によってはサーバーに対し連続でリクエストを発生させてしまい、サーバーへの大きな負荷になる可能性がありそうです。 (そもそも503のレスポンスが返ってくるのはサーバー負荷が高いことが原因であることが多いので、いっそうサーバーへの負荷を高めてしまい、いつまで経っても正常な結果が返ってこず、プログラム自体も上手く動かなくなる可能性も・・・。) 例えばループ時に処理の実行を少し(3~5秒)待つような一文もあるといいのかもしれませんね。 以上、蛇足でした。
otojiro

2017/04/24 02:18

はい、おっしゃる通りです。 ACCESSで同様のアプリケーションを作った際にも2秒待つ処理を入れました。 今回もネットで検索してSystem.Threading.Thread.Sleep(2000)で2秒待つ処理をいたしました。 昨晩から悩んでいた処理が解決できてほっとしております。
退会済みユーザー

退会済みユーザー

2017/04/24 02:29

すでに解決済みのところに横レスするのもなんですが、気になったので一言。 Exception をキャッチするのは止めた方がいいです。理由は以下の記事を見てください。 NETの例外処理 Part.1 https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/ .NETの例外処理 Part.2 https://blogs.msdn.microsoft.com/nakama/2009/01/02/net-part-2/ .NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見てください。 破損状態例外を処理する https://msdn.microsoft.com/ja-jp/magazine/dd419661.aspx Catch するなら WebException 例外のみ、かつ今回問題としている 503 エラーのみとし、それ以外の例外は再スローして処理を中断するのがよさそうです。
otojiro

2017/04/24 07:01

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

退会済みユーザー

2017/04/24 07: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 と出てきますが、それをそのままにすると例外を握りつぶしてなかったことになってしまうので、必ず削除してください。
otojiro

2017/04/24 10:28

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問