2013-09-27 126 views
2

我試圖使用不同的方法保存.pdf文件,我發現在stackoverflow上,包括FileUtils IO,但是,我總是會損壞它。當我用記事本打開損壞的文件,我得到了以下的東西:如何從瀏覽器保存.pdf?

<HEAD> 

    <TITLE> 
     09010b129fasdf558a- 
    </TITLE> 

</HEAD> 


<HTML> 

<SCRIPT language="javascript" src="./js/windowClose.js"></SCRIPT> 

<LINK href="./theme/default.css" rel="stylesheet" type="text/css"> 
<LINK href="./theme/additions.css" rel="stylesheet" type="text/css"> 

<BODY leftmargin="0" topmargin="0"> 

<TABLE cellpadding="0" cellspacing="0" width="100%"> 
    <TR> 
     <TD class="mainSectionHeader"> 
      <A href="javascript:windowClose()" class="allLinks"> 
       CLOSE 
      </A> 
     </TD> 

    </TR> 

</TABLE> 

       <script language='javaScript'> 
        alert('Session timed out. Please login again.\n'); 
        window.close(); 
       </script> 



</BODY> 

</HTML> 

後來,我試着從使用@BalusC提供的答案瀏覽器保存.pdf文件。此解決方案非常有用:我能夠擺脫session問題。但是,它也會產生一個損壞的.pdf。但是當我用記事本打開它時,情況完全不同。沒有登錄問題了,但:

<HTML> 

    <HEAD> 

     <TITLE> 
      Evidence System 
     </TITLE> 

    </HEAD> 

<LINK href="./theme/default.css" rel="stylesheet" type="text/css"> 

<TABLE cellpadding="0" cellspacing="0" class="tableWidth760" align="center"> 
    <TR> 
     <TD class="headerTextCtr"> 
      Evidence System 
     </TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 
      <HR size="1" noshade> 
     </TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 



<HTML> 
<HEAD> 
<link href="./theme/default.css" rel="stylesheet" type="text/css"> 
<script language="JavaScript"> 

function trim(str) 
{ 
    var trmd_str 

    if(str != "") 
    { 
     trmd_str = str.replace(/\s*/, "") 
     if (trmd_str != ""){ 

      trmd_str = trmd_str.replace(/\s*$/, "") 
     } 

    }else{ 
     trmd_str = str 
    } 
    return trmd_str 
} 

function validate(frm){ 
    //check for User name 
    var msg=""; 
    if(trim(frm.userName.value)==""){ 
     msg += "Please enter your user id.\n"; 
     frm.userName.focus(); 
    } 

    if(trim(frm.password.value)==""){ 
     msg += "Please enter your password.\n"; 
     frm.userName.focus(); 
    } 

    if (trim(msg)==""){ 
     frm.submit(); 
    }else{ 
     alert(msg); 
    } 
} 

function numCheck(event,frm){ 
    if(event.keyCode == 13){ 
      validate(frm); 
    } 
} 

</script> 
</HEAD> 

<BODY onLoad="document.frmLogin.userName.focus();"> 

<FORM name='frmLogin' method='post' action='./ServletVerify'> 
    <TABLE width="100%" cellspacing="20"> 
     <tr> 
      <td class="mainTextRt"> 
       Username 
       <input type="text" name="userName" maxlength="32" tabindex="1" value="" 
       onKeyPress="numCheck(event,this.form)" class="formTextField120"> 
      </TD> 
      <td class="mainTextLt"> 
       Password 
       <input type="password" name="password" maxlength="32" tabindex="2" value="" 
       onKeyPress="numCheck(event,this.form)" class="formTextField120"> 
      </TD> 
     </TR> 

     <tr>      
      <td colspan="2" class="mainTextCtr" style="color:red"> 
       Unknown Error 
      </td> 
     </tr> 

     <tr> 
      <td colspan="2" class="mainTextCtr"> 
       <input type="button" tabindex="3" value="Submit" onclick="validate(this.form)" > 
      </TD> 
     </TR> 
    </TABLE> 

    <INPUT TYPE="hidden" NAME="actionFlag" VALUE="inbox"> 
