爬虫获取渲染后页面(JAVA)

文章介绍了在Java环境下使用HttpClient处理HTTPS请求,以及通过WebClient和Selenium解决网页渲染后的内容抓取,针对HTTP请求超时和网页源码与下载内容不一致的问题提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景 

最近突然想了解一下爬虫,但是自己又不太了解python,所以学习了下Java版爬虫。在这个过程中遇到了一个问题,为了解决这个问题,百度了很多方法,两个小时候,终于找到了一个最佳方案

二、问题描述

第一个问题:想要抓取的网页是http or https请求,这个很关键,有些方法无法实现https请求。

第二个问题:关键接口相应内容为密文(除非可以解密,否则只能通过抓取网页,获取解析内容)

第三个问题:网页源码 与 下载后的文件不一致,下载后的文件为浏览器渲染后的网页

三、解决方法

3.1、http请求

若为https,则使用httpClient是无法访问通过的。该方法可以解决http请求获取页面问题

public static Page  sendRequstAndGetResponse(String url) {
        Page page = null;
        // 1.生成 HttpClinet 对象并设置参数
        HttpClient httpClient = new HttpClient();
        // 设置 HTTP 连接超时 5s
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        // 2.生成 GetMethod 对象并设置参数
        GetMethod getMethod = new GetMethod(url);
        // 设置 get 请求超时 5s
        getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
        // 设置请求重试处理
        getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
        // 3.执行 HTTP GET 请求
        try {
            int statusCode = httpClient.executeMethod(getMethod);
        // 判断访问的状态码
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: " + getMethod.getStatusLine());
            }
        // 4.处理 HTTP 响应内容
            byte[] responseBody = getMethod.getResponseBody();// 读取为字节 数组
            String contentType = getMethod.getResponseHeader("Content-Type").getValue(); // 得到当前返回类型
            page = new Page(responseBody,url,contentType); //封装成为页面
        } catch (HttpException e) {
        // 发生致命的异常,可能是协议不对或者返回的内容有问题
            System.out.println("Please check your provided http address!");
            e.printStackTrace();
        } catch (IOException e) {
        // 发生网络异常
            e.printStackTrace();
        } finally {
        // 释放连接
            getMethod.releaseConnection();
        }
        return page;
    }

3.2、网页源码 与 下载后的文件不一致,下载后的文件为浏览器渲染后的网页

方法一:虽然启用了JS、CSS,并添加了延时,但获取的页面依旧不是渲染后的网页。

对于有些复杂网页并不能够实现,有些网页在获取接口参数(甚至加密),

    public void test1() {
        // 新建一个模拟谷歌Chrome浏览器的浏览器客户端对象
        final WebClient webClient = new WebClient(BrowserVersion.CHROME);
        // 当JS执行出错的时候是否抛出异常, 这里选择不需要
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        // 当HTTP的状态非200时是否抛出异常, 这里选择不需要
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.getOptions().setActiveXNative(false);
        // 是否启用CSS, 因为不需要展现页面, 所以不需要启用
        webClient.getOptions().setCssEnabled(true);
        // 启用JS
        webClient.getOptions().setJavaScriptEnabled(true);
        // 很重要,设置支持AJAX
        webClient.setAjaxController(
                new NicelyResynchronizingAjaxController());


        HtmlPage page;
        try {
            page = webClient.getPage("https://xxx");
            Thread.sleep(10000);//程的等待 因为js加载需要时间的
            System.out.println(page.asXml());
            String s = page.asXml();
        } catch (Exception ignored) {
        }finally {
            webClient.close();
        }
    }

方法二:直接抓取渲染后网页进行解析(耗性能,但有用)

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.33.0</version>
</dependency>
public void test3() throws InterruptedException {
        //驱动所在的地址
        System.getProperties().setProperty("webdriver.chrome.driver", "C:\\Users\\leo\\Desktop\\chromedriver.exe");
        ChromeOptions option = new ChromeOptions();

        //chrome.exe所在的地址
        option.setBinary("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");

        ChromeDriver webDriver = new ChromeDriver(option);
        String str = "https://aaa#";
        //请求根地址
        webDriver.get(url);
        System.out.println(url);
        Thread.sleep(3000);

        //页面信息
        WebElement htmlElement = webDriver.findElement(By.xpath("/html"));
        String text = htmlElement.getText();
    }

四、总结

        内容简单但是有效,使用爬虫技术时候,请一定要合法哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值