Realizando login em sites utilizando Java
Veja nesse artigo como efetuar login em sites através do Java usando HttpClient (HttpComponents).
Determinadas aplicações necessitam efetuar login em sites da Web para obter dados ou interagir com o site. Podemos listar uma série de utilidades:
- extração de dados;
- robôs;
- web semântica;
- automação.
Veremos nesse artigo como efetuar essa tarefa em Java, a partir do uso do HttpClient.
Baixando o Http Components da Apache
O download do Http Components é feito a partir do site: Apache.org.
A versão utilizada nesse exemplo é o 4.2.3.
Exemplo de Uso: site da DevMedia
Efetuaremos o login automático no próprio site da devmedia:
No site da DevMedia temos os campos de login e senha, além do botão ok que irá submeter os dados ao servidor, que por sua vez, irá validar ou não o acesso.
Este plugin monitora e analisa toda a comunicação HTTP feita entre o browser e as aplicações servidoras que ele acessa.
Instale o plugin e reinicie o Firefox. Ele agora poderá ser usado para ajudar a descobrir os dados que precisamos para efetuar o login automático.
Para ativar o HttpFox, acesse o Menu Tools – Web Developer – HttpFox – Toggle HttpFox.
Depois de ativado, o Firefox ficará assim:
Ao clicar no botão Start, o HttpFox irá começar a monitorar todas as interações do browser com o servidor. Portanto, informe login e senha, pressione o botão ok. Após isso, clique no botão Stop do HttpFox.
Observe que o HttpFox gravou todas as interações que efetuamos (entre pressionar o botão Start e o botão Stop). Uma dessas ações é justamente o login, que está destacada na linha com realce em azul.
Repare que na Aba Headers, temos a informação da URL de login, /login/login.asp, e o tipo de requisição, no caso POST. Na aba POST Data, descobrimos quais são as informações que foram enviadas no POST:
- usuario = xxx
- senha = xxx
- ac = 1
Na aba POST Data, vemos o nome dos parâmetros que são realmente enviados ao servidor. Portanto, para efetuar o login na DevMedia, temos que:
- enviar o atributo usuario preenchido;
- enviar o atributo senha preenchido;
- enviar o atributo ac com valor “1”;
- URL de login: www.devmedia.com.br/login/login.asp.
Tendo essas informações em mãos, podemos construir nossa aplicação Java:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
*
* @author marcelo
*/
public class NavegadorSite {
private final DefaultHttpClient client = new DefaultHttpClient();
/**
* Efetua login no site
* @param url - URL de Login do site
* @param user - usuario
* @param password - senha
* @return true - login ok | false - login fail
* @throws UnsupportedEncodingException
* @throws IOException
*/
public boolean login(final String url, final String user, final String
password) throws
UnsupportedEncodingException, IOException {
/* Método POST */
final HttpPost post = new HttpPost(url);
boolean result = false;
/* Configura os parâmetros do POST */
final List<NameValuePair> nameValuePairs =
new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("usuario", user));
nameValuePairs.add(new BasicNameValuePair("senha", password));
nameValuePairs.add(new BasicNameValuePair("ac", "1"));
/*
* Codifica os parametros.
*
* Antes do encoder: fulano@email.com
* Depois do enconder: fulano%40email.com
*/
post.setEntity(new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8));
/* Define navegador */
post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:18.0)
Gecko/20100101 Firefox/18.0");
/* Efetua o POST */
HttpResponse response = client.execute(post);
/* Resposta HTTP: Sempre imprimirá “HTTP/1.1 302 Object moved”
(no caso da devmedia) */
System.out.println("Login form get: " + response.getStatusLine());
/*
* Consome o conteúdo retornado pelo servidor
* Necessário esvaziar o response antes de usar o httpClient novamente
*/
EntityUtils.consume(response.getEntity());
/*
* Testar se o login funcionou.
*
* Estratégia: acessar uma página que só está disponível quando se está logado
* Em caso de erro, o servidor irá redirecionar para a página de login
* A pagina de login contem uma string: "Login DevMedia"
* Se esta String estiver presente, significa que o login não foi efetuado com sucesso
*
*/
final HttpGet get = new HttpGet("https://www.devmedia.com.br/include/mynotes.asp");
response = client.execute(get);
/*
* Verifica se a String: "Login DevMedia" está presente
*/
if (checkSuccess(response)) {
System.out.println("Conexao Estabelecida!");
result = true;
} else {
System.out.println("Login não-efetuado!");
}
return result;
}
/**
* Abre página
* @param url - Página a acessar
* @throws IOException
*/
public void openPage(final String url) throws IOException {
final HttpGet get = new HttpGet(url);
final HttpResponse response = client.execute(get);
saveHTLM(response);
}
/**
* Encerra conexão
*/
public void close() {
client.getConnectionManager().shutdown();
}
/**
* Busca por String que indica se o usuário está logado ou não
* @param response
* @return true - Não achou String | false - Achou String
* @throws IOException
*/
private boolean checkSuccess(final HttpResponse response) throws IOException {
final BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line;
boolean found = false;
/* Deixa correr todo o laco, mesmo achando a String, para consumir o content */
while ((line = rd.readLine()) != null) {
if(line.contains("Login DevMedia")) {
found = true;
}
}
return !found;
}
/**
* Salva a página
* @param response
* @throws IOException
*/
private void saveHTLM(final HttpResponse response) throws IOException {
final BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line;
File arquivo = new File("c:\\arquivo.html");
PrintWriter writer = new PrintWriter(arquivo);
while ((line = rd.readLine()) != null) {
System.out.println(line);
writer.println(line);
}
writer.flush();
writer.close();
}
/**
* Roda aplicação
* @param args
*/
public static void main(String[] args) {
NavegadorSite navegador = new NavegadorSite();
try {
// Tenta efetuar login
boolean ok = navegador.login("https://www.devmedia.com.br/login/login.asp"
, "<login>", "<senha>");
if (ok) {
// Acessa página restrita
navegador.openPage("https://www.devmedia.com.br/include/mynotes.asp");
}
navegador.close();
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}Devemos adicionar as seguintes dependências ao projeto:
- httpclient-4.2.3.jar;
- httpcore-4.2.2.jar;
- commons-codec-1.6.jar;
- commons-logging-1.1.1.jar.
Observe que tivemos que configurar o header do POST, no caso, setando o User-Agent. Todas as informações de Header podem ser obtidas no HttpFox.
Através do método saveHTML, podemos ver se determinada página acessada está realmente correta. Para um melhor uso, o método openPage poderia receber um segundo argumento, indicando onde salvar a página.
Conclusão
Efetuar login em sites usando HttpClient é relativamente simples. O exemplo acima foi adaptado para funcionar particularmente com o site da DevMedia, porém, com algumas alterações, é possível utilizar o código para outros sites também (o código foi testado com outros sites, usando o HttpFox para descobrir os parâmetros a serem enviados).
O HttpClient também está disponível para a plataforma Android, o que permite usar a mesma estratégia.
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Vídeo