2015-10-13 4 views
9

Селен:Селен: Прокрутка до конца страницы

Я новичок в 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 раз, и я хочу, чтобы бросить/разорвать петлю, когда высота прокрутки достигается до конца. В этом подходе я хочу удалить жесткий код, например, java-code, потому что Я не знаю, сколько раз повторять итерацию для других приложений, чей свиток поддерживается динамически увеличивающимся. Например, Facebook приложение, Yahoo News ...

ответ

5

Прокрутка к нижней части динамической страницы может быть сложной в зависимости от того, как она реализована на странице.

Сначала вам нужно будет найти контейнер с полосой прокрутки, так как он может отличаться от того, который связан с 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); 
    })(); 
} 
+0

Вы можете проверить этот URL: 'https: // in.yahoo.com /'. и мой вопрос в том, что я просто хочу разбить цикл, когда он достигнет конца, используя 'webdriverjs.', какой URL, который вы проверили, содержит' div scroll'. – Yash

+0

@Yash, он работает с https://in.yahoo.com/. Ваш вопрос заключается в том, как прокручивать вниз до нижней части веб-страницы, когда высота прокрутки динамически возрастает, что в точности соответствует этому примеру с 'webdriverjs'. Я добавил еще один пример, который прокручивается, пока высота больше не увеличивается в течение определенного времени. –

+0

Можете ли вы проверить, что код выдает ошибку? ScriptTimeoutError: асинхронный тайм-аут сценария: результат не принимался за 0 секунд каждый раз во время работы. – Yash

1

Pure JavaScript:

В JavaScript можно использовать функцию setTimeout(). который будет вызывать указанную функцию рекурсивно после указанной вами временной задержки.

Я протестировал приложение групп Google, чей вертикальный прокрутка тега динамически увеличивается. Чтобы загрузить контент, я использовал временную задержку в 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, потому что он не собирается называть рекурсивную функцию временной задержки.

+0

Этот код выдает ошибку при использовании в режиме строгого соответствия ('t' является глобальным). –

+0

@ Red Herring thanks): - теперь я изменил t на локальную переменную var t = null; и испытал !. теперь «i» растет правильно. – Yash

0

из опыта, самый быстрый способ, чтобы перейти к концу страницы, чтобы искать элемент колонтитула и movetoit, как правило, #footer или .footer или просто footer селектор сделает это. Например.:

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

В случае «бесконечные» потоки, такие как Facebook, Twitter и т.д. Они могут блокировать вас, когда вы достигнете предела, так что все в порядке, чтобы объединить максимум итераций с window.scrollTo(0, 300); рекурсивно и подождать несколько секунд после каждого свитка ,

0

Попробуйте этот код - его работу в Python (просто перевести в вашем случае):

# Get scroll height. 
    last_height = self.driver.execute_script("return document.body.scrollHeight") 

    while True: 
     # Scroll down to the bottom. 
     self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 

     # Wait to load a page. 
     time.sleep(2) 

     # Calculate new scroll height and compare with last scroll height. 
     new_height = self.driver.execute_script("return document.body.scrollHeight") 
     if new_height == last_height: 
      break 
     last_height = new_height 

КСТАТИ: Вот я бегу JavaScript из Python.