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

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

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

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

1回答

2855閲覧

VBAにてウェブサイトのテーブルの内容を取得したい

unotalk

総合スコア124

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

1クリップ

投稿2019/02/21 16:02

編集2019/02/25 09:21

VBAで当ECサイトの商品の情報を取得したいと思っています。
商品はhttps://example.com?id=1のようにidで管理されています。
ただし、販売中止などにより中には404ページになるidも含まれております。

商品の情報はtableタグ内に存在しており、th,tdタグ内の情報をエクセルに移したいと考えています。

そこで以下のようにVBAを作成したのですが、1つ目の商品の処理が終わるとIEが「動作を停止しました」というエラーがでて2つ目以降の商品情報をとることができません。
デバックすると
objIE.navigate "http://example.com?id=" & j
の箇所が黄色くなっています。

商品数はとりあえず5としています。

初歩的なところで間違えているかもしれませんが、あれこれ試しても一向に解決しないため質問させていただきました。
お手数ですがどなたかご回答いただけますでしょうか。

VBA

1Sub product() 2 Dim i As Long 3 Dim j As Long 4 5 Dim objITEM As Object 6 Dim objIE As New InternetExplorer 7 objIE.Visible = True 8 9 For j = 1 To 5 10 objIE.navigate "http://example.com?id=" & j 11 Call untilReady(objIE) 12 13 Range("A1").CurrentRegion.Offset(1, 0).ClearContents 14 i = 2 15 For Each objITEM In objIE.document.querySelectorAll("th, td") 16 Cells(i, j) = objITEM.innerText 17 i = i + 1 18 Next 19 Next 20 objIE.Quit 21 Set objITEM = Nothing 22 Set objIE = Nothing 23End Sub 24 25Sub untilReady(objIE As Object, Optional ByVal WaitTime As Integer = 10) 26 Dim starttime As Date 27 starttime = Now() 28 Do While objIE.Busy = True Or objIE.readyState <> READYSTATE_COMPLETE 29 DoEvents 30 If Now() > DateAdd("S", WaitTime, starttime) Then 31 Exit Do 32 End If 33 Loop 34 DoEvents 35End Sub

試したこと
1.WaitTimeを10から1000に変更→結果、変化なし

VBA

1Sub untilReady(objIE As Object, Optional ByVal WaitTime As Integer = 1000)

2.UntilReadyを削除し、Sleepを使用→結果、変化なし

VBA

1Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) 2 3Sub maker() 4 Dim i As Long 5 Dim j As Long 6 7 Dim objITEM As Object 8 Dim objIE As New InternetExplorer 9 objIE.Visible = True 10 11 For j = 1 To 5 12 objIE.navigate "http://example.com?id=" & j 13 Sleep 1000 14 Range("A1").CurrentRegion.Offset(1, 0).ClearContents 15 i = 2 16 For Each objITEM In objIE.document.querySelectorAll("th, td") 17 Cells(i, j) = objITEM.innerText 18 i = i + 1 19 Next 20 Next 21 objIE.Quit 22 Set objITEM = Nothing 23 Set objIE = Nothing 24End Sub

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

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

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

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

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

m.ts10806

2019/02/22 01:16

多重起動の線が怪しそうです。 forで回さず、1つだけだとどうでしょうか。
m.ts10806

2019/02/22 01:17

あとはSleepを試してみてください。
unotalk

2019/02/25 09:22

ありがとうございます。 頂いたアドバイスを試してみました。 ・1つめのforを削除して、j=1で固定してみましたが、以下の結果でした。 結果: IEは問題が発生したため終了しました→プログラムの終了→このWebページに問題があるためIEのタブを開き直しました。 ・Sleepの実行 以下のコードを1行目に追記 Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) 以下のコードをSleep 20000 と入れ替え Call untilReady(objIE) 結果、上記と同じくIEの動作は停止しましたとなります。 他に、untilReadyのwaitTimeを1000に変更しましたが、同じでした。。
guest

回答1

0

untilReadyで完全に読み込みが終わっていないのに終了している可能性はないでしょうか?
(まだ途中なのにIEに次の要求が来てしまっておかしくなっている)
今の作りだとタイムアウトの10秒が過ぎると読み込みが終わっていなくても関数を抜けてしまうと思います。
試しにタイムアウトをなしにするか、時間を長く設定してみてはいかがでしょうか。

投稿2019/02/22 01:43

ttyp03

総合スコア16998

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

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

unotalk

2019/02/25 09:39

ttyp03さん ありがとうございます。タイムアウトを1000秒まで伸ばしてみましたが、残念ながら同じ結果でした。
ttyp03

2019/02/25 09:41

1000秒まで達しているのでしょうか? その前にループを抜けてますか? 1000秒まで達しているなら更に伸ばしてみる必要はあるかと思いますし、達していないなら別の要因になるので、現象を切り分けるためにも確認してみてください。
unotalk

2019/02/26 00:18

1000秒まで達しているということはないと思います。1000秒たつ前にエラーが発生しているので。。
unotalk

2019/02/26 00:18

TanakaHiroakiさん ありがとうございます!試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問