Selenium: прокрутка до конца страницы
Селена:
Я новичок в WebDriverJS. Я пробовал этот подход в 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++;
}
но я сталкиваюсь с проблемой в webdriverjs при итерации цикла.
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();
код Я жестко закодировал цикл для итерации до 50 раз, и я хочу выйти/разорвать цикл, когда высота прокрутки будет достигнута до конца. В этом подходе я хочу удалить hardcode как java-код, потому что Я не знаю, сколько раз повторять для других приложений, прокрутка которых постоянно увеличивается динамически. Например, приложение Facebook, Yahoo News...
3 ответов
прокрутка до нижней части динамической страницы может быть сложной задачей в зависимости от того, как она реализуется на странице.
сначала вам нужно будет найти контейнер с полосой прокрутки, так как он может отличаться от связанного с window.scrollTo
.
затем прокрутите контейнер, увеличив scrollTop
до scrollHeight
станет устойчивым, без запросов. Чтобы проверить, есть ли отложенные запросы, либо evalute jQuery.active
если на странице есть JQuery или hook XMLHttpRequest
для мониторинга звонки на send
.
вот пример использования общей функции для прокрутки до нижней части страницы несколько раз или до конца:
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);
})();
}
или с помощью прокрутки до тех пор, пока высота не увеличивается в течение определенного времени (5 секунд) :
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:
в JavaScript, мы можем использовать setTimeout (функция). который будет вызывать указанную функцию рекурсивно после указанной вами временной задержки.
я протестировал приложение google groups, вертикальная прокрутка тега div которого динамически увеличивается. Для загрузки контента я использовал временную задержку 5000. вы можете проверить этот код в консоли браузера, используя этот URL: 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.
но даже я не могу запустить этот скрипт с помощью WebDriver / WebDriverJS, потому что он не будет вызывать рекурсивную функцию с задержкой по времени.
из опыта, самый быстрый способ прокрутки до конца страницы-это поиск элемента нижнего колонтитула и movetoit, обычно #footer
или .footer
или просто footer
селектор сделает это. Например:
footer = driver.findElement({id: "footer"});
driver.executeScript("arguments[0].scrollIntoView(false);", footer);
в случае "бесконечных" потоков, таких как Facebook, Twitter и т. д. Они могут блокировать вас, когда вы достигнете предела, поэтому можно комбинировать максимальные итерации с window.scrollTo(0, 300);
рекурсивно и подождите несколько секунд после каждой прокрутки.