Java获取js渲染后的html页面源码实战(获取金价)

以下代码获取京东积存金实时价格,并高于预期卖出价或低于预期买入价时弹窗或微信提醒。

依赖

依赖htmlunit、jsoup两个包,htmlunit用于获取页面,jsoup用于解析html获取指定值。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>goldNotice</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.resource>1.8</maven.compiler.resource>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>net.sourceforge.htmlunit</groupId>
            <artifactId>htmlunit</artifactId>
            <version>2.45.0</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.12.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--强制maven以jdk8编译-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!--打包时包将所有依赖打进去-->
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>Main</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

代码

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import javax.swing.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.logging.LogManager;

public class Main {
    public static void main(String[] args) {
        LogManager.getLogManager().reset();
//        预期卖出价
        float expectPrice = 399;
//        预期买入价
        float lowPrice = 390;
//        间隔时间 默认2s
        long sec = 2000;
//        请求等待时间
        long reqSec = 5000;
        for (int i = 0; i <= 3; i++) {
            if (args.length > 0 && i == 0)
                expectPrice = Float.parseFloat(args[0]);
            if (args.length > 1 && i == 1)
                lowPrice = Float.parseFloat(args[1]);
            if (args.length > 2 && i == 2)
                sec = Long.parseLong(args[2]);
            if (args.length > 3 && i == 3)
                reqSec = Long.parseLong(args[3]);
        }
        System.out.println("数据加载中请稍候……");
        WebClient webClient = new WebClient(BrowserVersion.CHROME);//模拟CHROME浏览器
        try {
            webClient.setJavaScriptTimeout(5000);
            webClient.getOptions().setUseInsecureSSL(true);//接受任何主机连接 无论是否有有效证书
            webClient.getOptions().setJavaScriptEnabled(true);//设置支持javascript脚本
            webClient.getOptions().setCssEnabled(false);//禁用css支持
            webClient.getOptions().setThrowExceptionOnScriptError(false);//js运行错误时不抛出异常
            webClient.getOptions().setTimeout(100000);//设置连接超时时间
            webClient.getOptions().setDoNotTrackEnabled(false);
            HtmlPage page = webClient.getPage("https://m.jdjygold.com/finance-gold/newgold/index/?ordersource=2&jrcontainer=h5&jrlogin=true&utm_source=Android_url_1609033920704&utm_medium=jrappshare&utm_term=wxfriends");
//                加载js需要时间故延迟默认5s
            Thread.sleep(reqSec);
            while (true) {
//                使用Jsoup解析html
                Document document = Jsoup.parse(page.asXml());
                Elements span01 = document.getElementsByClass("price_span01");
                String price = span01.text();
                String localeString = new Date().toLocaleString();
                System.out.println(localeString + " " + price);
                String msg = localeString + "价格已达到预定值:" + price;
                String lowMsg = localeString + "价格已低于预定值:" + price;
                float goldPrice = Float.parseFloat(price);
                if (msg != null && goldPrice >= expectPrice) {
                    JOptionPane.showConfirmDialog(null, msg, "达到预期卖出价提示", JOptionPane.CLOSED_OPTION);
//                若部署在服务器上则使用Server酱提醒
//                getUrl("https://sc.ftqq.com/xxxxxxxxxxxxxx.send?text="+msg);
                    return;
                }
                if (msg != null && goldPrice <= lowPrice) {
                    JOptionPane.showConfirmDialog(null, lowMsg, "低于预期买入价提示", JOptionPane.CLOSED_OPTION);
//                getUrl("https://sc.ftqq.com/xxxxxxxxxxxxxx.send?text="+lowMsg);
                    return;
                }
                Thread.sleep(sec);
            }
        } catch (FailingHttpStatusCodeException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (MalformedURLException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } finally {
            webClient.close();
        }
    }

    public static void getUrl(String toUrl) throws IOException {
        URL url = new URL(toUrl);
        //建立连接
        URLConnection urlConnection = url.openConnection();
        //连接对象类型转换
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        //设定请求方法
        httpURLConnection.setRequestMethod("GET");
        //获取字节输入流信息
        InputStream inputStream = httpURLConnection.getInputStream();
        //字节流转换成字符流
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
        //把字符流写入到字符流缓存中
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = null;
        //读取缓存中的数据
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        //关闭流
        inputStream.close();
    }
}

使用方法

打包后直接执行命令

java -jar xxx.jar 390 360

第一个数字为预期卖出价;第二个为预期买入价,即当价格高于390或低于360提醒并关闭程序。

第三个参数设置间隔时间,单位毫秒;第四个参数设置请求等待时间,即启动时加载数据的等待时间,有时候网络不好时间短可能加载不出来,代码不填时默认5s,一般足矣无需带第四个参数。例如:

java -jar goldNotice-1.0-SNAPSHOT-jar-with-dependencies.jar 400 391.6 2500 3000

在服务器上部署请配置Server酱key并将弹窗代码注释。更多拓展可自行修改代码。

目录导航
  • 依赖
  • 代码
  • 使用方法