自动抢某房产抢车位,记录下可能用到的不常用技术

废话不多说部分代码如下,主要记录个别功能点:

1. 绕过Https的SSL认证:

RestTemplate restTemplate = restTemplate();

public RestTemplate restTemplate() {
    //忽略证书
    SSLContext sslContext = null;
    try {
        sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
                    throws java.security.cert.CertificateException {
                return true;
            }
        }).build();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    }

    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom()
            .setSSLSocketFactory(csf)
            .build();
    HttpComponentsClientHttpRequestFactory requestFactory =
            new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);
    RestTemplate restTemplate = new RestTemplate(requestFactory);
    //处理中文乱码
    restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    return restTemplate;
}

2.  发送Http请求并获取接口写入客户端的Header信息:

public String van(String url, HttpMethod method, MultiValueMap parameters) {
    HttpHeaders headers = getVankHeaders();
    HttpEntity> httpEntity = new HttpEntity(parameters, headers);

    ResponseEntity responseEntity = restTemplate.exchange(url, method, httpEntity, String.class);
    HttpHeaders entityHeaders = responseEntity.getHeaders();
    for (Map.Entry> stringListEntry : entityHeaders.entrySet()) {
        StringBuilder content = new StringBuilder("head-key = " + stringListEntry.getKey());
        for (String value : stringListEntry.getValue()) {
            content.append(" ; value = " + value);
        }
        System.out.println(content.toString());
    }
    String postForObject = responseEntity.getBody();
    return postForObject;
}

3.  构建请求头部信息:

public HttpHeaders getVankHeaders() {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    headers.add("Accept-Encoding", "gzip, deflate, br");
    headers.add("Accept-Language", "zh-cn");
    headers.add("Content-Type", "application/x-www-form-urlencoded");
    headers.add("Cookie", "");
    headers.add("Host", "mfang.van.com");
    headers.add("Origin", "");
    headers.add("Pragma", "no-cache");
    headers.add("Referer", "");
    headers.add("Sec-Fetch-Mode", "navigate");
    headers.add("Sec-Fetch-Site", "same-origin");
    headers.add("Sec-Fetch-User", "?1");
    headers.add("Content-Length", "79");
    headers.add("User-Agent", "");
    headers.add("X-Requested-With", "XMLHttpRequest");
    return headers;
}

4. Jsoup数据解析获取所有代抢车位:

/**
 * 所有代抢车位
 *
 * @return
 */
public Map allList() {
    Map idDes = new HashMap();
    Document document = Jsoup.parse(van(all, HttpMethod.GET, getHourseListValueMap()));
    Elements elementsByTag = document.getElementsByTag("a");
    for (Element element : elementsByTag) {
        String href = element.attr("href");
        String id;
        String desc;
        if (null == element.select("span").first()) {
            desc = element.select("a").first().text();
            id = "0";
        } else {
            id = href.substring(href.indexOf("Details") + 8, href.length());
            desc = element.select("span").first().text();
        }
        idDes.put(Long.parseLong(id), desc);
        System.out.println("id = " + id + " ; desc = " + desc);
    }
    return idDes;
}

5.  解析获取具体,并提取Csrf防护Token:

/**
 * 房间详情获取确认token
 *
 * @param id
 * @return
 */
public String[] detail(long id) {
    String allHtml = van(detail + id, HttpMethod.GET, getHourseDetailValueMap(id));
    Document document = Jsoup.parse(allHtml);
    String token = document.select("input[name=xxx]").first().attr("value");
    Elements elementsByTag = document.getElementsByTag("script");
    for (Element element : elementsByTag) {
        String[] data = element.data().toString().split("var");
        for (String datum : data) {
            if (datum.contains("=") && datum.contains("activityJson")) {
                String val = datum.split("=")[1].trim();
                Map parseObject = JSON.parseObject(val.substring(0, val.lastIndexOf(";")), Map.class);
                String rowId = parseObject.get("ID").toString();
                String CurrentPrice = parseObject.get("CurrentPrice").toString();
                String OpenType = parseObject.get("OpenType").toString();
                System.out.println(String.format("id = %s ; CurrentPrice = %s ; OpenType = %s", rowId, CurrentPrice, OpenType));
                return new String[]{rowId, CurrentPrice, OpenType, token};
            }
        }
    }
    return new String[]{};
}

6. 确认选购:

/**
 * 确认选购
 *
 * @param id
 * @TODO 部分请求参数需要替换
 */
public void activityTraget(String id, String price, String openType, String token) throws InterruptedException {
    String van = van(addAcivityTarget, HttpMethod.POST, getActivityTargetValueMap(id, price, openType, token));
    System.out.println("抢购结果 = " + van);
    Thread.sleep(10);
}

7. 剩下的交给时间。

PS: 本文目的为了记录不常用技术点,以上伪代码并不能直接运行。如果有需要全部代码学习的也可以联系我,期待与各位的技术交流。

 

你可能感兴趣的:(Java,房产)