2012-10-21 22 views
10

Ich versuche, XLS-Datei für eine Website herunterladen. Wenn ich auf den Link klicke, um die Datei herunterzuladen, erhalte ich ein Javascript-Bestätigungsfeld. Ich handle es wie untenDatei herunterladen mit HtmlUnit

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

Es gibt einen Link zum Download der Datei.

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

klicke ich auf den Link mit

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

handeConfirm() -Methode excuted wird. Aber ich habe keine Ahnung, wie man den Dateistrom vom Server speichert. Ich habe versucht, den Stream mit dem Code unten zu sehen.

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

Aber das Ergebnis ist das gleiche wie die Seite x. Weiß jemand, wie man den Strom vom Server erfasst? Vielen Dank.

+0

'anchor.click()' eine Seite zurück. Das sollte Ihre XLS-Datei enthalten – Lee

+0

siehe meine Antwort auf eine ähnliche Frage unter http://StackOverflow.com/a/28471835/612123 – culmat

Antwort

7

Ich habe einen Weg gefunden, InputStream mit WebWindowListener zu erhalten. Innerhalb von webWindowContentChanged (WebWindowEvent-Ereignis) habe ich den Code unten eingefügt.

Nachdem ich xls bekomme, könnte ich die Datei auf meiner Festplatte speichern.

+0

Ich lade eine CSV-Datei, können Sie pls erklären, was Ereignis ist und wann rufen Sie den Klick Ereignis auf Anker. Ich habe keine Bestätigungsbox zum Herunterladen der Datei. – Naveen

8

Ich machte es basierend auf Ihrem Beitrag .. Hinweis: Sie können den Inhaltstyp Bedingung für den Download nur bestimmte Art von Datei ändern. zB (application/octect-stream, application/pdf usw.).

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

Es tut mir leid, aber ich verstehe es nicht, wo oder wie genau halten Sie den Verweis auf "Webclient" in 'modifywebclient' Methode ...... Danke –

+1

https://selenium.googlecode.com/svn/trunk/ docs/api/java/org/openqa/Selen/Htmlunit/HtmlUnitDriver.html # modifyWebClient (com.gargoylesoftware.htmlunit.WebClient) Anudeep Samaiya ist eine Methode der übergeordneten Klasse .. wir es das Hinzufügen eines Handle außer Kraft setzen kann, um zu bestätigen Fenster der Download-Datei .. Aber Sie müssen den Inhaltstyp ändern warten in Ihrem Fall. –

+0

Wirklich tut es eine Magie .. Arbeitet reibungslos. – viralpatel

2

Es gibt einen einfacheren Weg, wenn Sie HtmlUnit nicht mit Selenium umhüllen möchten. Stellen Sie den WebClient von HtmlUnit einfach mit dem erweiterten WebWindowListener bereit.

Sie können Apache commons.io auch zum einfachen Streamen verwenden.

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

Abbildung aus der Download-URL, und es in List kratzen. Von der Download-URL können wir die gesamte Datei mit diesem Code abrufen.

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(); 
    }