【问题标题】:What stops HtmlUnit from loading PSN store page?是什么阻止 HtmlUnit 加载 PSN 商店页面?
【发布时间】:2017-10-07 20:20:50
【问题描述】:

我正在尝试使用 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

可以轻松打开。

【问题讨论】:

    标签: javascript java web-scraping kotlin htmlunit


    【解决方案1】:

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

    【讨论】:

    • 谢谢,我知道是SPA。但是 HtmlUnit 可以处理 JS 请求,它实际上适用于一些 SPA。看起来我用错误的方式等待 JS 执行
    【解决方案2】:

    至少这个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()。然后,可能有助于克服“加载”屏幕。会试试的,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多