Como você faz download programaticamente de uma página da Web em Java


117

Eu gostaria de poder buscar o html de uma página da web e salvá-lo em um String, para que eu possa fazer algum processamento nele. Além disso, como poderia lidar com vários tipos de compressão.

Como eu faria isso usando Java?


Este é basicamente um caso especial de stackoverflow.com/questions/921262/…
Robin Green

Respostas:


110

Aqui estão alguns códigos testados usando a classe URL do Java . Eu recomendo fazer um trabalho melhor do que o que faço aqui para lidar com as exceções ou transferi-las para a pilha de chamadas, no entanto.

public static void main(String[] args) {
    URL url;
    InputStream is = null;
    BufferedReader br;
    String line;

    try {
        url = new URL("http://stackoverflow.com/");
        is = url.openStream();  // throws an IOException
        br = new BufferedReader(new InputStreamReader(is));

        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    } catch (MalformedURLException mue) {
         mue.printStackTrace();
    } catch (IOException ioe) {
         ioe.printStackTrace();
    } finally {
        try {
            if (is != null) is.close();
        } catch (IOException ioe) {
            // nothing to see here
        }
    }
}

16
DataInputStream.readLine () está obsoleto, mas diferente desse exemplo muito bom. Usei um InputStreamReader () envolvido em um BufferedReader () para obter a função readLine ().
mjh2007

2
Isso não leva a codificação de caracteres em consideração, portanto, embora pareça funcionar para texto ASCII, eventualmente resultará em 'caracteres estranhos' quando houver uma incompatibilidade.
artbristol

Na 3ª linha substitua DataInputStreampor BufferedReader. E substitua "dis = new DataInputStream(new BufferedInputStream(is));"por"dis = new BufferedReader(new InputStreamReader(is));"
kolobok de

1
@akapelko Obrigado. Eu atualizei minha resposta para remover as chamadas para métodos obsoletos.
Bill the Lizard de

2
que tal fechar o InputStreamReader?
Alexander - Reintegrar Monica em

170

Eu usaria um analisador de HTML decente como o Jsoup . Então, é tão fácil quanto:

String html = Jsoup.connect("http://stackoverflow.com").get().html();

Ele lida com GZIP e respostas fragmentadas e codificação de caracteres de forma totalmente transparente. Ele oferece mais vantagens também, como passagem de HTML e manipulação por seletores CSS, como o jQuery pode fazer. Você só precisa agarrá-lo como Document, não como um String.

Document document = Jsoup.connect("http://google.com").get();

Você realmente não deseja executar métodos String básicos ou mesmo regex em HTML para processá-lo.

Veja também:


3
Boa resposta. Um pouco tarde. ;)
jjnguy

59
Melhor do que nunca.
BalusC de

Biblioteca fantástica :) Obrigado por isso.
Jakub P.

Por que ninguém me falou sobre .html () antes. Eu pesquisei muito sobre como armazenar facilmente o html obtido pelo Jsoup e isso ajuda muito.
Avamander

para iniciantes, se você usar esta biblioteca no Android, precisará usá-la em um thread diferente porque ela é executada por padrão no mesmo thread do aplicativo, o que fará com que o aplicativo seja lançadoNetworkOnMainThreadException
Mohammed Elrashied

25

A resposta de Bill é muito boa, mas você pode querer fazer algumas coisas com a solicitação, como compressão ou agentes de usuário. O código a seguir mostra como você pode aplicar vários tipos de compactação às suas solicitações.

URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Cast shouldn't fail
HttpURLConnection.setFollowRedirects(true);
// allow both GZip and Deflate (ZLib) encodings
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
String encoding = conn.getContentEncoding();
InputStream inStr = null;

// create the appropriate stream wrapper based on
// the encoding type
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
    inStr = new GZIPInputStream(conn.getInputStream());
} else if (encoding != null && encoding.equalsIgnoreCase("deflate")) {
    inStr = new InflaterInputStream(conn.getInputStream(),
      new Inflater(true));
} else {
    inStr = conn.getInputStream();
}

Para definir também o user-agent, adicione o seguinte código:

conn.setRequestProperty ( "User-agent", "my agent name");

Para quem deseja converter o InputStream em string, veja esta resposta .
SSight3

setFollowRedirects ajuda, eu uso setInstanceFollowRedirects no meu caso, eu estava recebendo páginas da web vazias em muitos casos antes de usar isso. Presumo que você tente usar compressão para baixar o arquivo mais rápido.
gouessej

12

Bem, você poderia ir com as bibliotecas integradas, como URL e URLConnection , mas elas não oferecem muito controle.

Pessoalmente, eu escolheria a biblioteca Apache HTTPClient .
Editar: HTTPClient foi definido para o fim da vida pelo Apache. A substituição é: Componentes HTTP


Não existe uma versão java do System.Net.WebRequest?
FlySwat

1
Mais ou menos, isso seria URL. :-) Por exemplo: new URL (" google.com"). OpenStream () // => InputStream
Daniel Spiewak

1
@ Jonathan: O que Daniel disse, na maior parte - embora WebRequest dê a você mais controle do que URL. HTTPClient está mais próximo em funcionalidade, IMO.
Jon Skeet