</FORM> 

</BODY> 
</HTML> 

     </TD> 
    </TR> 
    <TR> 
     <TD height="2"></TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 
      <HR size="1" noshade> 
     </TD> 
    </TR> 
    <TR> 
     <TD colspan="2"> 
      <LINK href="./theme/default.css" rel="stylesheet" type="text/css"> 

<TABLE width="80%" align="center" cellspacing="0" cellpadding="0"> 
    <TR> 
     <TD class="footerSubtext"> 
      Evidence Management System 
     </TD> 
    </TR> 

    <!-- For development builds, change the date accordingly when sending EAR files out to Wal-Mart --> 
    <TR> 
     <TD class="footerSubtext"> 
      Build:&nbsp;&nbsp;v3.1 
     </TD> 
    </TR> 

</TABLE> 
     </TD> 
    </TR> 
</TABLE> 

</HTML> 

我有什麼其他選擇?

PS:當我嘗試使用CTRL+Shift+S手動保存文件時,文件被保存成OK。

+0

編輯我的回答Buras ..我認爲問題可能是位置。它試圖保存一個html文件而不是pdf。請參閱**編輯**部分,該部分將解釋「這不是二進制文件」以及讀者認爲它「已損壞」 – sircapsalot

回答

3

從中似乎只是一個HTML錯誤頁面的響應errorneous:

警報(「會話超時,請重新登錄\ n」);

因此,似乎下載PDF文件需要在有效的HTTP會話中進行。 HTTP會話由一個cookie支持。 HTTP會話通常在服務器端包含關於當前活動和/或登錄用戶的信息。

Selenium web驅動程序完全透明地管理cookie本身。您可以通過編程獲取它們如下:

Set<Cookie> cookies = driver.manage().getCookies(); 

當硒java.net.URL外控制手動擺弄,你應該確保自己的URL連接使用同樣的Cookie(因此也保持相同的HTTP會話) 。您可以在URL連接上設置cookie如下:

URLConnection connection = new URL(driver.getCurrentUrl()).openConnection(); 

for (Cookie cookie : driver.manage().getCookies()) { 
    String cookieHeader = cookie.getName() + "=" + cookie.getValue(); 
    connection.addRequestProperty("Cookie", cookieHeader); 
} 

InputStream input = connection.getInputStream(); // Write this to file. 
+0

非常感謝。其實我確實遇到過問題。現在,當我保存.pdf時,它仍然受損,但至少沒有會話問題。我發佈了使用記事本打開的已損壞文件的更新版本 – Buras

+0

driver.getCurrentUrl()是否返回PDF文件的URL或網頁本身?我已經發現它是可疑的,但指定錯誤的URL首先是一個太明顯的錯誤,我只是忽略了它。 – BalusC

+0

是的,它的確如此。我用system.out重新檢查它。打印 – Buras

3

PDF被認爲是Binary File,並且由於copyUrlToFile()工作的方式而被損壞。順便說一句,這個貌似JAVA - Download Binary File (e.g. PDF) file from Webserver

重複嘗試這種自定義的二進制下載方法了 -

public void downloadBinaryFile(String path) { 
    URL u = new URL(path); 
    URLConnection uc = u.openConnection(); 
    String contentType = uc.getContentType(); 
    int contentLength = uc.getContentLength(); 
    if (contentType.startsWith("text/") || contentLength == -1) { 
     throw new IOException("This is not a binary file."); 
    } 
    InputStream raw = uc.getInputStream(); 
    InputStream in = new BufferedInputStream(raw); 
    byte[] data = new byte[contentLength]; 
    int bytesRead = 0; 
    int offset = 0; 
    while (offset < contentLength) { 
     bytesRead = in.read(data, offset, data.length - offset); 
     if (bytesRead == -1) 
     break; 
     offset += bytesRead; 
    } 
    in.close(); 

    if (offset != contentLength) { 
     throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes"); 
    } 

    String filename = u.getFile().substring(filename.lastIndexOf('/') + 1); 
    FileOutputStream out = new FileOutputStream(filename); 
    out.write(data); 
    out.flush(); 
    out.close(); 
} 

