使用htmlunit爬取同花順網站數據


背景

周末閑來無事,想做一個財報分析軟件,然后就想從同花順獲取數據,主要是想下載三大報表,下載地址是http://basic.10jqka.com.cn/api/stock/export.php?export=debt&type=year&code=600519,

然后問題來了,這個訪問是不需要登錄的,在瀏覽器直接點擊就能下載,但是使用HttpURLConnection來獲取的時候就報401,經過分析是缺少cookie,然后去網站上copy了一個cookie,放上去可以獲取數據了,然后過幾分鍾,cookie就失效了。

查找原因

把地址拿到postman中訪問,返回了一段js,可以看到把地址又重新訪問了一下,說明這段js對cookie做了修改

<html>

<body>
	<script type="text/javascript" src="//s.thsi.cn/js/chameleon/chameleon.min.1621682.js"></script>
	<script src="//s.thsi.cn/js/chameleon/chameleon.min.1621682.js" type="text/javascript"></script>
	<script language="javascript" type="text/javascript">
		window.location.href="//basic.10jqka.com.cn/api/stock/export.php?export=debt&type=year&code=000895";
	</script>
</body>

</html>

然后我納悶了,為什么瀏覽器里面可以直接下載呢?原因是我事先已經訪問了該頁面,cookie已經生成好了,於是把瀏覽器的緩存清空,再去下載,就沒反應了,也就是說首次直接訪問上面的地址其實是無法下載的,

然后清空cookie,在chameleon.min.1621682.js這個js中的setCookie的幾個地方打斷點,可以發現每隔幾秒setCookie就會執行一次,v對應的值就會改變,cookie如下,

由於代碼比較復雜,想去分析js是如何操作的不太現實。所以就想到了使用selenium之類的解決方法。最后無意間找到了htmlunit。

解決方案

由於上面的原因,想要僅僅通過HttpURLConnection來實現是不可能的了,最終發現htmlunit可以執行js,並且能實現跳轉,正好滿足要求,使用方式如下:

1、引入maven

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

2、編寫代碼

private InputStream downloadSheet(String urlStr) {
        try {
            WebClient webclient = new WebClient(BrowserVersion.CHROME); // 設置瀏覽器版本
            webclient.getOptions().setTimeout(10 * 1000);//設置超時時間
            webclient.getOptions().setRedirectEnabled(true);//啟用跳轉
            webclient.getOptions().setThrowExceptionOnFailingStatusCode(false);
            webclient.getOptions().setUseInsecureSSL(true);
            webclient.getOptions().setJavaScriptEnabled(true); // 啟用javascript
            webclient.getOptions().setThrowExceptionOnScriptError(false); // 關閉js的異常拋出
            webclient.getOptions().setCssEnabled(false); // 不加載CSS文件
            webclient.getCookieManager().setCookiesEnabled(true);
            webclient.setJavaScriptTimeout(600 * 1000);
            webclient.waitForBackgroundJavaScript(60 * 1000);
            webclient.setAjaxController(new NicelyResynchronizingAjaxController());
            webclient.setRefreshHandler(new ImmediateRefreshHandler());
            Page page = webclient.getPage(urlStr);
            InputStream is = page.getWebResponse().getContentAsStream();
            return is;
        }catch (Exception e){
            
        }
        return null;
    }

由於第一次使用,對這個框架不熟,由於沒有setThrowExceptionOnFailingStatusCode,最開始也是報401,最終一路摸索,終於可以拿到流了,由於是下載excel,只需要拿到流丟給easyExcel讀取就行了,到這里就結束了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM