2

を含むstackoverflowで見つけたさまざまな方法を使用して.pdfファイルを保存しようとしましたFileUtils IOが、常に破損していました。メモ帳を使用して破損したファイルを開くと、次のものが得られました。

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

.pdf後で、 @BalusC から提供された回答を使用して、ブラウザーからファイルを保存しようとしました。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、ファイルは正常に保存されます。

4

4 に答える 4

3

PDFはaBinary Fileと見なされ、その方法がcopyUrlToFile()機能するため破損します。ところで、これはJava - Download Binary File (eg 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' /> 、クリックする代わりに URL を取得し、そのリンクから href を取得してダウンロードします。

String pdfPath = driver.findElement(By.id("someId")).getAttribute("href");
downloadBinaryFile(pdfPath);
于 2013-09-27T21:10:22.803 に答える
3

単なる HTML エラー ページのように見えるエラー応答から:

alert('セッションがタイムアウトしました。再度ログインしてください。\n');

したがって、有効な HTTP セッションで PDF ファイルをダウンロードする必要があるようです。HTTP セッションは Cookie によってサポートされています。通常、HTTP セッションには、現在アクティブなユーザーやログインしているユーザーに関する情報がサーバー側に含まれています。

Selenium Web ドライバーは、Cookie を完全に透過的に管理します。次のようにプログラムで取得できます。

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

Selenium の外部制御を手動でいじる場合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.
于 2013-09-30T15:43:30.150 に答える
2

サーバーが pdf を圧縮している可能性があります。この回答から盗んだこのコードを使用して、サーバーからの応答を検出して解凍できます。

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;
}
于 2013-09-30T04:31:48.473 に答える
1

CTRL+Shift+S を使用してファイルを手動で保存しようとすると、ファイルは正常に保存されます。

Java を使用してファイルをダウンロードすることをお勧めしますが、プログラムでCtrl+ Shift+を押すあまり推奨されない回避策があります。SRobot

回避策を使用するのは面倒ですが、私が試したブラウザーと OS でわかる限り、確実に動作します。このコードは、重大なアプリケーションには使用しないでください。ただし、問題を正しい方法で解決できない場合でも、テストは問題ありません。

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

私が知っているブラウザーと OS では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 `:`?を使用できます。および文字列を KeyEvents に変換します

于 2013-09-30T15:30:56.027 に答える