2009-08-23 8 views
5

Siguiendo de this question, con respecto al acceso a un PDF en una página web usando Matlab que originalmente está enterrado detrás de una función de Javascript. Ahora tengo una URL que me permite acceder a la página directamente, esto funciona bien usando el objeto webrowser de Matlab (el PDF aparece en la pantalla), pero para guardar el PDF para su posterior procesamiento parece que necesito usar las funciones de Matlab urlread/urlwrite . Sin embargo, estas funciones no proporcionan ningún método para ofrecer credenciales de autenticación.¿Cómo proporciono un nombre de usuario/contraseña para acceder a un recurso web usando Matlab urlread/urlwrite?

¿Cómo proporciono nombre de usuario/contraseña para urlread/funciones urlwrite de Matlab?

Respuesta

6

de Matlab urlread() tiene un argumento "params", pero estos son los parámetros de tipo CGI que quedan codificadas en la URL. La autenticación se realiza con parámetros de solicitud HTTP de nivel inferior. Urlread no es compatible con estos, pero puede codificar directamente contra la clase de URL de Java para usarlos.

También puede utilizar la clase sun.misc.BASE64Encoder de un Sol de hacer la codificación Base 64 mediante programación. Esta es una clase no estándar, que no forma parte de la biblioteca estándar de Java, pero usted sabe que el envío de JVM con Matlab lo tendrá, por lo que puede librarse de la codificación.

Aquí un corte rápido que lo muestra en acción.

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: Buena captura de las deficiencias de URLREAD. – gnovice

+0

Limpio: no me había dado cuenta de que era tan sencillo hacer la codificación Base64 también. Planes en espera porque no creo que el administrador del sistema haya apreciado mis métodos de acceso poco ortodoxos: ahora, en lugar de un archivo pdf, ¡obtengo una página HTML de "No hagas eso"! Lo cual es bastante justo en realidad, cambiar al modo de diplomacia: oops: –

-2

No sé Matlab, esto es sólo una conjetura.

La documentación de la función here enumera las opciones como así:

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

Dependiendo de qué tipo de autenticación que utilice este puede o no puede trabajar, se le va a querer utilizar un método 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'}) 

Usted tendrá que buscar en el formulario de solicitud de HTML real o ver la ficha neta en Firebug para ver qué/valores del nombre real de él de nombre de usuario y la contraseña son parámetros.

0

Resulta que el sitio de Intranet está utilizando la autenticación básica, que no es compatible con Matlab desde el primer momento, pero hay una solución alternativa descrita en el sitio de Mathworks here que funciona bien. En la primera instancia, utilicé Firebug para obtener la cadena codificada en Base64 que necesitaba para acceder, pero también hice un cálculo directo con la herramienta here. Ahora he guardado mi archivo de informe PDF en el disco, por lo que he hecho el trabajo. Para mi próximo truco, lo convertiré en texto ...

Tengo entendido que los métodos de obtención y publicación son distintos del método de autenticación básico, pero que la autenticación básica no se usa a menudo en la red abierta. función

+0

Si termina trabajando con su solución a largo plazo, considere copiar urlread() y urlreadwrite() en un directorio aparte y renombrarlos. Modificar su instalación de Matlab puede ser riesgoso, incluso si es MathWorks el que le dice que lo haga, y tendría que hacerlo en cada instalación por separado. –

1

urlwrite_auth es el siguiente paso, por lo que aquí está ...

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: este es un desarrollo de la respuesta de Andrew para descargar archivos de un nombre de usuario y el sitio http contraseña.

0

como una actualización a esto: otra opción es la nueva función webread que se puede dar de forma explícita el nombre de usuario y una contraseña para authenticaition básica.

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

Esto también se puede utilizar para websave o webwrite. Más información en weboptionshere

Cuestiones relacionadas