Problema em download de arquivo ZIP

7 respostas
D

Caros,

Eu tinha uma aplicação que baixava do site da Caixa Econômica os resultados da Megasena em um arquivo zipado.
De um tempo pra cá, vi que não consigo mais fazê-lo via java, só via browser. Que tipo de limitação eles podem ter adicionado? E como conseguir fazer o download?
Tentei passar REFERER, cookies etc, sem sucesso.

Abaixo posto o código já alterado, que ainda não funciona. Se vocês puderem me dar uma luz, agradeceria.

Não uso proxy, essa era uma implementação que eu iria adicionar no futuro. Enchi de logs também para tentar melhor o entendimento do que está acontecendo; em vão.

public class URLDownload {
	final static int size = 1024;

	private static final Logger logger = Logger.getLogger(URLDownload.class
			.getName());

        public static final void main(String... x) {
            URLDownload.fileUrl("http://www1.caixa.gov.br/loterias/_arquivos/loterias/D_megase.zip", "teste.zip", ".");
        }
        
	/**
	 * 
	 * @param fAddress
	 * @param localFileName
	 * @param destinationDir
	 */
	public static void fileUrl(String fAddress, String localFileName,
			String destinationDir) {
		OutputStream outStream = null;
		URLConnection uCon = null;
		InputStream is = null;

		try {
			URL url;
			byte[] buf;
			int ByteRead, ByteWritten = 0;
			url = new URL(fAddress);
			outStream = new BufferedOutputStream(new FileOutputStream(
					destinationDir + "/" + localFileName));

			try {
				String host = ProxyProp.getInstance().get("host");
				String port = ProxyProp.getInstance().get("port");
				String user = ProxyProp.getInstance().get("user");
				String pass = ProxyProp.getInstance().get("pass");

				// faz a conexão via proxy
				if (host != null && !host.equals("") && JMega.proxyChecked) {
					Authenticator.setDefault(new BasicAuthenticator(user, pass));
					SocketAddress sa = new InetSocketAddress(host, new Integer(port));
					Proxy proxy = new Proxy(Type.HTTP, sa);
					uCon = url.openConnection(proxy);
                                        logger.info("Conexão aberta com sucesso");
				} else { // sem proxy
					uCon = url.openConnection();
                                        logger.info("Conexão aberta com sucesso");
				}
			} catch (Exception e) {
				uCon = url.openConnection(); // sem proxy
                                logger.info("Conexão aberta com sucesso");
			}
			
                        // setando propriedades de request
                        logger.info("Setando HTTP Request");
                        uCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30");
                        uCon.setRequestProperty("Referer", "http://www1.caixa.gov.br/loterias/loterias/megasena/megasena_resultado.asp");
                        
                        // trabalhando os cookies
                        logger.info("Abrindo conexão para coleta de cookies");
                        URL ref = new URL("http://www1.caixa.gov.br/loterias/loterias/megasena/megasena_resultado.asp");
                        URLConnection coo = ref.openConnection();
                        coo.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30");
                        coo.setRequestProperty("Referer", "http://www1.caixa.gov.br/loterias/loterias/megasena/megasena_resultado.asp");
                        logger.info("Conexão aberta");
                        CookieManager cm = new CookieManager();
                        cm.storeCookies(coo);
                        logger.info("Cookie: " + cm.toString());
                        cm.setCookies(uCon);
                        logger.info("Cookies setados");
                                             
                        logger.info("Lendo bytes");
			is = uCon.getInputStream();
			buf = new byte[size];
			while ((ByteRead = is.read(buf)) != -1) {
				outStream.write(buf, 0, ByteRead);
				ByteWritten += ByteRead;
			}
						
			logger.info("Download realizado com sucesso");
			logger.info("Nome do arquivo: \"" + localFileName + "\" - Bytes: "
					+ ByteWritten);
		} catch (Exception e) {
			logger.severe("Erro ao realizar o download");
			throw new RuntimeException(e);
		} finally {
			try {
				is.close();
				outStream.close();
			} catch (Exception e) {
				logger.severe("Erro ao fechar conexão");
				throw new RuntimeException(e);
			}
		}
	}

}

