e-learningサイトの操作
未読分:13件
昨日以降(0) 2日前以降(0) 3日前以降(0) 4日前以降(0) 5日前以降(0)
近田 伸矢, 植木 悠二, 上田 寛
IEのデータ収集&自動操作のプログラミング本はこの1冊だけ!IEの起動やポップアップウィンドウ、表示を制御する基本的なコードはもちろん、テキストボックスやラジオボタン、表、ハイパーリンクなどのHTML部品を制御する方法など、自動操作に欠かせないノウハウを丁寧に解説。
Message#13 2015年2月14日(土)08時40分 From: VBAマスター | 返事 削除 変更 |
手動でやっても3分、5分かかるようなサイトですか? そうだったサイト自体異常ですけどね(笑) 逆にサーバー負荷による遅延なら先方が解決する問題なのでこちら側からはどうしようもないです。 JavaScriptが絡むとややこしいですが、とりあえず >。二回目のボタンの方は、対象はなく、またURLはボタンを押す前のものでした。 ってことだったんで、対象が現れるまでループさせといて対象が現れたらループを抜ける処理をいれるとうまくいくかもしれません。 これで無理ならjavascriptそのものをどうにか操作させるしかないですね。 'ボタンが現れるまでループ処理させる Do While instr(objIE.document.body.outerHTML,"対象のボタン名") = 0 DoEvents Loop 'ボタンが現れたらクリック処理を入れる For Each objInput In objIE.document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click Exit Function End If Next javascript操作は以下で解説されていますが、ここはjavascriptの動作を確認しないといけないので、敷居は高いかと思います。 http://www.vba-ie.net/ie/javascript.html |
Message#12 2015年2月12日(木)09時43分 From: icycyi | 返事 削除 変更 |
VBAマスターさん、見捨てず返信してくださって、本当にありがとうございます。 最初はWaitメソッドを使用していたのですが、ここでのJavaScriptの作業がややこしく、サーバーの状況、リクエストの数などの関係で、5秒から3分、長い時は5分かかると、大変時間差のある作業となっています。なのでボタンを認識するのがベストと判断しました。 また以前はMsgBoxを使用して、ページの読み込みが終わってからボタンを押すという形にすれば、うまくはいってたのですが、何百件の作業となるので、ボタンを押すだけの作業なのに自動化している意味がないと感じ、何か方法はないか思案している次第です。ちなみにその時のコードはEです。 Eの時は大丈夫で、Fの時は大丈夫じゃない意味がわからないのですが・・・ 取り敢えず待機処理ではなく、他の処理でなんとかしようと思うのですが、ページ内にボタンがあるかどうか判別させるようなことは、できるのでしょうか。ご返答よろしくおねがいします。 E Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) Dim objInput As Object MsgBox buttonValue & "OK?" For Each objInput In objIE.document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click Exit Function End If Next F Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) Dim objInput As Object Do While b_ch=false For Each objInput In objIE.document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click b_ch=True Exit Function End If Next Loop |
Message#11 2015年2月10日(火)22時25分 From: VBAマスター | 返事 削除 変更 |
> HTMLソースの中に、処理対象があるかどうか、またその際のページのURLも書き出すようにしました。 > 結果は一回目のボタンの方は、当然ですが対象はあり、URLはこちらの思っている通りでした。二回目のボタンの方は、対象はなく、またURLはボタンを押す前のものでした。 JavaScriptの場合は、VBAの処理待ちは効かないので、単純にAPIのSleep関数を利用して数秒処理を停止させるか、Waitメソッドを利用して処理をとめるかするとよいと思いますよ。 【Sleep関数の場合】 Sleep 5000 ※API宣言が必要です。 【Waitメソッドの場合】 Dim waitTime As Variant waitTime = Now + TimeValue("0:00:05") Application.Wait waitTime この処理の停止する時間については実際に処理してみて正常に動作するところを決めたらよいと思います。 |
Message#10 2015年2月10日(火)13時17分 From: icycyi | 返事 削除 変更 |
なお必要と思われるVBAコードです。返り値がなくともFunctionをつかってるのは気にしないで下さい。 <略> objIE.navigate "一つ目のボタンがあるページ" Call IEwait(objIE) ’一つ目のボタン Call IEButtonClick(objIE, "一つ目のボタン") Call IEwait(objIE) Call IEButtonClick(objIE, "二つ目のボタン") Call IEwait(objIE) r_name = objIE.Document.getElementById("id_name").Value <略> Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) Dim objInput As Object kiroku2 = objIE.Document.all(0).innerHTML If InStr(1, kiroku2, buttonValue) > 0 Then Sheets("sheet2").Cells(l, 1) = "O" Sheets("sheet2").Cells(l, 2) = objIE.LocationURL Sheets("sheet2").Cells(l, 3) = objIE.Document.URL Else Sheets("sheet2").Cells(l, 1) = "X" Sheets("sheet2").Cells(l, 2) = objIE.LocationURL Sheets("sheet2").Cells(l, 3) = objIE.Document.URL End If l = l + 1 b_ch = False Do While b_ch = False For Each objInput In objIE.Document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click Exit Function End If Next Loop End Function Function IEwait(ByRef objIE As Object) Do While objIE.ReadyState <> 4 DoEvents Loop End Function |
Message#9 2015年2月10日(火)13時07分 From: icycyi | 返事 削除 変更 |
VBAマスターさん、返信ありがとうございました。 フレームはないので、JavaScriptが原因かと思われます。 返信頂いたところから色々と試してみました。 Dのコードを以下の様にしました。 Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) Dim objInput As Object kiroku2 = objIE.Document.all(0).innerHTML If InStr(1, kiroku2, buttonValue) > 0 Then Sheets("sheet2").Cells(l, 1) = "O" Sheets("sheet2").Cells(l, 2) = objIE.LocationURL Sheets("sheet2").Cells(l, 3) = objIE.Document.URL Else Sheets("sheet2").Cells(l, 1) = "X" Sheets("sheet2").Cells(l, 2) = objIE.LocationURL Sheets("sheet2").Cells(l, 3) = objIE.Document.URL End If l = l + 1 b_ch = False Do While b_ch = False For Each objInput In objIE.Document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click b_ch=True Exit Function End If Next Loop End Function HTMLソースの中に、処理対象があるかどうか、またその際のページのURLも書き出すようにしました。 結果は一回目のボタンの方は、当然ですが対象はあり、URLはこちらの思っている通りでした。二回目のボタンの方は、対象はなく、またURLはボタンを押す前のものでした。 一回目のボタンをおしてから少し経てばページは変わるので、 Function 待て() Do While objIE.LocationURL <> "指定のアドレス" Call IEwait(objIE) Loop End Function と組んだのですが、IEの表示がこちらの指定のアドレスになっているのに、Loopから抜けだせませんでした。 聞きまくりな感じですが、ご教授お願いします。 |
Message#8 2015年2月10日(火)01時25分 From: VBAマスター | 返事 削除 変更 |
サイトの構成が分かりませんが、VBAのIE制御で読み込みができない場合の多くはJavaScriptを利用している場合ですね。 あとは、フレームを利用している場合は、通常クリック処理がうまくいかない場合があります。 まずは、 変数 = objIE.document.all(0).outerHTML とかでまずどの範囲を取得しているのか確認してみてください。 取得したHTMLソース内にクリック処理ができる項目がなければいくら処理してもクリックされません。 フレームの場合はフレーム内のHTMLドキュメントを取得しなければいけないので、その処理が必要です。 待機処理も1回目はうまくいって次の処理でうまくいかないのであれば、JavaScriptあるいPHPの何かしらの処理でうまくいかないのかもしれません。 あとどのようなVBAコードを書いているか具体的に提示すると回答しやすいかと思います。 |
Message#7 2015年2月9日(月)19時03分 From: icycyi | 返事 削除 変更 |
またひとりで盛り上がっていると言われるかもしれませんが、状況整理と追加情報ということでまとめます。 どういったコードを書いているかというと、 (ここでの頭の数字は今までのものとは別です、丸の付いている数字は今までのものです) 1.指定のページを開く 2.読み込みを持つA 3.そのページにあるボタンを押す、次のページにいくD 4.読み込みを待つA 5.そのページにあるボタンを押す、次のページにいくD 6.読み込みを待つA 7.文章を入力 といった流れです。 1〜3まではうまくいくのですが、4のページの読み込みがうまく行かず、5のボタンを押そうとして見つからず、6、7といき、文章入力がうまく行かずエラーがでます。Dにボタンを押さないと抜け出せないようにすると、そこから抜けだせません。 4と5の問題だということはわかりました。 3はEーLearningの小テストをコピーするという時間が少しかかる作業で、4の待機処理がうまくいってないのだと思います。その不完全な状態で5のボタンを探そうとするから見つからないのだと思います。 ここでの疑問なのですが、5のボタンを探し続けてたら、いずれ開いて見つかるはずなのに、見つからない。もう一度ページを取得し直すようなことをすればいいと思うのですが、どう書けばいいでしょうか? ご教授お願いします。 |
Message#6 2015年2月9日(月)16時07分 From: icycyi | 返事 削除 変更 |
一人劇にみたいになってましたが、返信ありがとうございます。 確かにFunctionでなくともかまわなかったですね。 さて、問題のところですが、熟読させてもらい、いろいろと試しましたが、やはり待機処理でつまづきます。まだページが読み込まれていないのに、BusyプロパティではTrueを返し、InternetExplorerオブジェクトのReadyStateプロパティでは4を返し、DocumentオブジェクトのReadyStateプロパティでは"complete"を返します。 もうどうすれば・・・ |
Message#5 2015年2月8日(日)00時18分 From: VBAマスター | 返事 削除 変更 |
この質問みんな熱く語ってるなーと思ったら同じ人だったんですね(笑) とりあえず1つつっこませてもらうと > A > Function IEwait(ByRef objIE As Object) > Do While objIE.readystate <> 4 > DoEvents > Loop > End Function > > D > Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) > Dim objInput As Object > For Each objInput In objIE.document.getElementsByTagName("INPUT") > If objInput.Value = buttonValue Then > objInput.Click > Exit Function > End If > Next > > End Function ここってFunctionプロシージャにする必要ないですね。 というのも戻り値の設定もないですし。 あと今回問題になっているのがボタンクリック時の読み込みまでの待機処理になりますが、下記が結構まとまっているので一度読んでみたらどうですか? 長いんで疲れますけど、かなり待機処理について詳しく書いているので参考になると思います。 http://www.vba-ie.net/ie/subroutine2.html |
Message#4 2015年2月7日(土)18時58分 From: icyci | 返事 削除 変更 |
すいませでん、先ほど書き換えたのは、Dでした。 またさらにDのコードに書き加えました。 Dのコードは最初のままで、その前にDoWhileLoopを持ってきました。 結果は下のDoWhileLoopから出れないという書き換えた時と同じでした。 やっぱり中断している時の「objInput」の中身は、"[object HTMLInputElement]"となっています。 dim b_ch as boolan Function b_check(ByRef objIE As Object, b_name As String) b_ch = False Do While b_ch = False Call IEButtonClick(objIE, b_name)'Dのコードに行く Loop End Function |
Message#3 2015年2月7日(土)16時18分 From: icycyi | 返事 削除 変更 |
Aのコードを書き換えてみました。 下記の様に組んだのですが、Do While Loopの中で回り続けてしまいます。 ボタンを押したつもりではなく、ボタンが見つけられない状況でした。 中断した際、IEのウィンドウ内に指定のボタンは存在していて、中断から再度走らせても、やはりDo While Loopから抜けだせません。 中断している時の「objInput」の中身は、"[object HTMLInputElement]"となっています。 再度ページをVBAに読み込ませるみたいなことで解決できるのではないかと思うのですが、VBAをかじった程度の知識なので、やり方がわかりません。ご教授お願いします。 ご協力宜しくお願いします。 Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) Dim objInput As Object Dim b_ch As Boolean b_ch = False Do While b_ch = False For Each objInput In objIE.Document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click b_ch = True Exit Function End If Next Loop End Function |
Message#2 2015年2月7日(土)12時22分 From: icycyi | 返事 削除 変更 |
コードを書き忘れてました・・・ご協力お願いします。 A Function IEwait(ByRef objIE As Object) Do While objIE.readystate <> 4 DoEvents Loop End Function C Do Until objIE.Busy = False WScript.sleep(250) Loop' D Public Function IEButtonClick(ByRef objIE As Object, buttonValue As String) Dim objInput As Object For Each objInput In objIE.document.getElementsByTagName("INPUT") If objInput.Value = buttonValue Then objInput.Click Exit Function End If Next End Function |
Message#1 2015年2月7日(土)12時20分 From: icycyi | 返事 削除 変更 |
VBAでIEを操作し、PHPで開発されているMoodleというe-learningサイトを操作しようと思っています。 概ね自分の思い通りに動くように作れたのですが、一点だけ問題が発生してしまいました。 @Submitのボタンを押して、A2ページ目の読み込み待ち、B2ページ目のSubmitのボタンを押して3ページ目に行き、次の作業にいく、といった行程がうまく行きません。 エラーが出るのが、Bのボタンを押したつもりになって、3ページ目の作業に行ってしまっていました。 Aの読み込み待ちがうまく行かず、Bのボタンを押したつもりになってしまい、次の作業でエラーを起こす、そんな次第です。 Aのページの読み込みは下記の様に組んでます。 Cの様に組んでも結果は一緒でした。 あとページが変わるまで、ボタンを押し続ける様に組むと、サーバーが落ちました。(ボタンが無くても押していることができるということだったので、試してみました。コードは残していなかった。) ちなみにボタンを押すコードはDです。 PHPの読み込みを待っていないとかそんな原因ではないかと思うのですが、解決できないでしょうか。 |
昨日以降 2日前以降 3日前以降 4日前以降 5日前以降