プルダウンメニューで選択して「検索」すると結果を表示するようなタイプのホームページで、

検索結果内容を上手く自動取得する方法があればアドバイスをお願い致します。


http://www.journey-k.com/
例えばこのページは、プルダウンが2つあり、1つは都道府県、もう1つはカテゴリーを選択
するものです。両者を選択して「検索」ボタンを押すと、結果が表示されます。
※自由記入欄は無視して下さい。

このページに限っていうと、都道府県が47で、カテゴリーが10あるので、470パターンの検索結果
があることになります。全てを取得しようとすると手動ではたいへんです。なんとか自動取得
できないでしょうか?

取得結果はhtml形式もしくはtext形式で上手く残ってくれるといいなと思っています。
1ページ1ファイルでOKです!

上手いツールがあるとか、プログラム方法(ExcelのVBAだと嬉しい)があるとか、助言を
どうぞよろしくお願い致します。

※複数のサイトで自動取得したいので、上記サイトだけしか使えないんじゃなくて、多少汎用性
 があるといいです。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2009/10/07 16:24:53
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:maruyama2 No.1

回答回数4ベストアンサー獲得回数1

ポイント500pt

'ホームページの中の、

'プルダウンの読み取り

'

'マクロには、ここから必要です

'URLDownloadToFile を利用できるようにします

Private Declare Function URLDownloadToFile Lib _

"urlmon" Alias "URLDownloadToFileA" _

(ByVal pCaller As Long, ByVal szURL As String, _

ByVal szFileName As String, ByVal dwReserved As Long, _

ByVal lpfnCB As Long) As Long

Sub aホームページプルダウンの読み取り()

'URLDownloadToFile で「読み取りした.htm」に保存します

'ホームページfile名を準備します

  homepagefilename = "http://www.journey-k.com/index.htm"

Range("A1").Value = homepagefilename

returnValue = URLDownloadToFile _

(0, homepagefilename, ThisWorkbook.Path & "\読み取りした.htm", 0, 0)

'IEを起動して、ホームページfileを表示します

Set objIE = CreateObject("InternetExplorer.application")

objIE.Visible = True

objIE.Navigate homepagefilename

MsgBox "ホームページが表示したら、OKをクリック", , "エラー防止 待ちます"

'MsgBoxは、ホームページの裏に、隠れている時があります

'ホームページの、SELECTタグ毎にOPTIONタグを抜き出します

For Each objSELECT In objIE.Document.all.tags("SELECT")

行 = 2

列 = 列 + 2

Cells(行, 列).Value = objSELECT.Name

行 = 行 + 1

'OPTIONタグのValueとテキストを抜き出します

For Each objOPTION In objSELECT.all.tags("OPTION")

Cells(行, 列).Value = objOPTION.Value

Cells(行, 列 + 1).Value = objOPTION.innertext

行 = 行 + 1

Next objOPTION

Next objSELECT

Set objIE = Nothing

End Sub

'この後、組み合わせを行います

id:miku1973

ありがとうございます!

素晴らしいです!

いくつか質問とか追加要望とかありますがよろしいでしょうか・・・。(ポイントははずみます!)

下のコメント欄に書きますね!

