javascript - Selenium:滚动到页面末尾

标签 javascript node.js selenium selenium-webdriver

Selenium :

我是 WebDriverJS 的新手.我已经在 J​​ava 中尝试过这种方法。

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 代码这样的硬代码,因为我不知道要为滚动保持动态增加的其他应用程序迭代多少次。 例如,Facebook 应用程序、雅虎新闻...

最佳答案

滚动到动态页面的底部可能具有挑战性,具体取决于页面的实现方式。

首先,您必须找到带有滚动条的容器,因为它可能与链接到 window.scrollTo 的容器不同。

然后通过增加 scrollTop 滚动容器,直到 scrollHeight 变得稳定且没有待处理的请求。要检查是否有待处理的请求,请评估 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 - Selenium:滚动到页面末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33094727/

相关文章:

javascript - Angular2 - Loopback-sdk-builder - 如何在 api 调用中设置 header

Node.JS:如何在 URL 请求中使用百分号登录?

java - Selenium Java - 列表元素包含无序列表中的部分文本

javascript - 嵌套 Json 访问值

javascript - 允许日期选择器仅显示特定月份

javascript - 由 : com. intuit.karate.exception.KarateException: ReferenceError: "XMLHttpRequest"is not defined Karate 配置 js 文件中的异常引起

python - Selenium - X 时间后刷新所有选项卡

javascript - 如何连接 for 循环中的 set 变量以用作输入中的名称以获取值?

node.js - 使用 Workload Identity 从 GKE 向 Google Cloud Firestore 进行身份验证

java - 如何在java selenium中对两个数组字符串值求和并存储到另一个数组列表中?