成品展示:
(博主手殘黨)
完整成品:http://myspace123.qiniudn.com/456.html
源碼:https://github.com/xcr1234/overwatch
在入坑前先看一下之前的博文吧!從爬取湖北某高校hub教務系統課表淺談Java信息抓取的實現
暴雪爸爸在守望先鋒的官網上提供了一個生涯數據的查詢,可惜沒有提供相關的API,“無法通過公開渠道自由抓到完整數據”。因此是通過模擬登陸、解析html的方式獲取數據
1.開發環境
httpclient抓取頁面數據
jsoup解析html
mozilla rhino執行js代碼
2。抓包
使用fiddler抓包,暴雪的登錄接口是
這里面的csrftoken和sessionTimeout在頁面上有,useSrp、persistLogin、fp都是常量,password是占位符
主要需要解決的問題就是publicA(公鑰)和clientEvidenceM1(憑據)
3.生成公鑰和憑據
不用在意publicA(公鑰)和clientEvidenceM1(憑據)的意義,這兩個是從login.js的onSuccess方法中生成出來的。其中login.js使用了srp.js的對象SrpClientSession,直接使用rhino執行onSuccess的方法就行了。
(需要的moduls,generator等參數從一個csrf-token的api中獲取)
由於srp.js很大,rhino執行時很慢,因此先用rhino compiler編譯成srp.class文件,用PluginClassLoader動態加載進來執行。編譯后的class是實現了Script接口的,它有一個public Object exec(Context cx, Scriptable scope);方法,用來執行自身。
4、附錄
a.非常重要的設置
HttpClient的Cookie不正確,報invalid cookie header的錯誤。
RequestConfig.Builder builder = RequestConfig.custom(); builder.setCookieSpec(CookieSpecs.STANDARD); RequestConfig config = builder.build(); httpPost.setConfig(config); //httpGet.setConfig(config);
b.創建classloader時,應該使用AccessController.doPrivileged方法。
c.rhino的Context,Scope,Script應該在同一個線程中執行。

1 loginForm.csrfToken.val(e.csrf_token), this.password = this.inputPassword.val(), 2 3 this.srpClientSession = new SrpClientSession(e.modulus, e.generator, e.hash_function), 4 5 6 this.srpClientCredentials = this.srpClientSession.step1(e.username, this.password, e.salt, e.public_B), 7 8 null !== this.password && this.inputPassword.val(Array(this.password.length + 1).join(this.passwordFill)), 9 10 this.inputUseSrp.val("true"), 11 this.inputPublicA.val(this.srpClientCredentials.publicA.toString(16)), 12 13 this.inputClientEvidenceM1.val(this.srpClientCredentials.clientEvidenceM1.toString(16))

// 在原來的基礎上加了var navigator = {}; 以免rhino報錯 // https://github.com/xcr1234/overwatch/blob/master/src/main/resources/srp.js
5。問題
在登錄成功后自動跳轉(redirect)有問題,目前只能手動跳轉