最近、クローラーを作成する必要が出てきた。
というのは、とある卸業者から商品を購入するのですが、商品の取り扱いリストを貰えたものの、在庫の有無はネットショップで確認してくださいとのこと。
APIサービスもないし、DB情報をサクッとくれることもない。
まさか3,000件を毎月手動で調べるのは馬鹿らしい。
ってことで商品ページを巡回し、情報を獲得するクローラーを作成する事となった。
一般的にはcURLを使用するのでしょうが、そこのネットショップはログイン画面にJavaScriptによるチェックシステムがあり、cURLではその壁を乗り越えられない。
なので他の方法をいろいろ模索し、辿り着いたのが・・・
Microsoft Access(VBA)を使って巡回ツールを作るというもの。
なぜVBAかというと意外と便利で、こういう案件もかなりサクッと作成できるからである。
適当に情報を集め以下のコードでIEをハンドリングし、巡回させることにした。
▼フォームを作成し、以下のコードを書く
Option Compare Database Public objIE As Object 'フォーム内でPublic宣言しておくと使い回しができて便利 '起動ボタンクリック時 Private Sub IEハンドル_Click() Call IE_WAKEUP(objIE) 'IE起動 End Sub '巡回ボタンクリック時 Private Sub 巡回_Click() Dim id As Integer Dim html As String id = 10000 Do While id < 14000 objIE.navigate "http://www.******.com/products/detail.php?product_id=" & id Call IEWait(objIE) html = objIE.Document.body.innerHTML Call 解析(html, id) id = id + 1 Loop End Sub Sub 解析(html As String, id As Integer) '※ここはhtmlソースに対して好きなように記述 '※RegExpの正規表現を使おう。 '※例 Dim re As RegExp Dim mc As MatchCollection Set re = New RegExp html = Replace(html, vbLf, "") '改行コードがうざいので置換 re.Pattern = "<title>(.+?)<\/title>" re.Global = False Set mc = re.Execute(html) If mc.Count > 0 Then タイトル = Trim(mc.Item(0).SubMatches(0)) '※てな具合に抽出し、DBへ登録していけば良い End Sub
▼以下は共通モジュールとして記述
'IE起動 Sub IE_WAKEUP(ByRef objIE As Object) Set objIE = CreateObject("InternetExplorer.Application") objIE.Visible = True objIE.navigate "http://www.**************.com" Call IEWait(objIE) 'IEを待機 End Sub
'IEを待機 Function IEWait(ByRef objIE As Object) Do While objIE.Busy = True Or objIE.readystate <> 4 DoEvents Loop End Function
解説:
[起動ボタン]をクリックし、IEをハンドリングさせている。
その状態でログイン情報を入力してログイン
そして[巡回ボタン]でクロール開始。
とすることで、セッションを維持したまま巡回が可能。
1つ問題点としては描画のためレスポンスが悪い。
少しでもレスポンスを上げるために、JSをOFFったり、画像を読み込ませなかったりすると良い。
とりあえずエラー処理等は省いているので適宜、追加するべし。