7 Respostas

D

A propósito: este mesmo código de download em outro arquivo de outro site, e vem tranquilo.

R

Estou passando pelo mesmo problema... o erro que vem para mim é:

java.net.ProtocolException: Server redirected too many times (20) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1413) at com.robsonximenes.catiguria.persistence.ConcursoDAO.baixarArquivo(ConcursoDAO.java:59) at com.robsonximenes.catiguria.persistence.ConcursoDAO.main(ConcursoDAO.java:70)

O código é bem simples:

URL url = new URL("http://www1.caixa.gov.br/loterias/_arquivos/loterias/D_megase.zip");
		URLConnection con = url.openConnection();
		con.setConnectTimeout(5000);
		ZipInputStream in = new ZipInputStream(new BufferedInputStream(con.getInputStream()));
R

Tbm estou passando pelo mesmo problema. Fiz uma aplicação swing que ao clicar no botao atualizar puxa o arquivo do site da Loterias Caixa.

Alguém tem uma ideia?

O erro que dá: Server redirected too many times (20)

D

Isso aconteceu comigo também (programo em C++). Resolvi usando a função da API [color=darkred]URLDownloadToFile[/color]

Em C++ fica assim:

#include <tchar.h>
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")
int main()
{
	HRESULT hr = URLDownloadToFile ( NULL, _T("your web page"), _T("c:/web_page.html"), 0, NULL );
	return 0;
}
R

Alguém conseguiu resolver esse problema?

W

Galera, descobri como resolve!
Simplesmente os servidores da caixa passaram a usar uma espécie de “COOCKIE SESSION CKECK”.
Basicamente é um coockie que é definido ao iniciar a sessão e excluido ao terminar de enviar os dados do cabeçalho.
Enfim, a solução é relativamente simples, basta permitir o uso de cookies apartir da API padrão do java para todas as conexões.

Resolução do problema:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

Coloquem isso antes de fazer uma HttpRequest ou coisas do género.
Como é de escopo global, basta colocar uma vez na aplicação toda.
Percebi também que apenas sites em ASP e ASPX necessitam desse COOCKIE CHECK. Aparamente isso coisa do servidor de aplicação da M$. Tinha que ser coisas da porcaria da M$ mesmo.

Criei uma classe que gerencia downloads e anexei ao post. Faça bom e uso e apenas não tirem os creditos (agradeço por isso)!

A

Uma outra alternativa seria vc usar o HttpClient --> http://hc.apache.org/downloads.cgi

Fiz um pequeno exemplo como baixar o zip…

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;

/**
 *
 * @author Andy11x 
 */
public class MegaSena { 
    
    private HttpClient httpCliente;
    private HttpResponse httpResponse;
    private HttpGet httpGet;
    private HttpEntity httpEntity;   
    private ByteArrayOutputStream outBytes;
    
    public static void main(String[] args) {
        String link = "http://www1.caixa.gov.br/loterias/_arquivos/loterias/D_megase.zip";
        String path = "C:\\Users\\Andy11x\\Desktop\\megasena.zip";
        new MegaSena().createFile(link, path);        
    }
    
    private ByteArrayOutputStream downloadZip(String link) {       
        httpCliente = HttpClientBuilder.create().build(); 
        httpGet = new HttpGet(link); 
        outBytes = new ByteArrayOutputStream();      
        try{
            httpResponse = httpCliente.execute(httpGet);
            httpEntity = httpResponse.getEntity();
            if(httpEntity != null){                                
                httpEntity.writeTo(outBytes);     
                outBytes.close(); 
            }
        }        
        catch(Exception ex){ }        
        return outBytes;
    }     
    
    private void createFile(String link, String path) {        
        FileOutputStream fos = null;
        try{
            fos = new FileOutputStream(new File(path));
            fos.write(downloadZip(link).toByteArray());
            fos.close();
        }
        catch(Exception ex){}
    }    
}
Criado 27 de julho de 2011
Ultima resposta 1 de mar. de 2014
Respostas 7
Participantes 6