2012-10-21 15 views
10

Próbuję pobrać plik Xls dla witryny. Kiedy kliknę link, aby pobrać plik, otrzymuję okno potwierdzenia javascript. Obsługuję go poniżej:Pobierz plik przy użyciu narzędzia HtmlUnit

ConfirmHandler okHandler = new ConfirmHandler(){ 
      public boolean handleConfirm(Page page, String message) { 
       return true; 
      } 
     }; 
    webClient.setConfirmHandler(okHandler); 

Istnieje łącze do pobrania pliku.

<a href="./my_file.php?mode=xls&amp;w=d2hlcmUgc2VsbElkPSd3b3JsZGNvbScgYW5kIHN0YXR1cz0nV0FJVERFTEknIGFuZCBkYXRlIDw9IC0xMzQ4MTUzMjAwICBhbmQgZGF0ZSA%2BPSAtMTM1MDgzMTU5OSA%3D" target="actionFrame" onclick="return confirm('Do you want do download XLS file?')"><u>Download</u></a> 

klikam odnośnik stosując metodę

HTMLPage x = webClient.getPage("http://working.com/download"); 
HtmlAnchor anchor = (HtmlAnchor) x.getFirstByXPath("//a[@target='actionFrame']"); 
anchor.click(); 

handeConfirm() jest uruchamiane. Ale nie mam pojęcia, jak zapisać strumień plików z serwera. Próbowałem zobaczyć strumień z kodem poniżej.

anchor.click().getWebResponse().getContentAsString(); 

Ale wynik jest taki sam jak strona x. Ktoś wie, jak przechwycić strumień z serwera? Dziękuję Ci.

+0

'anchor.click()' powróci stronę. To powinno contianować twój plik XLS – Lee

+0

zobacz moją odpowiedź na podobne pytanie na http://stackoverflow.com/a/28471835/612123 – culmat

Odpowiedz

7

Znalazłem sposób na uzyskanie InputStream przy użyciu WebWindowListener. Wewnątrz webWindowContentChanged (zdarzenie WebWindowEvent) umieszczam poniższy kod.

InputStream xls = event.getWebWindow().getEnclosedPage().getWebResponse().getContentAsStream(); 

Po uzyskaniu xls, mógłbym zapisać plik na dysku twardym.

+0

Pobieram plik csv, czy możesz wyjaśnić, co jest zdarzeniem i kiedy dzwonisz klikając wydarzenie na kotwicy. Nie mam pola potwierdzenia pobierania pliku. – Naveen

8

Zrobiłem to na podstawie Twojego wpisu. Uwaga: możesz zmienić typ zawartości, aby pobrać tylko określony typ pliku. np. (aplikacja/strumień literowy, aplikacja/pdf, itp.).

package net.s4bdigital.export.main; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.util.List; 

import org.junit.Before; 
import org.junit.Test; 
import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.htmlunit.HtmlUnitDriver; 

import com.gargoylesoftware.htmlunit.ConfirmHandler; 
import com.gargoylesoftware.htmlunit.Page; 
import com.gargoylesoftware.htmlunit.WebClient; 
import com.gargoylesoftware.htmlunit.WebResponse; 
import com.gargoylesoftware.htmlunit.WebWindowEvent; 
import com.gargoylesoftware.htmlunit.WebWindowListener; 
import com.gargoylesoftware.htmlunit.util.NameValuePair; 

public class HtmlUnitDownloadFile { 

    protected String baseUrl; 
    protected static WebDriver driver; 

    @Before 
    public void openBrowser() { 
     baseUrl = "http://localhost/teste.html"; 
     driver = new CustomHtmlUnitDriver(); 
     ((HtmlUnitDriver) driver).setJavascriptEnabled(true); 

    } 


    @Test 
    public void downloadAFile() throws Exception { 

     driver.get(baseUrl); 
     driver.findElement(By.linkText("click to Downloadfile")).click(); 

    } 

    public class CustomHtmlUnitDriver extends HtmlUnitDriver { 

      // This is the magic. Keep a reference to the client instance 
      protected WebClient modifyWebClient(WebClient client) { 


      ConfirmHandler okHandler = new ConfirmHandler(){ 
        public boolean handleConfirm(Page page, String message) { 
         return true; 
        } 
      }; 
      client.setConfirmHandler(okHandler); 

      client.addWebWindowListener(new WebWindowListener() { 

       public void webWindowOpened(WebWindowEvent event) { 
        // TODO Auto-generated method stub 

       } 

       public void webWindowContentChanged(WebWindowEvent event) { 

        WebResponse response = event.getWebWindow().getEnclosedPage().getWebResponse(); 
        System.out.println(response.getLoadTime()); 
        System.out.println(response.getStatusCode()); 
        System.out.println(response.getContentType()); 

        List<NameValuePair> headers = response.getResponseHeaders(); 
        for(NameValuePair header: headers){ 
         System.out.println(header.getName() + " : " + header.getValue()); 
        } 

        // Change or add conditions for content-types that you would to like 
        // receive like a file. 
        if(response.getContentType().equals("text/plain")){ 
         getFileResponse(response, "target/testDownload.war"); 
        } 



       } 

       public void webWindowClosed(WebWindowEvent event) { 



       } 
      });   

      return client; 
      } 


    } 

