みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

VBAでキーワード検索

EXCEL(テキスト可)内に書かれた大量のキーワードを
1ワードずつ自動でGoogle検索し、
1ページ目の検索結果のリンクを1つ1つクリックしていき、
検索結果ページ内に、目的の情報があれば取得し、
EXCEL(テキスト可)に出力するといった操作を
VBAで自動で行いたいと思っています。

EXCEL2010かEXCEL2000に対応していればOKです。
検索するところまでは分かりましたが、検索結果(1ページ目のみ)
のリンクをクリックして、ページ内の目的の情報を取得する
といったところをどう記述すればよいかが分かりません。

検索するところまではこことほぼ同じように書きました。
http://vbaie.blog111.fc2.com/?mode=m&no=6

お分かりになる方、アドバイスのほど、よろしくお願いします。

投稿日時 - 2014-01-02 14:03:43

QNo.8410220

困ってます

質問者が選んだベストアンサー

ちょうど正月休みでJavaScript - DOMのお勉強をしていましたので、試しにやってみました。
当方の環境(Win7Home64bit、IE10、xl2010-32bit)の環境ではお示しのコードは動きませんでした。
ソース(ページの見た目の割にとんでもなくごちゃごちゃしたソースで、自作のWebのTreeをワークシートに書き出すVBAコードを使って解析しました)を見ると、検索窓のIDや、「Google 検索」のタグも変わっている様でした。Googleさんの気分で時々変わるとすると、自力で作成できる様にお勉強していただくしかないと思います。下記で使用したidやclassnameも明日には変わっているかもしれません。
検索結果の最初の1ページ(10件分)のリンク-これも訳の分からない他のリンクが山ほど存在していて、正規表現による取得ではNGと思います-を取得して、5秒ごとにリンク先のページを表示するというところまでやってみました。ここまでで、自分の勉強に戻ります。ご参考まで。

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

'Googleで「VBA」と検索する
Sub GoogleSearch()
Dim objIE As Object
Dim myElements As Object
Dim i As Long
Dim urls() As String

'IE起動
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
'Googleに接続
objIE.navigate "http://www.google.co.jp"
'IEを待機
Call IEWait(objIE)
'検索窓に「VBA」と入力
objIE.document.getElementById("gbqfq").Value = "VBA"
'1秒停止
Sleep 1000
'検索ボタンを押す
objIE.document.getElementById("gbqfb").Click
'IEを待機
Call IEWait(objIE)
Sleep 1000
Set myElements = objIE.document.getElementsByClassName("altcts")
ReDim urls(0 To myElements.Length - 1)
For i = 0 To UBound(urls)
urls(i) = myElements(i).NextSibling.FirstChild.href
Next i
'取得したリンク先を表示する
For i = 0 To UBound(urls)
objIE.navigate urls(i)
Sleep 5000
Next i

'IE終了
' objIE.Quit
' Set objIE = Nothing
End Sub

'IEを待機する関数
Function IEWait(ByRef objIE As Object)
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
End Function

投稿日時 - 2014-01-03 21:33:47

このQ&Aは役に立ちましたか?

5人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

#5です。
getElementsByClassNameはIE9以降しか使えないそうです。
IEも9以降からようやく世間並みになってきている様ですね。とはいっても、VBAからActiveXとして利用するには、他に選択肢はありません。
JavaScriptであれば、IE8以下でgetElementsByClassNameを代替するライブラリが多々あるそうですが、VBAから使うにはそういう訳にもいきません。下記リンクの記事の関数はVBAに載せ替えられそうな気がします。IE8以下しか使えない事情がある場合のご参考まで...
http://t87r.wordpress.com/2011/02/13/getelementsbyclassname%E3%82%AF%E3%83%A9%E3%82%B9%E5%90%8D%E3%82%92ie%E3%81%A7%E4%BD%BF%E3%81%86/

投稿日時 - 2014-01-06 23:43:37

ANo.4

度々すいません。
あくまでも特別な事情があってIEを操作してデータアクセスしたいということで、よろしいでしょうか?
結構遠回りな方法ですので…

投稿日時 - 2014-01-02 15:29:20

補足

特に事情はありませんので、
他に方法がありましたら、他の方法でも構いません。
よろしくお願いいたします。

投稿日時 - 2014-01-02 15:31:32

ANo.3

ソースが必要であれば、補足お願いします。

取り敢えずイメージで回答します。
1階層目の処理は出来たとのことですので省きます。
2階層目では正規表現でページ内のリンクを探し、手当たり次第配列にぶっこみます。
次に配列を呼び出してページをリクエストします。(httprequest)
3階層目では、目的の情報がどういった構造の物か解りかねますので、省きます。

※リンクをクリックするというよりは、目的のURLに対してリクエストし、Html構文を文字列で処理します。
結構メモリ食うはずですので、いらなくなった配列は順次初期化したらいいと思います。

投稿日時 - 2014-01-02 14:55:04

補足

ご回答ありがとうございます。

私にはやや難しいので、下記ソースコードに追記いただきたいです。
(VBAで検索した場合の例)

