Java selenuim用执行js模拟鼠标滚动的方式完成页面滚动的异步加载及Java接收浏览器js的返回值

    在使用selenuim webdriver爬取网页时,经常会有很多网页并不是访问链接就会加载全部内容的,而是需要鼠标向下滚动,动态的加载内容,比如知乎首页。这样在爬取的过程中并不能直接抓数据,需要先模拟鼠标滚动,让页面先加载出来才行。


    我使用的方法是利用如下js代码来完成页面的滚动,每次滚动多少可以根据不同情况自行调整。

scroll(0,document.body.scrollHeight)

    在浏览器控制台输入js代码即可看到效果,和程序中使用起来是一样的。可以先在真实场景调试好每次要滚动多少会触发加载,然后再写进代码中使用。同理想要横向滑动的话,就改变第一个参数,第二个参数置为0。

    对于部分网页来说,是不会允许无限制的加载新数据的,换句话说就是滚动加载出的数据是有一定限制的。那么如何使页面滚动到恰好加载到没新数据可加载 就是一个新问题了。想到加载过程中 document.body.scrollHeight 这个值是会根据每次新加载数据动态变化的,那么也就是说 当执行一次js代码后,这个值没有发生改变,就代表本次没有加载新的数据了。

    接下来的问题就是如何使Java代码能够接收到浏览器执行的js代码返回值的问题了。很简单,在js代码上加上return  即可。注意有一个空格。

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * 描述 :谷歌浏览器驱动工具类
 * 作者 :WYH
 * 时间 :2019/8/29 13:57
 **/
public class ChromeDriverUtil {

    private static WebDriver driver;

    private final static int DEFAULT_TIMEOUT = 30;

    static {
        System.setProperty("java.awt.headless", "true");
        String driverPath = "D:/chromedriver.exe";//驱动需下载到指定目录
        ChromeOptions option = new ChromeOptions();
        option.addArguments("disable-infobars");
        option.addArguments("start-maximized");
        //option.addArguments("headless");
        System.setProperty("webdriver.chrome.driver", driverPath);
        driver = new ChromeDriver(option);
        driver.manage().timeouts().pageLoadTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        driver.manage().timeouts().setScriptTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);

    }

    public static void setTimeOut(int second) {
        driver.manage().timeouts().pageLoadTimeout(second, TimeUnit.SECONDS);
        driver.manage().timeouts().setScriptTimeout(second, TimeUnit.SECONDS);
    }

    public static WebDriver getDriver() {
        return driver;
    }

    public static void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    /**
     * 滑动页面到最底部 返回true代表加载了新的 false代表已经没有再加载的了
     */
    private static boolean scrollDown() {
        boolean flag = false;
        if (driver != null) {
            try {
                Long before = (Long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                ((JavascriptExecutor) driver).executeScript("scroll(0,document.body.scrollHeight)");
                //给页面预留加载时间
                Thread.sleep(2000);
                Long after = (Long) ((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight");
                if (!(before.equals(after))) flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return flag;
    }

    public static void loadAll() {
        while (scrollDown());
    }
}

只要是true,就继续执行scrollDown函数,直到它返回false。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值