废话不多说部分代码如下,主要记录个别功能点:
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, MultiValueMapparameters) { 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 MapallList() { 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: 本文目的为了记录不常用技术点,以上伪代码并不能直接运行。如果有需要全部代码学习的也可以联系我,期待与各位的技术交流。