ひとまず、1ページ目の検索結果の各リンクをクリックし、
現れたページ内にメールアドレスがあればメールアドレスを取得といった操作を
作っていただきたいです。ポイントを記述いただきましたら、
細かいところははしょっていただいて構いません。


’Googleで「VBA」と検索する
Sub GoogleSearch()
Dim objIE As Object

'IE起動
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True

'Googleに接続
objIE.navigate "http://www.google.co.jp"

'IEを待機
Call IEWait(objIE)

'検索窓に「VBA」と入力
objIE.Document.getElementById("q").Value = "VBA"

'5秒停止
Call WaitFor(5)

'検索ボタンを押す
Call IEButtonClick(objIE, "Google 検索")

'5秒停止
Call WaitFor(5)

'IE終了
objIE.Quit

Set objIE = Nothing
End Sub

’ボタンを押す関数
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 For
End If
Next
End Function

'IEを待機する関数
Function IEWait(ByRef objIE As Object)
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
End Function

'指定した秒だけ停止する関数
Function WaitFor(ByVal second As Integer)
Dim futureTime As Date

futureTime = DateAdd("s", second, Now)
While Now < futureTime
DoEvents
Wend
End Function

投稿日時 - 2014-01-02 15:25:03

そこから先はちょっと難しく、Web上にもあまり載っていません。
HTMLの知識とVBAの知識がかなりないと厳しいかと思います。


for each obj in objIE.document.getelementsbytagname("A")
obj.click
next

で全てのAタグをクリックします(この方法ではクリックできないリンクもあります)。


objIE.document.body.innerText

でページ内の文字列全てを取得します。


if instr(objIE.document.body.innerText,"○○")>0 then
 debug.print objIE.document.body.innerText
end if

で、文字列に○○があったら、ページ内の文字列全てを取得します。


あとは、HTMLソースを表示して中を解析し、
objIE.document.getelementbyid("").~
objIE.document.getelementsbyname("").~
objIE.document.getelementsbyclassname("").~
などで必要な部品を動かします。


これらを複合的に利用して記述します。

投稿日時 - 2014-01-02 14:49:18

補足

ご回答ありがとうございます。

確かに難しいですね。組み合わせればできそうではありますが・・・。
検索でもヒントとなるサイトがなかなか見つかりませんでしたし。
だからこのQ&Aで解決できればと思っています。


もし可能でしたら、下記ソースコードに追記いただきますと助かります。
(VBAで検索した場合の例)


’Googleで「VBA」と検索する
Sub GoogleSearch()
Dim objIE As Object

'IE起動
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True

'Googleに接続
objIE.navigate "http://www.google.co.jp"

'IEを待機
Call IEWait(objIE)

'検索窓に「VBA」と入力
objIE.Document.getElementById("q").Value = "VBA"

'5秒停止
Call WaitFor(5)

'検索ボタンを押す
Call IEButtonClick(objIE, "Google 検索")

'5秒停止
Call WaitFor(5)

'IE終了
objIE.Quit

Set objIE = Nothing
End Sub

’ボタンを押す関数
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 For
End If
Next
End Function

'IEを待機する関数
Function IEWait(ByRef objIE As Object)
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
End Function

'指定した秒だけ停止する関数
Function WaitFor(ByVal second As Integer)
Dim futureTime As Date

futureTime = DateAdd("s", second, Now)
While Now < futureTime
DoEvents
Wend
End Function

投稿日時 - 2014-01-02 15:21:34

ANo.1

検索結果からどのように一番目のリンクを取得するかは色々やり方あるとおもいます。
パッと思いつかないですが最初のリンクタグを文字列一致で取得するとか。

あとはそのURLに対してhttpゲットした結果を表示すれば良いかと。

投稿日時 - 2014-01-02 14:40:45

補足

ご回答ありがとうございます。
できれば、下記ソースコードに追記いただくと幸いです。
(VBAで検索した場合の例)

グーグルにアクセスして検索ボタンを押して、
1ページ目を表示するところまではこちらのコードでできますが、
そこから1ページ目の検索結果のリンク(上位10ページ)を
1つ1つクリックして、目的の情報(例:メールアドレス)があるかどうか
(あるなら取得してエクセル等に出力)を確認するところの記述が分かりません。


’Googleで「VBA」と検索する
Sub GoogleSearch()
Dim objIE As Object

'IE起動
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True

'Googleに接続
objIE.navigate "http://www.google.co.jp"

'IEを待機
Call IEWait(objIE)

'検索窓に「VBA」と入力
objIE.Document.getElementById("q").Value = "VBA"

'5秒停止
Call WaitFor(5)

'検索ボタンを押す
Call IEButtonClick(objIE, "Google 検索")

'5秒停止
Call WaitFor(5)

'IE終了
objIE.Quit

Set objIE = Nothing
End Sub

’ボタンを押す関数
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 For
End If
Next
End Function

'IEを待機する関数
Function IEWait(ByRef objIE As Object)
Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Loop
End Function

'指定した秒だけ停止する関数
Function WaitFor(ByVal second As Integer)
Dim futureTime As Date

futureTime = DateAdd("s", second, Now)
While Now < futureTime
DoEvents
Wend
End Function

投稿日時 - 2014-01-02 14:52:55

あなたにオススメの質問