編輯:它實際上聽起來好像你不是,你認爲你在頁面上..而不是做 driver.getCurrentUrl()

讓您的腳本從鏈接到PDF的URL。假設有一個像<a href='http://mysite.com/my.pdf' />這樣的鏈接,而不是點擊它,然後獲取網址,只需從該鏈接中獲取href並下載它。

String pdfPath = driver.findElement(By.id("someId")).getAttribute("href"); 
downloadBinaryFile(pdfPath); 
+0

再次感謝您。我得到異常:這不是一個二進制文件 – Buras

+0

看來'contentLength == -1 ... => 拋出新的IOException(「這不是一個二進制文件。」);' – Buras

+0

感謝您的更新。我使用'system.out.print'進行了雙重檢查:**驅動程序位於正確的URL **上。另外,由於'href =「javascript:viewDocument('0901asdasd09309d','093094defkjhsdf','23423432','General',''''),直接引用'href'會拋出'java.net.MalformedURLException:unknown protocol: -pleasae select','search','')「' – Buras

2

服務器可能正在壓縮pdf。您可以使用此代碼,從this answer被盜檢測並解壓縮從服務器的響應,

InputStream is = driver.getCurrentUrl().openStream(); 
try { 
    InputStream decoded = decompressStream(is); 
    FileOutputStream output = new FileOutputStream(
     new File("C:\\Users\\myDocs\\myfolder\\myFile.pdf")); 
    try { 
     IOUtils.copy(decoded, output); 
    } 
    finally { 
     output.close(); 
    } 
} finally { 
    is.close(); 
} 

public static InputStream decompressStream(InputStream input) { 
    PushBackInputStream pb = new PushBackInputStream(input, 2); //we need a pushbackstream to look ahead 
    byte [] signature = new byte[2]; 
    pb.read(signature); //read the signature 
    pb.unread(signature); //push back the signature to the stream 
    if(signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b) //check if matches standard gzip maguc number 
     return new GZIPInputStream(pb); 
    else 
     return pb; 
} 
+0

非常感謝。它確實將文件保存到目的地,但是,當我嘗試打開該文件時,「Adobe」說該文件已損壞。 – Buras

1

當我嘗試保存文件使用CTRL + SHIFT + S,該文件 被保存OK手動。

雖然我主張用Java來下載文件,還有一個不那麼建議的解決方法是按下Ctrl鍵++小號編程:本Robot類。

它使用一種解決方法很糟糕,但它可以可靠地工作,只要我可以在我嘗試的瀏覽器和操作系統中看到。此代碼不應該進入任何嚴重的應用程序。但如果您無法以正確的方式解決問題,則可以進行測試

Robot robot = new Robot(); 

按下Ctrl + Shift + S

robot.keyPress(KeyEvent.VK_CONTROL); 
robot.keyPress(KeyEvent.VK_SHIFT); 
robot.keyPress(KeyEvent.VK_S); 
robot.keyRelease(KeyEvent.VK_S); 
robot.keyRelease(KeyEvent.VK_SHIFT); 
robot.keyRelease(KeyEvent.VK_CONTROL); 

在瀏覽器和我知道的操作系統,你應該在文件名輸入Save file對話。您可以輸入您的絕對路徑:

robot.keyPress(KeyEvent.VK_C);  // C 
robot.keyRelease(KeyEvent.VK_C); 
robot.keyPress(KeyEvent.VK_COLON); // : (colon) 
robot.keyRelease(KeyEvent.VK_COLON); 
robot.keyPress(KeyEvent.VK_SLASH); ///(slash) 
robot.keyRelease(KeyEvent.VK_SLASH); 
// etc. for the whole file path 

robot.keyPress(KeyEvent.VK_ENTER); // confirm by pressing Enter in the end 
robot.keyRelease(KeyEvent.VK_ENTER); 

爲了得到鍵碼,你可以使用KeyEvent#getExtendedKeyCodeForChar()(Java 7+只),或How can I make Robot type a `:`?Convert String to KeyEvents

相關問題