2009-08-23 5 views
5

Seguendo da this question, per quanto riguarda l'accesso a un PDF su una pagina Web utilizzando Matlab che è originariamente sepolto dietro una funzione Javascript. Ora ho un URL che mi permette di accedere direttamente alla pagina, funziona bene usando l'oggetto webrowser Matlab (il PDF appare sullo schermo), ma per salvare il PDF per l'elaborazione successiva mi sembra di aver bisogno di usare le funzioni di urlread/urlwrite di Matlab . Tuttavia, queste funzioni non forniscono alcun metodo per l'offerta di credenziali di autenticazione.Come posso fornire un nome utente/password per accedere a una risorsa Web usando Matlab urlread/urlwrite?

Come è possibile fornire nome utente/password per le funzioni di urlread/urlwrite di Matlab?

risposta

6

La funzione urlread() di Matlab ha un argomento "params", ma questi sono parametri in stile CGI che vengono codificati nell'URL. L'autenticazione viene eseguita con i parametri di richiesta HTTP di livello inferiore. Urlread non supporta questi, ma è possibile codificare direttamente contro la classe URL Java per utilizzarli.

È inoltre possibile utilizzare una classe Sun.misc.BASE64Encoder del Sun per eseguire la codifica Base 64 a livello di codice. Questa è una classe non standard, non parte della libreria standard di Java, ma tu sai che la spedizione JVM con Matlab ce l'avrà, quindi puoi farla franca con la codifica.

Ecco un modo rapido per mostrarlo in azione.

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: buona presa sulle carenze URLREAD. – gnovice

+0

Neat - Non mi ero reso conto che fosse così semplice fare anche la codifica Base64. Piani in attesa poiché non penso che il sysadmin abbia apprezzato i miei metodi di accesso non ortodossi - ora invece di un file pdf ottengo una pagina HTML "Do not do that"! Il che è abbastanza giusto, passando alla modalità diplomazia: oops: –

-2

Non conosco MATLAB, questa è solo un'ipotesi plausibile.

La documentazione funzione di here elenca le opzioni come in:

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

A seconda del tipo di autenticazione che utilizzare questo può o non può lavorare, si sta andando a voler usare un metodo post.

// Params is supposed to be a "cell array of name/value pairs, I don't know matlab... 
s = urlread('http://whatever.com','post', {'username' 'ian'; 'password' 'awesomepass'}) 

Dovrete guardare il modulo di richiesta HTML reale o visualizzare la scheda netta in Firebug per vedere che cosa il nome effettivo/valori di lui nome utente e password sono i parametri.

0

Si scopre che il sito intranet utilizza l'autenticazione di base, che non è supportata da Matlab out-of-the-box ma esiste una soluzione alternativa descritta sul sito Mathworks here che funziona correttamente. Nel primo caso ho usato Firebug per ottenere la stringa codificata Base64 necessaria per l'accesso, ma ho anche eseguito un calcolo diretto utilizzando lo strumento here. Ora ho salvato il mio file di report PDF su disco - quindi lavoro fatto. Per il mio prossimo trucco lo convertirò in testo ...

La mia comprensione è che i metodi get e post sono distinti dal metodo di autenticazione di base, ma quell'autenticazione di base non è spesso utilizzata sulla rete aperta.

+0

Se si finisce con la soluzione alternativa a lungo termine, è consigliabile copiare urlread() e urlreadwrite() in una directory separata e rinominarli. La modifica dell'installazione di Matlab può essere rischiosa, anche se è MathWorks che ti dice di farlo, e avresti bisogno di farlo per ogni installazione separata. –

1

urlwrite_auth è il passo successivo, ecco che è ...

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

Nota questo è uno sviluppo della risposta da Andrew per scaricare file da un nome utente http e il sito password.

0

Come aggiornamento a questo: un'altra opzione è la nuova funzione webread che è possibile fornire in modo esplicito nome utente e password per l'autenticazione di base.

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

questo può essere utilizzato anche per websave o webwrite. Ulteriori informazioni su weboptionshere