2017-11-01 8 views
5

Webページが完全に読み込まれるまでコードを一時停止するには、私はほぼすべての時間で大きな成功を収めています。この方法は、ページが完全にロードされ、そのコンテンツが抽出されていないと判断した後Excel VBAでは、Webページが完全に読み込まれているかどうかを確認する方法は何ですか?

Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop 

しかし時折、私は、テキストコンテンツのロードを参照してください。

ただし、F8でコードをステップ実行すると、コンテンツが毎回抽出されます。これは、私がF8キーを繰り返し押すほど速く行われます。

コードがデータを引き続き抽出する前に、ページとそのすべてのコンテンツが完全に読み込まれていることを確認するにはどうすればよいですか?

どちらの場合も、IEは目に見えない形で実行されています。しかし、私はこれをIEで表示しようとしましたが、実際には私が作業しているページのこの特定の場所にコンテンツがあります。

これは、VBAスクリプトを使用してExcel 2016で実行されています。特定のコンテンツの要求は次のように書かれている:

私はドキュメントがロードされた後、多分値はデータをこするから誰を防ぐための努力で、追加取得していると思うので、私は Excel VBA: Wait for JavaScript execution in Internet Explorerて読んだ
'get item name from page and write it to the first cell on the first empty row available 
Set itemName = objIE.document.querySelector(".the-item-name") 
Worksheets("Results").Range("A1048576").End(xlUp).Offset(1, 0).Value = itemName.innerText 

。しかし、私はそれを行う可能性のあるスクリプトを特定することはできません。それがそこにないことを意味しません。私はまだそれを見ることができません。 -/each:それは要求が返されるものですので、ロードされている価格に先立って、( - )この問題のページの

具体的な例としては、URL

https://www.homedepot.ca/en/home/p.dry-cloth-refills-32---count.1000660019.html

で最初product-total-price div要素は、ダッシュが含まれています$11.29/eachの代わりに

私は回避策がありますが、それは私がそうしたいと思うほど効率的でも簡潔でもありません。私はダッシュの存在のために返された文字列をテストします。それがあれば、ループしてもう一度チェックし、それをキャプチャしてワークシートに挿入します。

setPriceUM: 
    Set hdPriceUM = objIE.document.querySelector(".product-total-price").innerTe‌​‌​xt 
    hdPriceUMString = hdPriceUM.innerText 
    stringTest = InStr(hdPriceUMString, "-") 
    If stringTest = True Then 
     GoTo setPriceUM 
    Else 
     Debug.Print hdPriceUMString 
    End If 

これを読んでいただき、ありがとうございます。

+1

優秀な質問です。私はこの問題にも苦労していますが、幸いにも私が問題を解決したのは、オブジェクトが利用可能になるまでループした初期ループの後にループを追加することでした。だから、私の質問は:すべてのオブジェクトは、ページが完全に "ロード"後に利用可能ですか?例: 'Set SubmitBtn = doc.getElement .....' ...ランタイムエラーを表示する 'Nothing'ですか? –

+0

私もこの問題に遭遇しましたが、通常はネットワークの問題です。ネットワークが高速で実行されているときは問題はありませんが、時間がかかり始めるとページが完全に読み込まれません。私は余分な時間を許すために待機タイマーを追加することに頼らざるを得なかった。 'Application.Wait(Now + TimeValue(" 0:00:06 "))'これは6秒の待機です。 – Mitch

+0

@Mitch Timersは、特に低速ネットワークの場合、信頼性の低いソリューションです。 – omegastripes

答えて

1

ウェブページの機能は非常に異なります。そのため、すべての機能に適合するソリューションはありません。

あなたの例については、あなたの問題を回避するには、実用的なソリューションで、コードは次のようであるかもしれない:とにかく

Sub TestIE() 

    Dim q 

    With CreateObject("InternetExplorer.Application") 
     .Visible = True 
     .Navigate "https://www.homedepot.ca/en/home/p.dry-cloth-refills-32---count.1000660019.html" 
     ' Wait IE 
     Do While .readyState < 4 Or .Busy 
      DoEvents 
     Loop 
     ' Wait document 
     Do While .document.readyState <> "complete" 
      DoEvents 
     Loop 
     ' Wait element 
     Do 
      q = .document.querySelector(".product-total-price").innerText 
      If Left(q, 1) <> "-" Then Exit Do 
      DoEvents 
     Loop 
     .Quit 
    End With 
    Debug.Print q 

End Sub 

、あなたは(ブラウザの開発者ツールを使用して、Webページのロード処理、XHRsとDOMの変更を検討する必要がありますF12)。そのようにすれば、数多くのXHRのうちの1つが価格をJSON形式で返すことがわかります。ページがロードされている間に価格が表示される直前に、ブラウザ開発者ツールのネットワークタブに記録されます。そのXHRは、ロードされたJSの1つ、特にページがロードされた後に発生します。

Sub TestXHR() 

    Dim q 

    With CreateObject("MSXML2.XMLHTTP") 
     .Open "GET", "https://www.homedepot.ca/homedepotcacommercewebservices/v2/homedepotca/products/1000660019/localized/9999?catalogVersion=Online&lang=en", False 
     .Send 
     q = .ResponseText 
    End With 
    q = Replace(q, " : ", ":") 
    q = Split(q, """displayPrice""", 2)(1) 
    q = Split(q, """formattedValue"":""", 2)(1) 
    q = Split(q, """", 2)(0) 
    Debug.Print q 

End Sub 

しかし、再び、全く普通はありません:あなたは、ちょうどそのXHRを再現し、分割によって価格を抽出してもよい

https://www.homedepot.ca/homedepotcacommercewebservices/v2/homedepotca/products/1000660019/localized/9999?catalogVersion=Online&lang=en

:(私はちょうどネットワーク]タブからそれをコピーした)、このURLを試してみてください場合。

+0

Omegastripes、最初のコードスニペットで行ったことは、私の回避策とほぼ同じです。そのため、コーディングの品質が向上していることを奨励しています。 XHRは私にとって新しく、私は15年前に初めて登場して以来、JSONの仕事をしていません。私はそれらの両方の速度を上げるつもりです。私は先週MSXML2.XMLHTTP関数を先週調べ始めました。私はあなたが正しいと信じて、これが行く方法です。私はそれを仕事に出して、ここに報告します。ありがとうございました! – Innertube

関連する問題