阻止HtmlUnit加载PSN商店页面?
我试图用对的HtmlUnit加载的Playstation Store页面,但看起来像它加载与“正在加载...”文本(和一些JavaScript)空白页的一切。 我用下面的配置,使工作的HtmlUnit,但绝望(其科特林):阻止HtmlUnit加载PSN商店页面?
мая 09, 2017 4:08:22 PM com.gargoylesoftware.htmlunit.html.HtmlScript isExecutionNeeded
WARNING: Script is not JavaScript (type: application/json, language:). Skipping execution.
мая 09, 2017 4:08:22 PM com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController processSynchron
INFO: Re-synchronized call to https://sonynetworkentertainment.112.2o7.net/b/ss/snestorewebloadglobal/1/chidv1/s75296982536092?AQB=1&ndh=1&t=9%2F5%2F2017%2016%3A8%3A22%202%20-180&ts=1494335302&vid=c61f4752-adfd-84d1-728c-187350f9aa37&pageName=web%3Aloading_start&v1=D%3DpageName&g=https%3A%2F%2Fstore.playstation.com%2F&r=&v2=xx-xx&ch=web%3Aloading_start&c68=D%3Dg&c72=web&v72=web&cc=USD&ce=UTF-8&server=web&events=event1&AQE=1
мая 09, 2017 4:08:22 PM com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController processSynchron
INFO: Re-synchronized call to https://store.playstation.com/kamaji/api/chihiro/00_09_000/geo
的问题是:什么停止
@Test
@Throws(Exception::class)
fun homePage() {
val webClient = WebClient(BrowserVersion.INTERNET_EXPLORER).apply {
ajaxController = NicelyResynchronizingAjaxController()
options.isUseInsecureSSL = true
options.isThrowExceptionOnScriptError = false
options.isJavaScriptEnabled = true
options.isCssEnabled = true
options.isRedirectEnabled = true
options.isThrowExceptionOnFailingStatusCode = false
options.isUseInsecureSSL = true
options.isDownloadImages = true
cookieManager.isCookiesEnabled = true
waitForBackgroundJavaScript(10000)
waitForBackgroundJavaScriptStartingBefore(10000)
}
val page = webClient.getPage<HtmlPage>("https://store.playstation.com/")
Thread.sleep(10000)
assertFalse(page.asXml().contains("Loading"))
}
我不加载页面时看到任何具体的错误HtmlUnit从加载页面?我试图自己弄明白,但我唯一的想法是,它可能是针对无头浏览器的某种防御或HtmlUnit不支持的非常重的JS。但对于例如
可以没有任何麻烦地打开。
这就是所谓的SPA - Single Page Application。一般来说,SPA只有基本的标记,一个容器,整个用户界面是用框架动态呈现的,如React或Angular。
从https://store.playstation.com剩下剥离脚本和样式后是:
<div id="waitAppLoading">
<div class="waitHorizon">
<div class="centerBox">
<div class="logoCtnr"></div>
<div class="textBox"><div class="spinCtnr"></div><div id="appLoadingMsg"></div></div>
<div class="startupErr"></div>
</div>
</div>
</div>
<div id="appRoot" class="hidden"></div>
<div id="lockdownScreen"></div>
<div id="global-wait">
<div class="waitHorizon">
<div class="waitContainer">
<div class="sq1"></div>
<div class="sq2"></div>
<div class="sq3"></div>
<div class="sq4"></div>
<div class="sq5"></div>
<div class="sq6"></div>
</div>
</div>
<div id="global-ps-loader">
</div>
</div>
<div id="notifierCtnr" class="mainCol"><div id="notifier-box"></div></div>
<div id="storeNotAvail"></div>
<div class="dimToolEl dimToolElProdTitle"></div>
<div class="dimToolEl dimToolElProdSubTitle"></div>
<div id="transact-iframe-container">
<iframe id="transact-iframe"></iframe>
</div>
正如你看到的,这里没有内容,只为应用线框。 Web客户端不能完全模拟浏览器,也不会执行该脚本。这就是为什么你看到一个空的页面。
至少这java代码在这里工作。我在真正的FF中获得了语言选择对话框。 我使用最新的HtmlUnit代码。这通常是一个好主意。
String url = "https://store.playstation.com/";
try (final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_52)) {
final HtmlPage page = webClient.getPage(url);
webClient.waitForBackgroundJavaScript(1000 * 10);
System.out.println("----------------");
System.out.println(page.asText());
System.out.println("----------------");
HtmlElement btn = page.querySelector(".btn");
System.out.println(btn.asXml());
System.out.println("----------------");
}
并请删除通话
waitForBackgroundJavaScript(10000)
waitForBackgroundJavaScriptStartingBefore(10000)
从您的设置代码。这些方法不设置任何选项;他们在执行时正在等待。
哦!所以应该调用这些方法,而不是Thread.sleep()。然后,可能会有助于克服“加载”屏幕。将尝试,谢谢 – Ilya
谢谢你,我知道这是SPA。但是HtmlUnit可以处理JS请求,它实际上可以在一些SPA中工作。看起来我已经用错了方式等待JS执行 – Ilya