0

私の目標は、Webページ上にという要素があるとの情報を体系的に収集することです。具体的には、各要素に対してel.getBoundingClientRect()window.getComputedStyle(el)を実行したいと思います。ウェブドライバでJavaScriptを非同期に実行する

私はNodeJS用にSelenium WebDriverを使用して、ページを読み込んでブラウザの操作を管理しています。すべての要素を

driver.findElements(By.xpath("//*")) 
     .then(elements => { 
      var elementsLeft = elements.length; 
      console.log('Entering async map'); 
      async.map(elements, el => { 
       driver.executeScript("return window.getComputedStyle(arguments[0]).cssText",el) 
        .then((styles: any) => { 
         //stuff would be done here with the styles 
         console.log(elements.indexOf(el)); 
        }); 
      }); 
    }); 

このコードがループをして自分のスタイルを取得するが、それは非常に遅いです:簡素化するために、ちょうどgetComputedStyleに焦点を当ててみましょう。ページを完了するまでに数分かかることがあります。私はドライバが非同期にスクリプトを実行することを望みますが、これは可能ではありません。なぜなら、各Seleniumドライバには、最後の完了後にのみドライバへの各コマンドが開始されることを保証する 'ControlFlow'があるからです。私はこのための回避策を見つける必要があるので、私はページ上でJavaScriptを非同期的に実行することができます。

注:SeleniumのexecuteAsyncScriptも試してみましたが、これはexecuteScriptのラッパーにすぎず、終了するまでブロックされます。ここに私のコードはexecuteAsyncScriptを使用している - それだけでだけでなく、以前のコードを実行:私は非同期的に私のJavaScriptを実行するために、いずれかのバイパスセレンのControlFlowへの道を探しています

driver.findElements(By.xpath("//*")) 
     .then(elements => { 
      var elementsLeft = elements.length; 
      async.map(elements, el => { 
       driver.executeAsyncScript( 
        function(el: any) { 
         var cb = arguments[arguments.length - 1]; 
         cb(window.getComputedStyle(el).cssText); 
        }, el) 
        .then((styles: any) => { 
         //stuff would be done here with the styles 
         console.log(elements.indexOf(el)); 
        }); 
      }); 
    }); 

を、オブジェクトを抽出する方法を見つけますドライバに拘束されることはありません。また、必要なデータを取得するための代替ツール/ソリューションを見つけることもできます。

答えて

0

executeScriptWebElement秒であるため、executeScriptを繰り返し呼び出すのではなく、1回の呼び出しですべての作業を高速に行うことができますか。

driver.findElements(By.xpath("//*")) 
    .then(elements => { 
     driver.executeScript("return arguments[0].map(function(el) {return [el, window.getComputedStyle(el).cssText];})", elements) 
      .then((styles: any) => { 
       //stuff would be done here with the styles 
       console.log(styles); 
      }); 
    }); 
}); 

遅すぎる場合は、スクリプト内のすべての要素を渡すのではなく、スクリプト内に配置することを検討しましたか?

driver.findElements(By.xpath("//*")) 
    .then(elements => { 
     driver.executeScript("return Array.prototype.slice.call(document.getElementsByTagName('*'))" + 
       ".map(function(el) {return [el, window.getComputedStyle(el).cssText];})", elements) 
      .then((styles: any) => { 
       //stuff would be done here with the styles 
       console.log(styles); 
      }); 
    }); 
}); 
+0

はい!ありがとうございました!なぜ私はそれについて考えなかったのか分かりませんが、それは完璧です。最初のコードブロックを試してみましたが、それは魅力のように機能します。パフォーマンスが今まで以上に問題を抱えている場合は、2番目の方法も試してみてください。これは私の最初のstackoverflowの質問でしたし、いくつかの夜のためにこれを理解しようとした後、私はついにサインアップして尋ねることに決めました...最適な経験をありがとう! :) – IvanVolons

関連する問題