• Unreal is funny !!!

java + selenium 爬取网页

Java 站长 2年前 (2022-12-28) 198次浏览 已收录 0个评论
文章目录[隐藏]

需求

最近在爬取一家网站的内容,但是发现这家网站的部分内容嵌入在css里,需要解析css 的值,所以用无头的chrome浏览器来抓取页面,利用chrome driver 解析网页,运行js 来提取网页内容。
技术方案采用 java 11 + selenium 4.7.2 + chrome driver 108
注意 windows 上 chrome driver 的版本要与 本机的chrome 版本一致。
chrome driver 下载地址 http://chromedriver.storage.googleapis.com/index.html?path=108.0.5359.71/

代码实现

pom.xml 依赖配置

<dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-chrome-driver</artifactId>
            <version>4.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-api</artifactId>
            <version>4.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-remote-driver</artifactId>
            <version>4.7.2</version>
        </dependency>

crawl.java 主要 java 代码

        Document doc = null;
        System.setProperty("webdriver.chrome.driver", "C:\\tmp\\chromedriver_win32_108\\chromedriver.exe");

        //谷歌浏览器
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless", "--window-size=1920,1200", "--disable-gpu", "--no-sandbox", "--disable-dev-shm-usage", "--no-sandbox");
        options.setHeadless(true);
        options.setAcceptInsecureCerts(true);
        options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");

        WebDriver driver = new ChromeDriver(options);
        driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        
        //示例爬取url
        String htmlUrl = "https://xfunpark.com";
        driver.get(htmlUrl);
        ((JavascriptExecutor) driver).executeScript(JS_SCRIPT);
        WebDriverWait webDriverWait = new WebDriverWait(driver, 10);
        webDriverWait.until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver webDriver) {
                JavascriptExecutor jsExecutor = (JavascriptExecutor) webDriver;
                Object res = jsExecutor.executeScript("\n;return checkPageReady()");
                log.info("js checkPageReady() 返回:{}", res);
                return res != null && (Boolean) res;
            }
        });
        JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
        String json = (String) jsExecutor.executeScript("return getOnePageData();");
        log.info("结果显示:{}", json);

这里有个 JS_SCRIPT 变量,存储的是 是 JS 代码,由于传统的爬虫是 java/python 代码来获取dom元素来解析,这样太麻烦了,不优雅,
由于我们已经使用了 chrome driver,相当于一个chrome浏览器了,我们直接传给 chrome 一些解析dom的方法,返回值是我们想要的json,
再传给java,这样更为简洁优雅。示例的 JS_SCRIPT 如下 :

crawl.js (放在 classpath 下,直接读取文件为 字符串,传给 chrome)
给window 挂载两个方法,后面去调用她们。


//返回 #content_list 是否已经生成
window.checkPageReady = function(){
      return  document.getElementById('content_list') != undefined;
}

//获取这个页面上我们想要的数据为 json
window.getOnePageData = function(){
      let res = {};
      res.title = document.getElementById("title").innerText;
      res.price = document.getElementById("price").innerText;
      return JSON.stringify(res);
}

这里有个 webDriverWait ,这个是代表chrome 在等待一定条件之后再去往下执行,我们这里是检测 checkPageReady 是否返回true,返回true 了才去执行获取数据的方法。


本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java + selenium 爬取网页
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址