私の目標は、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));
});
});
});
を、オブジェクトを抽出する方法を見つけますドライバに拘束されることはありません。また、必要なデータを取得するための代替ツール/ソリューションを見つけることもできます。
はい!ありがとうございました!なぜ私はそれについて考えなかったのか分かりませんが、それは完璧です。最初のコードブロックを試してみましたが、それは魅力のように機能します。パフォーマンスが今まで以上に問題を抱えている場合は、2番目の方法も試してみてください。これは私の最初のstackoverflowの質問でしたし、いくつかの夜のためにこれを理解しようとした後、私はついにサインアップして尋ねることに決めました...最適な経験をありがとう! :) – IvanVolons