2015-10-13 15 views
9

Selen:Selen: Przewiń do końca strony

Jestem nowy WebDriverJS. Próbowałem tego podejścia w Javie.

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++; 
} 

ale mam problem z webdriverjs podczas iteracji pętli.

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(); 

W moim kodu Mam ustalony dla pętli iteracyjne aż 50 razy i chcę zakończyć/przerwać pętlę gdy wysokość przewijania zostanie osiągnięty do końca. W tym podejściu chcę usunąć hardcode, taki jak kod java, ponieważ Nie wiem, ile razy należy powtórzyć dla innych aplikacji, których zwój jest dynamicznie zwiększany. Na przykład, aplikacja Facebook, Yahoo News ...

Odpowiedz

5

Przewijanie strony w dół dynamicznej strony może być trudne w zależności od sposobu implementacji strony.

Najpierw musisz znaleźć pojemnik z paskiem przewijania, ponieważ może być inny niż ten podłączony do window.scrollTo.

Następnie przewiń kontener, zwiększając wartość scrollTop, aż scrollHeight stanie się stabilny bez oczekujących żądań. Aby sprawdzić, czy są oczekujące żądania, należy wykonać evalute jQuery.active, jeśli strona ma JQuery lub przechwycić XMLHttpRequest, aby monitorować połączenia pod numerem send.

Oto przykład stosując na funkcję rodzajowy, aby przewinąć do dołu strony kilka razy, aż do końca:

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); 
    })(); 
} 

Albo przewijając aż wysokość nie zwiększa już podczas konkretny czas (5 sekund tutaj):

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

Czy możesz sprawdzić za pomocą tego adresu URL: 'https: // in.yahoo.com /'. a moje pytanie brzmi: chcę przerwać pętlę, gdy się zakończy, używając 'webdriverjs.', który URL, który zaznaczyłeś, zawiera' div scroll'. – Yash

+0

@Yash, działa z https://in.yahoo.com/. Pytanie brzmi: jak przewinąć w dół do dolnej strony strony internetowej, gdy wysokość przewijania dynamicznie wzrasta, co jest dokładnie tym przykładem w przypadku 'webdriverjs'. Dodałem kolejny przykład, który przewija się, dopóki wysokość nie wzrośnie w określonym czasie. –

+0

Czy możesz sprawdzić, że kod rzuca błąd 'ScriptTimeoutError: asynchroniczny limit czasu skryptu: wynik nie został odebrany w ciągu 0 sekund za każdym razem podczas działania. – Yash

1

Czysta JavaScript:

W JavaScript możemy używać setTimeout funkcji(). który wywoła określoną funkcję rekursywnie po określonym czasie opóźnienia.

Przetestowałem aplikację grup dyskusyjnych Google, której pionowy przewijak znacznika div dynamicznie się zwiększa. Aby załadować zawartość użyłem opóźnienia czasowego 5000. możesz przetestować ten kod na konsoli przeglądarki używając tego adresu 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. 

ale nawet nie mogę uruchomić ten skrypt za pomocą WebDriver/WebDriverJS ponieważ nie będzie wywołanie funkcji rekurencyjnej na opóźnieniem.

+0

Ten kod wygeneruje błąd w trybie ścisłej zgodności ("t" jest globalne). –

+0

@ A Red Herring thanks): - teraz zmieniłem t jako zmienną lokalną var t = null; i przetestowane !. teraz "i" odpowiednio się zwiększa. – Yash

0

z doświadczenia wynika, że ​​najszybszym sposobem, aby przejść do końca strony jest szukanie elementu stopki i movetoit, zwykle #footer lub .footer lub tylko footer zrobi to. Na przykład.:

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

W przypadku „niekończące się” strumienie, takich jak Facebook, Twitter, itp mogą one blokować po osiągnięciu limitu, więc jest to w porządku, aby połączyć max powtórzeń z window.scrollTo(0, 300); rekurencyjnie i poczekać kilka sekund po każdym zwoju .

0

Spróbuj tego kodu - swoją pracę w Pythonie (tylko tłumaczyć w danym przypadku):

# 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 

BTW: Oto Używam JavaScript z Python.