Sélénium: défiler jusqu’à la fin de la page

Sélénium:

Je suis nouveau sur WebDriverJS . J’ai essayé cette approche en Java.

Long repaeted = 0l, scrollHeight = 0l, returnHeight = 0l; while(true){ if (repaeted == 0) { returnHeight = (Long) jse.executeScript("var scroll =document.documentElement.scrollHeight;window.scrollTo(0, scroll); return scroll;"); System.out.println("Height : "+scrollHeight +"\t Chnage : "+returnHeight+ "\t Repeated : "+repaeted); scrollHeight = returnHeight; }else { returnHeight = (Long) jse.executeScript("var scroll = document.documentElement.scrollHeight;window.scrollTo(0, scroll); return scroll;"); System.out.println("Height : "+scrollHeight +"\t Chnage : "+returnHeight+ "\t Repeated : "+repaeted); if (scrollHeight.intValue() == returnHeight.intValue()) { System.out.println("Break.."+ returnHeight); break; } else { scrollHeight = returnHeight; } } repaeted++; } 

mais je suis confronté à un problème dans webdriverjs tout en itérant la boucle.

 var webdriver = require('..'), By = webdriver.By, until = webdriver.until; // make sure chromedriver can be found on your system PATH var driver = new webdriver.Builder() .forBrowser('chrome') .withCapabilities(webdriver.Capabilities.chrome()) .build(); driver.get('https://in.yahoo.com/').then(function(){ var window = new webdriver.WebDriver.Window(driver); window.maximize(); driver.manage().timeouts().implicitlyWait(1000 * 3); }) .then(function(){ console.log('Entered'); var check = 0, count = 0 for(var i = 0; i< 50; i++){ //driver.sleep(1000 * 2); driver.executeScript('var dynamicscroll = document.documentElement.scrollHeight;window.scrollTo(0, dynamicscroll);return dynamicscroll;').then(function(height){ console.log('Check : '+check+' Height : '+height +' Repeated : '+(count++)); if(check === 0 || check !== height){console.log('continue'); check = height; } else { console.log('break'); i = 100; } }); } }) .then(null, function(err) { console.error("An error was thrown! By Promise..." + err); }); driver.quit(); 

Dans mon code, j’ai codé en dur la boucle à parcourir jusqu’à 50 fois et je souhaite quitter / interrompre la boucle lorsque la hauteur de défilement est atteinte . Dans cette approche, je souhaite supprimer le code dur, tel que le code Java, car je ne sais pas combien de fois itérer pour les autres applications dont le défilement continue d’augmenter de façon dynamic . Par exemple, application Facebook, Yahoo News …

Le défilement jusqu’au bas d’une page dynamic peut être difficile, en fonction de la manière dont elle est implémentée par la page.

Vous devez d’abord trouver le conteneur avec la barre de défilement car il peut être différent de celui lié à window.scrollTo .

scrollHeight ensuite défiler le conteneur en augmentant scrollTop jusqu’à ce que scrollHeight devienne stable, sans demande en attente. Pour vérifier s’il y a des demandes en attente, évaluez jQuery.active si la page a JQuery ou connectez XMLHttpRequest pour surveiller les appels send .

Voici un exemple d’utilisation d’une fonction générique pour faire défiler plusieurs fois le bas de la page ou jusqu’à la fin:

 var webdriver = require('selenium-webdriver'); var driver = new webdriver.Builder().forBrowser('chrome').build(); driver.get('https://groups.google.com/forum/#!search/webdriverjs'); // scroll to the bottom 3 times driver.executeAsyncScript(scrollBottom, 3) .then(n => console.log(`scrolled ${n} time(s)`)); // scroll to the bottom until the end driver.executeAsyncScript(scrollBottom) .then(n => console.log(`scrolled ${n} time(s)`)); 
 function scrollBottom(){ var count = arguments[arguments.length - 2] || 0x7fffffff; var callback = arguments[arguments.length - 1]; /* get the scrollable container */ var elm = document.elementFromPoint(window.innerWidth - 25, window.innerHeight / 2); for ( ;elm && (++elm.scrollTop, !elm.scrollTop); elm=elm.parentElement); elm = elm || document.documentElement; /* hook XMLHttpRequest to monitor Ajax requests */ if (!('idle' in XMLHttpRequest)) (function(){ var n = 0, t = Date.now(), send = XMLHttpRequest.prototype.send; var dispose = function(){ --n; t = Date.now(); }; var loadend = function(){ setTimeout(dispose, 1) }; XMLHttpRequest.idle = function() { return n > 0 ? 0 : Date.now() - t; }; XMLHttpRequest.prototype.send = function(){ ++n; this.addEventListener('loadend', loadend); send.apply(this, arguments); }; })(); /* scroll until steady scrollHeight or count of scroll and no pending request */ var i = 0, scrollHeight = -1, scrollTop = -1; (function scroll(){ if ((scrollHeight === elm.scrollHeight || i === count) && XMLHttpRequest.idle() > 60) return callback(i); scrollTop = elm.scrollTop; scrollHeight = elm.scrollHeight; if (i < count) i += (elm.scrollTop = 0x7fffffff, scrollTop !== elm.scrollTop); setTimeout(scroll, 100); })(); } 