9

Todas as abordagens mencionadas acima não baixam o texto da página da web como ele aparece no navegador. hoje em dia, muitos dados são carregados nos navegadores por meio de scripts em páginas html. nenhuma das técnicas mencionadas acima oferece suporte a scripts, elas apenas baixam apenas o texto html. HTMLUNIT oferece suporte a javascripts. portanto, se você deseja fazer o download do texto da página da web conforme aparece no navegador, deve usar HTMLUNIT .


1

Provavelmente, você precisará extrair o código de uma página da web segura (protocolo https). No exemplo a seguir, o arquivo html está sendo salvo em c: \ temp \ filename.html Divirta-se!

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

/**
 * <b>Get the Html source from the secure url </b>
 */
public class HttpsClientUtil {
    public static void main(String[] args) throws Exception {
        String httpsURL = "https://stackoverflow.com";
        String FILENAME = "c:\\temp\\filename.html";
        BufferedWriter bw = new BufferedWriter(new FileWriter(FILENAME));
        URL myurl = new URL(httpsURL);
        HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection();
        con.setRequestProperty ( "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0" );
        InputStream ins = con.getInputStream();
        InputStreamReader isr = new InputStreamReader(ins, "Windows-1252");
        BufferedReader in = new BufferedReader(isr);
        String inputLine;

        // Write each line into the file
        while ((inputLine = in.readLine()) != null) {
            System.out.println(inputLine);
            bw.write(inputLine);
        }
        in.close(); 
        bw.close();
    }
}

0

Em uma máquina Unix / Linux, você pode simplesmente executar 'wget', mas esta não é realmente uma opção se você estiver escrevendo um cliente de plataforma cruzada. É claro que isso pressupõe que você realmente não deseja fazer muito com os dados baixados entre o ponto de baixá-los e chegar ao disco.


eu também começaria com esta abordagem e a refatoraria mais tarde se insuficiente
Dustin Getz,

0

Jetty tem um cliente HTTP que pode ser usado para baixar uma página da web.

package com.zetcode;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;

public class ReadWebPageEx5 {

    public static void main(String[] args) throws Exception {

        HttpClient client = null;

        try {

            client = new HttpClient();
            client.start();

            String url = "http://www.something.com";

            ContentResponse res = client.GET(url);

            System.out.println(res.getContentAsString());

        } finally {

            if (client != null) {

                client.stop();
            }
        }
    }
}

O exemplo imprime o conteúdo de uma página da web simples.

Em um tutorial Lendo uma página da web em Java , escrevi seis exemplos de download de uma página da web programaticamente em Java usando URL, JSoup, HtmlCleaner, Apache HttpClient, Jetty HttpClient e HtmlUnit.


0

Obtenha ajuda desta classe para obter o código e filtrar algumas informações.

public class MainActivity extends AppCompatActivity {

    EditText url;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );

        url = ((EditText)findViewById( R.id.editText));
        DownloadCode obj = new DownloadCode();

        try {
            String des=" ";

            String tag1= "<div class=\"description\">";
            String l = obj.execute( "http://www.nu.edu.pk/Campus/Chiniot-Faisalabad/Faculty" ).get();

            url.setText( l );
            url.setText( " " );

            String[] t1 = l.split(tag1);
            String[] t2 = t1[0].split( "</div>" );
            url.setText( t2[0] );

        }
        catch (Exception e)
        {
            Toast.makeText( this,e.toString(),Toast.LENGTH_SHORT ).show();
        }

    }
                                        // input, extrafunctionrunparallel, output
    class DownloadCode extends AsyncTask<String,Void,String>
    {
        @Override
        protected String doInBackground(String... WebAddress) // string of webAddress separate by ','
        {
            String htmlcontent = " ";
            try {
                URL url = new URL( WebAddress[0] );
                HttpURLConnection c = (HttpURLConnection) url.openConnection();
                c.connect();
                InputStream input = c.getInputStream();
                int data;
                InputStreamReader reader = new InputStreamReader( input );

                data = reader.read();

                while (data != -1)
                {
                    char content = (char) data;
                    htmlcontent+=content;
                    data = reader.read();
                }
            }
            catch (Exception e)
            {
                Log.i("Status : ",e.toString());
            }
            return htmlcontent;
        }
    }
}

0

Para fazer isso usando NIO.2 poderoso Files.copy (InputStream em, Path target):

URL url = new URL( "http://download.me/" );
Files.copy( url.openStream(), Paths.get("downloaded.html" ) );

-1

Usei a resposta real para este post ( url ) e escrevi a saída em um arquivo.

package test;

import java.net.*;
import java.io.*;

public class PDFTest {
    public static void main(String[] args) throws Exception {
    try {
        URL oracle = new URL("http://www.fetagracollege.org");
        BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));

        String fileName = "D:\\a_01\\output.txt";

        PrintWriter writer = new PrintWriter(fileName, "UTF-8");
        OutputStream outputStream = new FileOutputStream(fileName);
        String inputLine;

        while ((inputLine = in.readLine()) != null) {
            System.out.println(inputLine);
            writer.println(inputLine);
        }
        in.close();
        } catch(Exception e) {

        }

    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.