    public static void getFileResponse(WebResponse response, String fileName){ 

     InputStream inputStream = null; 

     // write the inputStream to a FileOutputStream 
     OutputStream outputStream = null; 

     try {  

      inputStream = response.getContentAsStream(); 

      // write the inputStream to a FileOutputStream 
      outputStream = new FileOutputStream(new File(fileName)); 

      int read = 0; 
      byte[] bytes = new byte[1024]; 

      while ((read = inputStream.read(bytes)) != -1) { 
       outputStream.write(bytes, 0, read); 
      } 

      System.out.println("Done!"); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (inputStream != null) { 
       try { 
        inputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      if (outputStream != null) { 
       try { 
        // outputStream.flush(); 
        outputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

      } 
     } 

    } 

} 
+1

Przykro mi, ale nie rozumiem, gdzie lub jak dokładnie zachowujesz odniesienie do "webclient" w metodzie 'modifywebclient' ... dzięki –

+1

https://selenium.googlecode.com/svn/trunk/ docs/api/java/org/openqa/selen/HtmlUnit/HtmlUnitDriver.html # modifyWebClient (com.gargoylesoftware.htmlunit.WebClient) Anudeep Samaiya to metoda klasy bazowej .. możemy zastąpić go dodając uchwyt, aby potwierdzić okna pobierania pliku. Ale potrzebujesz zmodyfikować typ zawartości czekający w twoim przypadku. –

+0

Naprawdę robi magię ... Działa płynnie. – viralpatel

2

Jest łatwiejszy sposób, jeśli nie pakujesz HtmlUnit z Selenium. Po prostu podaj WebClient HtmlUnit z rozszerzonym WebWindowListener.

Można również użyć Apache commons.io do łatwego kopiowania strumieniowego.

WebClient webClient = new WebClient(); 
webClient.addWebWindowListener(new WebWindowListener() { 
    public void webWindowOpened(WebWindowEvent event) { } 

    public void webWindowContentChanged(WebWindowEvent event) { 
     // Change or add conditions for content-types that you would 
     // to like receive like a file. 
     if (response.getContentType().equals("text/plain")) { 
      try { 
       IOUtils.copy(response.getContentAsStream(), new FileOutputStream("downloaded_file")); 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

    public void webWindowClosed(WebWindowEvent event) {} 
}); 
1
final WebClient webClient = new WebClient(BrowserVersion.CHROME); 
     webClient.getOptions().setTimeout(2000); 
     webClient.getOptions().setThrowExceptionOnScriptError(false); 
     webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); 
     webClient.waitForBackgroundJavaScript(2000); 

     //get General page 
     final HtmlPage page = webClient.getPage("http://your"); 

     //get Frame 
     final HtmlPage frame = ((HtmlPage) 
     page.getFrameByName("Frame").getEnclosedPage()); 

     webClient.setConfirmHandler(new ConfirmHandler() { 
      public boolean handleConfirm(Page page, String message) { 
       return true; 
      } 
     }); 

     //get element file 
     final DomElement file = mainFrame.getElementByName("File"); 

     final InputStream xls = file.click().getWebResponse().getContentAsStream(); 

     assertNotNull(xls); 
    } 
-1

dowiedzieć się pobrać adresu URL, i drapać go w wykazie. z adresu pobierania można pobrać cały plik za pomocą tego kodu.

try{ 
     String path = "your destination path"; 
     List<HtmlElement> downloadfiles = (List<HtmlElement>) page.getByXPath("the tag you want to scrape"); 
     if (downloadfiles.isEmpty()) { 
      System.out.println("No items found !"); 
     } else { 
      for (HtmlElement htmlItem : downloadfiles) { 
       String DownloadURL = htmlItem.getHrefAttribute(); 

       Page invoicePdf = client.getPage(DownloadURL); 
       if (invoicePdf.getWebResponse().getContentType().equals("application/pdf")) { 
        System.out.println("creatign PDF:"); 
        IOUtils.copy(invoicePdf.getWebResponse().getContentAsStream(), 
          new FileOutputStream(path + "file name")); 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
Powiązane problemy