2009/10/04 08:29:01
  • id:miku1973
    MsgBox "ホームページが表示したら、OKをクリック", , "エラー防止 待ちます"
     
    この処理は非常に嬉しいのですが、ここが手動になってしまうのもいまいちでして、例えば
    「60秒待ってもHPが表示されなかったら無視」
    みたいな処理ができると嬉しいです。
  • id:miku1973
    あと、ごめんなさい。
    html形式で保存されるようになっていますが、
    ・text形式で。(ホームページのテキスト部分の取得だけでもOKなんです)
    ・ファイル名は、例えば検索結果が470個あるなら、1.txtから470.txtで吐き出されるように。
    ・このtextファイルの保存場所は、デスクトップではなく特定のフォルダに。
     (デスクトップがファイルだらけになってしまいそうなので・・・)
     
    みたいにできると嬉しいです。
  • id:maruyama2
    '待ち時間 = 60 '秒
    'Sub b組み合わせ()
    'Sub cファイルに書き出し()
    '汎用性が無いですが、ご参考にしてください。
    'ファイルが801個出来ますので、
    'フォルダを作り、中に、test.xlsを作成し、その中にマクロを入れてみてください
    'Sub aホームページプルダウンの読み取り() を実行すると、
    '続けてSub b組み合わせ()'Sub cファイルに書き出し()も実行します。
    '
    'ホームページの中の、
    'プルダウンの読み取り
    '
    'マクロには、ここから必要
    'URLDownloadToFile を利用できるようにする
    Private Declare Function URLDownloadToFile Lib _
    "urlmon" Alias "URLDownloadToFileA" _
    (ByVal pCaller As Long, ByVal szURL As String, _
    ByVal szFileName As String, ByVal dwReserved As Long, _
    ByVal lpfnCB As Long) As Long
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sub aホームページプルダウンの読み取り()
    'URLDownloadToFile で「読み取りした.htm」に保存します
    'ホームページfile名を準備します
    homepagefilename = "http://www.journey-k.com/index.htm"
    Range("A1").Value = homepagefilename
    Range("A2").Value = ""
    returnValue = URLDownloadToFile _
    (0, homepagefilename, ThisWorkbook.Path & "\読み取りした.htm", 0, 0)
    '
    'IEを起動して、ホームページfileを表示します
    Set objIE = CreateObject("InternetExplorer.application")
    objIE.Visible = True
    objIE.Navigate homepagefilename
    '
    待ち時間 = 60 '秒
    'Busyとreadystateをチェックしながら、待ちます
    Do While (objIE.Busy Or Not (objIE.readystate = 4))
    'Sleepは、これが必要、
    'Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sleep 1000
    wcount = wcount + 1
    If wcount > 待ち時間 Then
    Set objIE = Nothing
    Range("A2").Value = "ホームページ見れませんでした"
    Exit Sub
    End If
    Loop
    '以上が上手く動作しない時は、
    'この下の1行をコメントではなく、有効にしてみてください。
    'MsgBox "ホームページが表示したら、OKをクリック", , "エラー防止 待ちます"
    '    MsgBoxは、ホームページの裏に、隠れている時があります
    '
    'ホームページのBodyのTextを抜き出します
    Open ThisWorkbook.Path & "\読み取りしたTEXT.txt" For Output As #1
    Print #1, objIE.Document.body.innerText
    Close #1
    '
    'ホームページの、SELECTタグ毎にOPTIONタグを抜き出します
    For Each objSELECT In objIE.Document.all.tags("SELECT")
    行 = 2
    列 = 列 + 2
    SELECTの数 = SELECTの数 + 1
    Cells(行, 列).Value = objSELECT.Name
    行 = 行 + 1
    '
    'OPTIONタグのValueとテキストを抜き出します
    For Each objOPTION In objSELECT.all.tags("OPTION")
    Cells(行, 列).Value = objOPTION.Value
    Cells(行, 列 + 1).Value = objOPTION.innerText
    行 = 行 + 1
    Cells(2, 列 + 1).Value = 行 - 4 '4行目からのデータの数
    Next objOPTION
    Next objSELECT
    '
    Set objIE = Nothing
    '
    Call b組み合わせ
    End Sub
    'この後、組み合わせを行います
    '
    Sub b組み合わせ()
    'この部分は、汎用性が無いですが、ご参考にしてください。
    列 = "C"
    繰り返し数 = 1
    データ数 = Cells(2, "C").Value
    セルのコピー数 = Cells(2, "E").Value
    n = 1
    For l = 1 To 繰り返し数
    For d = 1 To データ数
    For c = 1 To セルのコピー数
    Cells(n, "G").Value = n
    Cells(n, "H").Value = Cells(d + 3, "C").Value
    n = n + 1
    Next
    Next
    Next
    '
    列 = "E"
    繰り返し数 = Cells(2, "C").Value
    データ数 = Cells(2, "E").Value
    セルのコピー数 = 1
    n = 1
    For l = 1 To 繰り返し数
    For d = 1 To データ数
    For c = 1 To セルのコピー数
    Cells(n, "I").Value = Cells(d + 3, "E").Value
    n = n + 1
    Next
    Next
    Next
    '
    Call cファイルに書き出し
    End Sub
    'この後、ファイルに書き出します
    '
    Sub cファイルに書き出し()
    'この部分は、汎用性が無いですが、ご参考にしてください。
    '
    Cells(1, "G").Select
    ファイル名 = Cells(1, "G").Value
    特定のフォルダ名 = ThisWorkbook.Path
    Do While ファイル名 <> ""
    Open 特定のフォルダ名 & "\" & ファイル名 & ".txt" For Output As #1
    Print #1, ActiveCell.Offset(0, 1).Value & "," & ActiveCell.Offset(0, 2).Value
    Close #1
    ActiveCell.Offset(1, 0).Select
    ファイル名 = ActiveCell.Value
    Loop
    '
    Cells(1, "G").Select
    MsgBox "ファイルに書き出しました", , "マクロ処理終了"
    '
    End Sub
  • id:miku1973
    ありがとう。
    ごめんなさい、追加で質問させてください!!
     
    各801個のファイルの中身なんですが、どうもどれも検索キーワードが表示されてしまっているようです。
     
    例えば、796.text を見ると、
    沖縄県,ホームページ作成
    となっていました。違う~!
     
    実は、取得したいのは、「検索キーワード」ではなくて、「検索結果のページまるまる」なんです。
     
    なので、ちょっと違いました・・・。
    あと、もう一発上手く直せないでしょうか?
     
     
    VBAの記述の中身は、私も自分で勉強して、改良できるようにしたいと思っています。ありがとう!
  • id:maruyama2
    '改良できる、参考になると良いですね。
    '以下、ご参考に、して下さい。
    'Sub dキーワードで検索してファイルに書き出()
    'を入れました。
    長いコメントですが、今までの全てのマクロをまとめて以下に入れました。
    '
    '汎用性が無いですが、ご参考にしてください。
    'Sub aホームページプルダウンの読み取り()
    'Sub b組み合わせ()
    'Sub cファイルに書き出し()
    'Sub dキーワードで検索してファイルに書き出()
    'これは、Sub a b cを行い、列G,H,Iにデータが必要です。
    'ホームページを800回くらい見に行くので時間がかかります。
    '初めは、何行目まで行うか、少ない数で様子を見てください。
    '
    'ホームページの中の、
    'プルダウンの読み取り
    '
    'マクロには、ここから必要
    'URLDownloadToFile を利用できるようにする
    Private Declare Function URLDownloadToFile Lib _
    "urlmon" Alias "URLDownloadToFileA" _
    (ByVal pCaller As Long, ByVal szURL As String, _
    ByVal szFileName As String, ByVal dwReserved As Long, _
    ByVal lpfnCB As Long) As Long
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sub aホームページプルダウンの読み取り()
    'URLDownloadToFile で「読み取りした.htm」に保存します
    'ホームページfile名を準備します
    homepagefilename = "http://www.journey-k.com/index.htm"
    Range("A1").Value = homepagefilename
    Range("A2").Value = ""
    returnValue = URLDownloadToFile _
    (0, homepagefilename, ThisWorkbook.Path & "\読み取りした.htm", 0, 0)
    '
    'IEを起動して、ホームページfileを表示します
    Set objIE = CreateObject("InternetExplorer.application")
    objIE.Visible = True
    objIE.Navigate homepagefilename
    '
    待ち時間 = 60 '秒
    'Busyとreadystateをチェックしながら、待ちます
    Do While (objIE.Busy Or Not (objIE.readystate = 4))
    'Sleepは、これが必要、
    'Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sleep 1000
    wcount = wcount + 1
    If wcount > 待ち時間 Then
    Set objIE = Nothing
    Range("A2").Value = "ホームページ見れませんでした"
    Exit Sub
    End If
    Loop
    '以上が上手く動作しない時は、
    'この下の1行をコメントではなく、有効にしてみてください。
    'MsgBox "ホームページが表示したら、OKをクリック", , "エラー防止 待ちます"
    '    MsgBoxは、ホームページの裏に、隠れている時があります
    '
    'ホームページのBodyのTextを抜き出します
    Open ThisWorkbook.Path & "\読み取りしたTEXT.txt" For Output As #1
    Print #1, objIE.Document.body.innerText
    Close #1
    '
    'ホームページの、SELECTタグ毎にOPTIONタグを抜き出します
    For Each objSELECT In objIE.Document.all.tags("SELECT")
    行 = 2
    列 = 列 + 2
    SELECTの数 = SELECTの数 + 1
    Cells(行, 列).Value = objSELECT.Name
    行 = 行 + 1
    '
    'OPTIONタグのValueとテキストを抜き出します
    For Each objOPTION In objSELECT.all.tags("OPTION")
    Cells(行, 列).Value = objOPTION.Value
    Cells(行, 列 + 1).Value = objOPTION.innerText
    行 = 行 + 1
    Cells(2, 列 + 1).Value = 行 - 4 '4行目からのデータの数
    Next objOPTION
    Next objSELECT
    '
    objIE.Quit
    Set objIE = Nothing
    '
    Call b組み合わせ
    End Sub
    'この後、組み合わせを行います
    '
    Sub b組み合わせ()
    'この部分は、汎用性が無いですが、ご参考にしてください。
    列 = "C"
    繰り返し数 = 1
    データ数 = Cells(2, "C").Value
    セルのコピー数 = Cells(2, "E").Value
    n = 1
    For l = 1 To 繰り返し数
    For d = 1 To データ数
    For c = 1 To セルのコピー数
    Cells(n, "G").Value = n
    Cells(n, "H").Value = Cells(d + 3, "C").Value
    n = n + 1
    Next
    Next
    Next
    '
    列 = "E"
    繰り返し数 = Cells(2, "C").Value
    データ数 = Cells(2, "E").Value
    セルのコピー数 = 1
    n = 1
    For l = 1 To 繰り返し数
    For d = 1 To データ数
    For c = 1 To セルのコピー数
    Cells(n, "I").Value = Cells(d + 3, "E").Value
    n = n + 1
    Next
    Next
    Next
    '
    Call cファイルに書き出し
    End Sub
    'この後、ファイルに書き出します
    '
    Sub cファイルに書き出し()
    'この部分は、汎用性が無いですが、ご参考にしてください。
    '
    Cells(1, "G").Select
    ファイル名 = Cells(1, "G").Value
    特定のフォルダ名 = ThisWorkbook.Path
    Do While ファイル名 <> ""
    Open 特定のフォルダ名 & "\" & ファイル名 & ".txt" For Output As #1
    Print #1, ActiveCell.Offset(0, 1).Value & "," & ActiveCell.Offset(0, 2).Value
    Close #1
    ActiveCell.Offset(1, 0).Select
    ファイル名 = ActiveCell.Value
    Loop
    '
    Cells(1, "G").Select
    MsgBox "ファイルに書き出しました", , "マクロ処理終了"
    '
    End Sub
    'この後、キーワードで検索してファイルに書き出します
    '
    Sub dキーワードで検索してファイルに書き出()
    'この部分は、汎用性が無いですが、ご参考にしてください。
    '今までの処理を行い、列G,H,Iにデータが必要です。
    'ホームページを800回くらい見に行くので時間がかかります。
    '初めは、何行目まで行うか、少ない数で様子を見てください。
    '
    Cells(1, "G").Select
    ファイル名 = Cells(1, "G").Value
    特定のフォルダ名 = ThisWorkbook.Path
    何行目まで行うか = 3
    '
    n = 1
    Do While ファイル名 <> "" And Val(ファイル名) <= 何行目まで行うか
    'エクセルのステータスの付近に、進行状況を表示します
    Application.StatusBar = ファイル名 & " 個目の実行中・・クリックしないで!"
    Cells(n, "G").Select
    ファイル名 = Cells(n, "G").Value
    都道府県 = Cells(n, "H").Value
    カテゴリー = Cells(n, "I").Value
    '
    url = "http://www.journey-k.com/database/database.cgi"
    sParam = "cmd=s&HyojiSu=200&Tfile=&HTML=&DataHtml=&Target_30=site_name,site_url,keyword,comment&Type_30=Normal-and&Sort=Word_link&Sort2=Num_Rtime&Sort3=Num_UpTime"
    sPm1 = "&S_10_Key_area=" & 都道府県
    sPm2 = "&S_20_Key_category=" & カテゴリー
    sPm3 = "&S_30_Key_Multi="
    '
    sParam = sParam & sPm1 & sPm2 & sPm3
    homepagefilename = url & "?" & sParam
    '
    'IEを起動して、ホームページfileを表示します
    Set objIE = CreateObject("InternetExplorer.application")
    'objIE.Visible = True
    objIE.Navigate homepagefilename
    '
    待ち時間 = 60 '秒
    'Busyとreadystateをチェックしながら、待ちます
    Do While (objIE.Busy Or Not (objIE.readystate = 4))
    'Sleepは、これが必要、
    'Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sleep 1000
    wcount = wcount + 1
    If wcount > 待ち時間 Then
    Set objIE = Nothing
    Range("F1").Value = "待ち時間すぎで、出来ませんでした"
    Exit Sub
    End If
    Loop
    '
    'ホームページのBodyのTextを抜き出します
    Open 特定のフォルダ名 & "\" & ファイル名 & ".txt" For Output As #1
    Print #1, ファイル名 & " , " & 都道府県 & " , " & カテゴリー & vbCrLf
    Print #1, objIE.Document.body.innerText
    Close #1
    objIE.Quit
    Set objIE = Nothing
    n = n + 1
    Loop
    Cells(1, "G").Select
    MsgBox "ファイルに書き出しました", , "マクロ処理終了"
    '
    End Sub
  • id:miku1973
    わー、めっちゃすごいです!!
    いろいろやってみます!
    また明日書き込みます。
    取り急ぎお礼まで。
  • id:miku1973
    いろいろありがとうございます!
    差し支えなければ教えてください。
     
     
    sParam = "cmd=s&HyojiSu=200&Tfile=&HTML=&DataHtml=&Target_30=site_name,site_url,keyword,comment&Type_30=Normal-and&Sort=Word_link&Sort2=Num_Rtime&Sort3=Num_UpTime"
     
    この記述なんですが、
    一見、該当のホームページのURLを見ても、
    検索結果のURLを見ても、
    この記述になることが発見できませんでした。
     
    正しいことはわかるのですが、これはどうやって導きだしたのでしょうか?
     
    他のページの場合で、自力で導き出せるようになりたいため質問致します。
    どうぞよろしくお願い致します。

  • id:miku1973
    すいません、上記件、自力で理解できました。
    こんな仕組みになっていることを初めて知りました。
    勉強になります。
  • id:miku1973
    本当にありがとうございます。
    非常に稼動かけて記述いただき助かりました。
    自分なりに記述内容を勉強してみようと思いますが、かなり自分のしたいことができるようになり、感謝しております。
    あらためてポイントと「いるか」を贈りたいと思います。
     
    ぶしつけで申し訳ありませんが、最後にもう1点だけアドバイスを頂ければ幸いです。
     
     
     
     
     
    検索結果が大量に存在するケースなどでは、処理が非常に長くなります。
    Loopを組んでいるためかわかりませんが、textファイルの吐き出すスピードも段々遅くなるようです。
    textファイルが数百~数千レベルになるとキツそうです。
     
    Sleep時間を長めにとったり、DoEventsを入れたりしましたが、抜本的解決には至りません。
    著しくPCのパフォーマンスが落ちていくようです。
     
    少しでも処理時間を短縮し、CPUへの不可軽減につながるような方法がありましたら、助言頂けると
    嬉しいです。一応メモリは2GBです。(そもそもLoopがまずいでしょうか?)
     
     
     
     
    非常に申し訳ないため、コメント欄での質問はこれを最後にしたいと思います。
    VBAの質問ははてなでよくするため、またアドバイス頂ければ幸いです。
     

  • id:maruyama2
    「Sleep 200 の様に、短くする」
    Sleepによる停止が、スピードを遅くしている様であれば
    do loop のloop回数が、多くなるかもしれませんが、
    Sleep 200 の様に、短くすると、少し良いかも知れません。


    SetWaitableTimer も、良いかもしれません。
    今回は、Sleepの他に、とも思いましたが、
    複雑な感じでしたので、検討しませんでした。

    以下は、マクロでなく、VBでの説明の参考です。
    http://support.microsoft.com/kb/231298/ja
    「ちょっとした補足です、ご参考にして下さい」
    1.
     VBAに白紙の「Module2」を追加して、説明サンプルの
    「Module1 に、次のコードを貼り付けます。」の部分の、
    の中身をVBAの白紙の「Module2」貼り付けます。
    2.
     1箇所書き換えます。App.EXEName を ThisWorkbook.Name に。
    hTimer = CreateWaitableTimer(0, True, App.EXEName & "Timer")
      の部分を、以下にします。
    hTimer = CreateWaitableTimer(0, True, ThisWorkbook.Name & "Timer")
    3.
     元のマクロの「 Sleep 1000 」を 「 Wait 1 」に書き換えます。
        ( Sleepは、ミリ秒単位   Waitは、秒単位 )
    以上です。
    大きな効果は、無いかもしれませんが、
    ぜひ、チャレンジされてみてください。


    最後になりますが、
    ポイントと「いるか」のご配慮、ありがとうございます。
    楽しみにしております。
  • id:miku1973
    いろいろありがとうございました!
    かけていただいた稼動を考えれば非常に少ないポイントになってしまいますがご容赦ください。
    VBAの質問はよくしますので、またどうぞよろしくお願い致します。
    お礼まで。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません