今回は調子を見るために早めに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/中旬あたりを目標に集計しようと思う。