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

时间:2017-05-09 13:28:32

标签: javascript java web-scraping kotlin htmlunit

我正在尝试使用HtmlUnit加载Playstation Store页面,但看起来它加载的所有内容都是带有“正在加载...”文本(以及一些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

可以毫无困难地打开。

2 个答案:

答案 0 :(得分:0)

这称为SPA - Single Page Application。通常,SPA只有基本标记,一个容器,整个UI使用ReactAngular等框架动态呈现。

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客户端不完全模拟浏览器,也不执行该脚本。这就是你看到一个空页面的原因。

答案 1 :(得分:0)

至少这个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)

来自您的设置代码。这些方法没有设置任何选项;他们正在执行时等待。