• Selenium/HtmlUnit设置代理获取JS生成的网页


    通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient获取的网页源代码都是直观可见的,其代码的内容和通过浏览器右键网页->点击查看网页源代码的内容一致。

    但是现在越来越多的网站使用Js来动态生成内容来提高相应速度,而HttpClient只是返回后端相应的response的请求主体,并没有返回浏览器生成的网页,所以对于Js生成的内容HttpClient是获取不了的。

    对于获取Js生成的网页,我们主要通过模拟浏览器的运行,渲染response的请求主体最终得到对应的内容,得到的内容和通过浏览器右键网页->点击检查/查看元素的内容一致。

    我们这里讲的模拟方法大概有两种:

    • 一种是使用Selenium
    • 一种是使用HtmlUnit

    抓取目标

    我们这次的目标是获取bilibili动态生成的动画列表,左上是抓取的目标列表,左下是浏览器渲染的html内容,右面是服务器返回的response的正文。通过对比,我们可以看出目标列表是Js生成。
    bilibili

    使用Selenium获取页面

    Selenium是一个用于Web应用自动化测试的工具,更多的介绍就谷歌。这里我们主要用作模拟页面的运行并将结果返回,对于网页截图的功能也是可行的。

    Selenium支持模拟很多浏览器,但是我们这里只模拟PhantomJS,因为PhantomJS 是一个脚本化的无界面 WebKit,以 JavaScript 为脚本语言实现各项功能。由于是无界面的,所以速度性能方面会较好。

    1.下载
    使用PhantomJS需要到官网下载最新的客户端,这里使用phantomjs-2.1.1-windows.zip

    2.maven依赖引入:

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>2.53.0</version>
    </dependency>
    <dependency>
        <groupId>com.codeborne</groupId>
        <artifactId>phantomjsdriver</artifactId>
        <version>1.2.1</version>
        <exclusions>
            <exclusion>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-remote-driver</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

    3.示例代码

    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.phantomjs.PhantomJSDriver;
    import org.openqa.selenium.phantomjs.PhantomJSDriverService;
    import org.openqa.selenium.remote.DesiredCapabilities;
    
    import java.util.ArrayList;
    
    /**
     * @author GinPonson
     */
    public class TestSelenium {
    
        static final String HOST = "127.0.0.1";
        static final String PORT = "80";
        static final String USER = "gin";
        static final String PWD = "12345";
    
        public static void main(String[] args){
            System.setProperty("phantomjs.binary.path", "D:\phantomjs-2.1.1-windows\bin\phantomjs.exe");
            DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
    
            //设置代理或者其他参数
            ArrayList<String> cliArgsCap = new ArrayList<>();
            //cliArgsCap.add("--proxy=http://"+HOST+":"+PORT);
            //cliArgsCap.add("--proxy-auth=" + USER + ":" + PWD);
            //cliArgsCap.add("--proxy-type=http");
            capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, cliArgsCap);
            //capabilities.setCapability("phantomjs.page.settings.userAgent", "");
    
            WebDriver driver = new PhantomJSDriver(capabilities);
            driver.get("http://www.bilibili.com/video/bangumi-two-1.html");
            System.out.println(driver.getPageSource());
            driver.quit();
        }
    }
    

    4.其他功能

    • 设置参数或者代理:去掉上面的注释,就可以使用自己的代理了。
    • 操作页面,返回操作后页面内容:不多说了,这里介绍一下可以做。
    • 页面截图:返回浏览器的全屏截图。

    使用HtmlUnit获取页面

    HtmlUnit功能上算是是Selenium的一个子集,Selenium有对应的HtmlUnit实现。HtmlUnit是用Java写的无界面的浏览器,正因为其没有界面,因此执行的速度还是可以的。

    1.maven依赖引入

    <dependency>
        <groupId>net.sourceforge.htmlunit</groupId>
        <artifactId>htmlunit</artifactId>
        <version>2.25</version>
    </dependency>
    

    2.Java代码

    /**
     * @author GinPonson
     */
    public class TestHtmlUnit {
        static final String HOST = "127.0.0.1";
        static final String PORT = "80";
        static final String USER = "gin";
        static final String PWD = "12345";
    
        public static void main(String[] args) throws Exception{
            WebClient webClient = new WebClient();
            //设置代理
            //ProxyConfig proxyConfig = webClient.getOptions().getProxyConfig();
            //proxyConfig.setProxyHost(HOST);
            //proxyConfig.setProxyPort(Integer.valueOf(PORT));
            //DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
            //credentialsProvider.addCredentials(USER, PWD);
    
            //设置参数
            //webClient.getOptions().setCssEnabled(false);
            //webClient.getOptions().setJavaScriptEnabled(false);
            webClient.getOptions().setThrowExceptionOnScriptError(false);
            HtmlPage page = webClient.getPage("http://www.bilibili.com/video/bangumi-two-1.html");
    
            System.out.println(page.asXml());
            webClient.close();
        }
    }
    

    3.其他功能

    • 设置参数或者代理:去掉上面的注释,就可以使用自己的代理了。
    • 操作页面,返回操作后页面内容:不多说了,这里介绍一下可以做。
    • 解析页面

    总结

    PhantomJS和HtmlUnit模拟浏览器页面的生成功能都不错,PhantomJS作为一个无界面的WebKit,渲染页面的功能非常完善,而且带有浏览器截图功能,能模拟登录操作。HtmlUnit使用Rhino引擎来解析Js,有时候解析速度非常慢,就像上面的例子,费了很长时间,但是HtmlUnit可以获取页面,解析元素一套做完(当然解析元素还是使用Jsoup好),是不错的工具。
    HtmlUnit遇到错误后,前后处理相差7分钟,可能是我不会用QAQ
    截图
    欢迎补充:)

  • 相关阅读:
    C#设计一个简单的计算器,实现两个数的加,减,乘,除,求幂等计算,运行效果如下图所示:
    如何用C#中的窗体设计一款只含有加减乘除,求平方的简易版计算器?
    番外篇科普为什么1024是程序员日?2020年10月24日,程序员为啥都不放假?
    VS2019基础,C#编辑窗体时,工具箱如何调用,工具箱挡住窗体怎么办,如何改窗体名字
    C++用函数重载实现两个整数和三个浮点数的排序,按照从小到大的顺序将排序结果输出
    C++用引用形参实现两个变量的值互换
    C++用带有默认参数的函数实现,求2个或3个正整数中的最大数
    linux服务器磁盘速度测试
    CSS HACK收集
    分享一个web页面背景全屏的jquery插件Fullscreen Background
  • 原文地址:https://www.cnblogs.com/ginponson/p/6659167.html
Copyright © 2020-2023  润新知