Ou en faisant défiler jusqu'à ce que la hauteur n'augmente plus pendant un temps spécifique (5 secondes ici):

 function scrollBottom(){ var count = arguments[arguments.length - 2] || 0x7fffffff; var callback = arguments[arguments.length - 1]; var timeout = 5000; /* 5 seconds timeout */ var i = 0; /* get the scrollable container */ var elm = document.elementFromPoint(window.innerWidth - 25, window.innerHeight / 2); for ( ;elm && (++elm.scrollTop, !elm.scrollTop); elm=elm.parentElement); elm = elm || document.documentElement; /* scroll while the height is increasing or until timeout */ (function scroll(){ var endtime = Date.now() + timeout; var height = elm.scrollHeight; elm.scrollTop = 0x7fffffff; /* scroll */ setTimeout(function check(){ if (Date.now() > endtime) /* returns if waited more than 5 sec */ callback(i); else if (elm.scrollHeight == height) /* wait again if same height */ setTimeout(check, 60); else if (++i === count) /* returns if scrolled the expected count */ callback(i); else /* scroll again */ setTimeout(scroll, 60); }, 250); })(); } 

JavaScript pur:

En JavaScript, nous pouvons utiliser la fonction setTimeout (). qui appellera la fonction spécifiée de manière récursive après le délai que vous avez spécifié.

J’ai testé l’application Google Groupes, dont la balise div scroll vertical augmente de façon dynamic. Pour charger le contenu, j’ai utilisé le délai de 5 000. vous pouvez tester ce code dans la console du navigateur en utilisant l’URL suivante: https://groups.google.com/forum/#!search/webdrierjs .

 var i = 0, height = 0, check = 0, t = null; flow(); function run(arg){ var objDiv = document.querySelector('div.IVILX2C-b-F'); objDiv.scrollTop = objDiv.scrollHeight; return objDiv.scrollHeight; } function flow() { i++; switch(i){ case 0: height = run(i); sleep(5000); break; case -1: run(i); clearTimeout(t); //stops flow break; default: check = run(i); console.log('Return Height : '+check +' Count : '+i); if(check === height){ i = -2; console.log('Break message : '+i); }else { console.log('Changed...'); height = check; } sleep(5000); break; } } function sleep(delay) { t=setTimeout("flow()",delay);} //starts flow control again after time specified. //function sleep(delay) { var start = new Date().getTime(); while (new Date().getTime() < start + delay); flow(); } // stops execution and then continues. 

mais même moi, je ne peux pas exécuter ce script avec WebDriver / WebDriverJS car il n’appellera pas la fonction récursive à la fin du temps.

Par expérience, le moyen le plus rapide de faire défiler l’écran jusqu’en fin de page consiste à rechercher l’élément de pied de page et movetoit, généralement #footer ou .footer ou tout simplement un sélecteur de footer . Par exemple:

 footer = driver.findElement({id: "footer"}); driver.executeScript("arguments[0].scrollIntoView(false);", footer); 

Dans le cas de stream «sans fin» tels que Facebook, Twitter, etc. Ils peuvent vous bloquer lorsque vous atteignez une limite. Il est donc possible de combiner le nombre maximal d’itérations avec window.scrollTo(0, 300); récursivement et attendez quelques secondes après chaque défilement.