2009-08-23 55 views
5

this question開始,關於使用最初隱藏在Javascript函數後面的Matlab訪問網頁上的PDF。我現在有一個URL可以讓我直接訪問頁面,這可以使用Matlab webrowser對象(PDF出現在屏幕上),但爲了保存後續處理的PDF,我似乎需要使用Matlab的urlread/urlwrite函數。但是,這些函數不提供提供身份驗證憑據的方法。如何使用Matlab urlread/urlwrite提供用戶名/密碼來訪問網絡資源?

我要如何Matlab的urlread/urlwrite功能提供用戶名/密碼?

回答

6

Matlab的urlread()函數有一個「PARAMS」的說法,但這些都是得到的URL編碼的CGI樣式參數。身份驗證是通過較低級別的HTTP請求參數完成的。 Urlread不支持這些,但您可以直接對Java URL類進行編碼以使用它們。

您也可以使用Sun的sun.misc.BASE64Encoder類以編程方式做Base 64編碼。這是一個非標準的類,不是標準Java庫的一部分,但是你知道使用Matlab發佈的JVM會擁有它,所以你可以通過編碼來獲得它。

下面是一個快速入門示範。

function [s,info] = urlread_auth(url, user, password) 
%URLREAD_AUTH Like URLREAD, with basic authentication 
% 
% [s,info] = urlread_auth(url, user, password) 
% 
% Returns bytes. Convert to char if you're retrieving text. 
% 
% Examples: 
% sampleUrl = 'http://browserspy.dk/password-ok.php'; 
% [s,info] = urlread_auth(sampleUrl, 'test', 'test'); 
% txt = char(s) 

% Matlab's urlread() doesn't do HTTP Request params, so work directly with Java 
jUrl = java.net.URL(url); 
conn = jUrl.openConnection(); 
conn.setRequestProperty('Authorization', ['Basic ' base64encode([user ':' password])]); 
conn.connect(); 
info.status = conn.getResponseCode(); 
info.errMsg = char(readstream(conn.getErrorStream())); 
s = readstream(conn.getInputStream()); 

function out = base64encode(str) 
% Uses Sun-specific class, but we know that is the JVM Matlab ships with 
encoder = sun.misc.BASE64Encoder(); 
out = char(encoder.encode(java.lang.String(str).getBytes())); 

%% 
function out = readstream(inStream) 
%READSTREAM Read all bytes from stream to uint8 
try 
    import com.mathworks.mlwidgets.io.InterruptibleStreamCopier; 
    byteStream = java.io.ByteArrayOutputStream(); 
    isc = InterruptibleStreamCopier.getInterruptibleStreamCopier(); 
    isc.copyStream(inStream, byteStream); 
    inStream.close(); 
    byteStream.close(); 
    out = typecast(byteStream.toByteArray', 'uint8'); %' 
catch err 
    out = []; %HACK: quash 
end 
+0

+1:很好的捕捉URLREAD的缺點。 – gnovice 2009-08-24 17:07:52

+0

整潔 - 我還沒有意識到它也很直接的做Base64編碼。因爲我不認爲系統管理員對我非傳統的訪問方法感興趣,因此暫停計劃 - 現在我不再使用pdf文件,而是收到「不要這樣做」的HTML頁面!真的很公平,切換到外交模式:oops: – 2009-08-24 18:37:07

-2

我不知道MATLAB,這只是一個猜測。

的函數文檔here列出的選項像這樣:

s = urlread('url','method','params') 

取決於他們使用什麼樣的身份驗證這可能會或可能無法正常工作,你會想使用POST方法。

​​

你必須看實際的請求HTML表單或查看螢火淨標籤,看看他的用戶名和密碼參數的實際名稱的/值。

0

事實證明,Intranet網站正在使用基本身份驗證,Matlab不支持這種基本身份驗證,但在Mathworks網站here上描述的解決方案工作正常。在第一個例子中,我使用Firebug來獲取我需要訪問的Base64編碼字符串,但是我也使用工具here進行了直接計算。我現在已將我的PDF報告文件保存到磁盤 - 這樣完成了工作。對於我的下一個技巧,我將其轉換成文本...

我的理解是,GET和POST方法是從基本的身份驗證方法不同,但基本的身份驗證是不是經常在開網使用。

+0

如果最終將長期解決他們的問題,請考慮將urlread()和urlreadwrite()複製到單獨的目錄並重命名它們。即使MathWorks告訴你這樣做,修改你的Matlab安裝也是有風險的,並且你需要將它安裝到每個單獨的安裝中。 – 2009-08-24 17:04:12

1

urlwrite_auth是下一個步驟,所以這裏是......

function [output,status]=urlwrite_auth(url, user, password,location,wanted) 
%URLWRITE_AUTH Like URLWRITE, with basic authentication 
% 
% location is where you want the file saved 
% wanted is the name of the file you want 
% Returns the output file which is now saved to location. 
% 
% Examples: 
% sampleUrl = 'http://browserspy.dk/password-ok.php'; 
% [output,status] = urlwrite_auth(sampleUrl, 'user', 'password', location, wanted); 


% Matlab's urlread() doesn't do HTTP Request params, so work directly with Java 
jUrl = java.net.URL(url); 
conn = jUrl.openConnection(); 
conn.setRequestProperty('Authorization', ['Basic ' base64encode([user ':' password])]); 
conn.connect() 
%note this calls the function below 

% Specify the full path to the file so that getAbsolutePath will work when the 
% current directory is not the startup directory and urlwrite is given a 
% relative path. 
file = java.io.File(location); 

% the path. 
try 
    file = file.getCanonicalFile; 
catch 
    error('MATLAB:urlwrite:InvalidOutputLocation','Could not resolve file "%s".',char(file.getAbsolutePath)); 
end 

% Open the output file. 
pathy=strcat(location,'\',wanted); 
try 
    fileOutputStream = java.io.FileOutputStream(pathy); 
catch 
    error('MATLAB:urlwrite:InvalidOutputLocation','Could not open output file "%s".',char(file.getAbsolutePath)); 
end 

% Read the data from the connection. 
try 
    inputStream = conn.getInputStream; 
     import com.mathworks.mlwidgets.io.InterruptibleStreamCopier; 
    % This StreamCopier is unsupported and may change at any time. 
    isc = InterruptibleStreamCopier.getInterruptibleStreamCopier; 
    isc.copyStream(inputStream,fileOutputStream); 
    inputStream.close; 
    fileOutputStream.close; 
    output = char(file.getAbsolutePath); 
catch 
    fileOutputStream.close; 
    delete(file); 
    if catchErrors, return 
    else error('MATLAB:urlwrite:ConnectionFailed','Error downloading URL. Your network  connection may be down or your proxy settings improperly configured.'); 
    end 
end 

status = 1; 


function out = base64encode(str) 
% Uses Sun-specific class, but we know that is the JVM Matlab ships with 
encoder = sun.misc.BASE64Encoder(); 
out = char(encoder.encode(java.lang.String(str).getBytes())); 
%this is the bit of code that makes it connect!!!! 

注意這是由Andrew答案從HTTP用戶名和密碼的網站下載文件的發展。

0

作爲更新這樣的:另一種選擇是新功能webread,你可以明確地給出了基本authenticaition用戶名和密碼。

options = weboptions('Username','user','Password','your password'); 
data = webread(url, options); 

這也可以被用於websavewebwrite。有關更多信息weboptionshere

相關問題