什么阻止HtmlUnit加载PSN商店页面?

我试图用HtmlUnit加载Playstation商店页面,但看起来像加载的所有内容是“加载…”文本(和一点点的JavaScript)的空白页面。 我使用下面的配置使HtmlUnit工作,但绝望(它的kotlin):

@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")) } 

我在加载页面时看不到任何特定的错误:

 мая 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 

问题是:什么阻止HtmlUnit加载页面? 我试图自己弄明白,但我唯一的想法是,它可能是对无头浏览器的某种防御或HtmlUnit不支持的非常重的JS。 但是,例如

https://account.sonyentertainmentnetwork.com

可以打开没有任何麻烦。

这被称为SPA – 单页面应用程序 。 一般来说,SPA只有基本的标记,一个容器,而且整个UI都是用React或Angular等框架动态呈现的。

https://store.playstation.com剥离脚本和样式后剩下的是&#xFF1A;

 <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) 

从您的设置代码。 这些方法不设置任何选项; 他们正在执行等待的时间。