今回は調子を見るために早めに12/25あたりから動かし始めている。
このプログラムは初めて年を越すため早速バグ発見。ヤフオクのページ上日付が月日単位しか表示されないので、年データを補完しなければならないということがわかった。
あと1回の巡回に1時間くらいかかっているのでどうしても即決分で取りこぼしが避けられない。
もうちょっと精度を上げるためにもうちょっと巡回間隔を短くしたいが、Excel VBAで作っている以上シングルタスクでしか動作できない。
今日はちょっとひらめいたのでプログラムに手を入れて擬似マルチスレッドにしてみた。
Do For n = 0 To 1 Select Case current_phase(n) Case PHASE_INIT origin_url(n) = objIEs(n).locationurl ready_retry(n) = 0 current_phase(n) = PHASE_NAVIGATE Case PHASE_NAVIGATE navigate_retry(n) = 0 If origin_url(n) = target_url(n) Then objIEs(n).Refresh current_phase(n) = PHASE_NAVIGATED Else objIEs(n).navigate target_url(n) time_out(n) = 1 / 24 / 60 / 60 stt(n) = Now() next_phase(n) = PHASE_CONFIRMNAVIGATED current_phase(n) = PHASE_WAITTIME End If Case PHASE_CONFIRMNAVIGATED stt(n) = Now() current_phase(n) = PHASE_CONFIRMNAVIGATED2 Case PHASE_CONFIRMNAVIGATED2 If Now() - stt(n) > 1 / 24 / 20 Then ' navigate retry navigate_retry(n) = navigate_retry(n) + 1 If navigate_retry(n) < 3 Then current_phase(n) = PHASE_NAVIGATE Else AsyncGetUrlByIE = RESULT_FAILURE Or n current_phase(n) = 0 Exit Function End If Else If objIEs(n).locationurl <> origin_url(n) _ And objIEs(n).locationurl = target_url(n) _ Then current_phase(n) = PHASE_NAVIGATED End If End If Case PHASE_NAVIGATED If Not objIEs(n).busy Then current_phase(n) = PHASE_NAVIGATE_DONE End If Case PHASE_NAVIGATE_DONE stt(n) = Now() current_phase(n) = PHASE_WAIT_READY Case PHASE_WAIT_READY If Now() - stt(n) > 1 / 24 / 60 Then ' navigate retry ready_retry(n) = ready_retry(n) + 1 If ready_retry(n) < 3 Then current_phase(n) = PHASE_NAVIGATE Else AsyncGetUrlByIE = RESULT_FAILURE Or n current_phase(n) = 0 Exit Function End If Else If objIEs(n).readystate >= 2 Then current_phase(n) = PHASE_READY End If End If Case PHASE_READY current_phase(n) = 0 Exit Do Case PHASE_WAITTIME If Now() - stt(n) > time_out(n) Then current_phase(n) = next_phase(n) next_phase(n) = 0 End If Case Else current_phase(n) = PHASE_INIT End Select Next n DoEvents Loop
IEオブジェクトを複数作成して、それぞれnavigateさせれば、各IEオブジェクトはExcel VBAのメインスレッドとは別スレッドで動作するため、少なくともHTMLデータ取得にかかるコストだけはマルチスレッド化することが可能。但し、シリアルなフローにできないのでこんな感じでステートマシンで管理してかないといけないので結構面倒くさい。割り込みをポーリングで管理しなければならないOSにでもなった気分だ。
ただ、HTML取得後のHTMLの解析処理はVBA部分なのでここはシーケンシャルになってしまう。しかし、解析処理を行っている間にもIEオブジェクト側は非同期でページの読み込みを続けられるので、全体の巡回時間はかなり削減できた。
理論上は2スレッド以上でもいけるが、どうやってURLをフィードするかが課題。第1段階としては一般カテゴリとアダルトカテゴリで2スレッド動作がもっとも単純。第2段階はそれぞれ奇数ページと偶数ページにして4スレッド化。これで精度は大分上がるはず。
あとの課題は複数点出品/落札データの取得かなぁ…。取得自体はできるんだけどどうやって管理するかが面倒くさくなりそう。リンク(さらに多く)をもう一階層増やさなければならないのでそれも面倒だな…
データの方は前回の経験からイベント終了後出品傾向が一段楽するまでに10日程度かかるので、1/中旬あたりを目標に集計しようと思う。