HtmlUnit не может получить страницу после загрузки файла - PullRequest
4 голосов
/ 08 ноября 2011

У меня странная проблема с HtmlUnit в Java. Я использую его для загрузки некоторых данных с веб-сайта, процесс выглядит примерно так:

1 - Логин

2 - за каждый элемент (автомобили)

----- 3 Поиск автомобиля

----- 4 Скачать zip-файл по ссылке

Код:

Создание веб-клиента:

webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
webClient.setJavaScriptEnabled(true);
webClient.setThrowExceptionOnScriptError(false);
DefaultCredentialsProvider provider = new DefaultCredentialsProvider();
provider.addCredentials(USERNAME, PASSWORD);
webClient.setCredentialsProvider(provider);
webClient.setRefreshHandler(new ImmediateRefreshHandler());

Логин:

  public void login() throws IOException
  {
    page = (HtmlPage) webClient.getPage(URL);
    HtmlForm form = page.getFormByName("formLogin");

    String user = USERNAME;
    String password = PASSWORD;

    // Enter login and password
    form.getInputByName("LoginSteps$UserName").setValueAttribute(user);
    form.getInputByName("LoginSteps$Password").setValueAttribute(password);

    // Click Login Button
    page = (HtmlPage) form.getInputByName("LoginSteps$LoginButton").click();

    webClient.waitForBackgroundJavaScript(3000);

    // Click on Campa area
    HtmlAnchor link = (HtmlAnchor) page.getElementById("ctl00_linkCampaNoiH");
    page = (HtmlPage) link.click();

    webClient.waitForBackgroundJavaScript(3000);
    System.out.println(page.asText());
  }

Поиск авто на сайте:

private void searchCar(String _regNumber) throws IOException
 {
// Open search window
page = page.getElementById("search_gridCampaNoi").click();

webClient.waitForBackgroundJavaScript(3000);

// Write plate number
HtmlInput element = (HtmlInput) page.getElementById("jqg1");
element.setValueAttribute(_regNumber);

webClient.waitForBackgroundJavaScript(3000);

// Click on search
HtmlAnchor anchor = (HtmlAnchor) page.getByXPath("//*[@id=\"fbox_gridCampaNoi_search\"]").get(0);
page = anchor.click();

webClient.waitForBackgroundJavaScript(3000);
System.out.println(page.asText());
}

Загрузить pdf:

    try
    {
      InputStream is = _link.click().getWebResponse().getContentAsStream();
      File path = new File(new File(DOWNLOAD_PATH), _regNumber);
      if (!path.exists())
      {
        path.mkdir();
      }
      writeToFile(is, new File(path, _regNumber + "_pdfs.zip"));
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

Проблема:

Первая машина работает нормально, pdf загружается, но как только я ищу новую машину, когда попадаю в эту строку:

page = page.getElementById("search_gridCampaNoi").click();

Я получаю это исключение:

Exception in thread "main" java.lang.ClassCastException: com.gargoylesoftware.htmlunit.UnexpectedPage cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlPage

После отладки я понял, что в тот момент, когда я делаю этот вызов:

InputStream is = _link.click().getWebResponse().getContentAsStream();

тип возвращаемого значения page.getElementById ("search_gridCampaNoi"). Click () изменяется с HtmlPage на WebResponse, поэтому вместо получения новой страницы я снова получаю файл, который я уже скачал.

Несколько скриншотов отладчика, показывающих эту ситуацию:

Первый звонок, тип возврата ОК:

enter image description here

Второй вызов, тип возврата изменен и я больше не получаю HtmlPage:

enter image description here

Заранее спасибо!

1 Ответ

9 голосов
/ 10 ноября 2011

На всякий случай, если кто-то сталкивается с той же проблемой, я нашел обходной путь. Изменение строки:

InputStream is = _link.click().getWebResponse().getContentAsStream();

до

InputStream is = _link.openLinkInNewWindow().getWebResponse().getContentAsStream();

, кажется, делает трюк. У меня проблемы сейчас при выполнении нескольких итераций, иногда это работает, иногда нет, но по крайней мере у меня что-то есть сейчас.

...