프로그래밍 방식으로 Java로 웹 페이지를 다운로드하는 방법


117

웹 페이지의 html을 가져 와서에 저장하여 String일부 처리를 할 수 있기를 바랍니다. 또한 다양한 유형의 압축을 어떻게 처리 할 수 ​​있습니까?

Java를 사용하여 어떻게 할 수 있습니까?


이것은 기본적으로의 특별한 경우이다 stackoverflow.com/questions/921262/...
로빈 그린

답변:


110

다음은 Java의 URL 클래스를 사용하여 테스트 된 코드 입니다. 하지만 예외를 처리하거나 호출 스택에 전달하는 것보다 더 나은 작업을 수행하는 것이 좋습니다.

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 ()은 더 이상 사용되지 않지만 아주 좋은 예가 아닙니다. readLine () 함수를 가져 오기 위해 BufferedReader ()에 래핑 된 InputStreamReader ()를 사용했습니다.
mjh2007 2010

2
이것은 문자 인코딩을 고려하지 않으므로 ASCII 텍스트에서 작동하는 것처럼 보이지만 불일치가있을 때 결국 '이상한 문자'가됩니다.
artbristol 2012

세 번째 줄 DataInputStream에서 BufferedReader. 그리고 교체 "dis = new DataInputStream(new BufferedInputStream(is));""dis = new BufferedReader(new InputStreamReader(is));"
kolobok

1
@akapelko 감사합니다. 더 이상 사용되지 않는 메서드에 대한 호출을 제거하기 위해 내 대답을 업데이트했습니다.
Bill the Lizard

2
닫는 건 InputStreamReader어때?
Alexander-Monica 복원

170

Jsoup 과 같은 괜찮은 HTML 파서를 사용합니다 . 그러면 다음과 같이 쉽습니다.

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

GZIP 및 청크 응답 및 문자 인코딩을 완전히 투명하게 처리합니다. HTML 순회 및 jQuery와 같은 CSS 선택기에 의한 조작 과 같은 더 많은 이점도 제공합니다 . 당신은 같은 그것을 잡아가 Document아닌 같은 String.

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

당신은 정말 그것을 처리하기 위해 HTML에서 기본 String 메서드 또는 심지어 정규식을 실행하고 싶지 않습니다 .

또한보십시오:


3
좋은 대답입니다. 조금 늦게. ;)
jjnguy

59
결코하지 않는 것보다 낫다.
BalusC

환상적인 라이브러리 :) Thx.
Jakub P.

왜 아무도 전에 .html ()에 대해 말하지 않았습니다. 나는 Jsoup에서 가져온 html을 쉽게 저장하는 방법에 대해 너무나 열심히 조사했고 그것은 많은 도움이되었습니다.
Avamander

당신이 안드로이드에서이 라이브러리를 사용하는 경우 응용 프로그램이 던져하게됩니다 동일한 응용 프로그램 스레드에서 기본적으로 실행되기 때문에 이민자를 들어, 다른 스레드에서 이것을 사용할 필요가NetworkOnMainThreadException
모하메드 Elrashied

25

Bill의 대답은 매우 좋지만 압축 또는 사용자 에이전트와 같은 요청으로 몇 가지 작업을 수행 할 수 있습니다. 다음 코드는 요청에 대한 다양한 유형의 압축 방법을 보여줍니다.

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();
}

사용자 에이전트도 설정하려면 다음 코드를 추가하십시오.

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

InputStream을 문자열로 변환하려는 사람들은 this answer를 참조하십시오 .
SSight3

setFollowRedirects가 도움이되며, 제 경우에는 setInstanceFollowRedirects를 사용합니다. 사용하기 전에 많은 경우 빈 웹 페이지를 얻었습니다. 압축을 사용하여 파일을 더 빨리 다운로드하려고한다고 가정합니다.
gouessej

12

글쎄, URLURLConnection 과 같은 내장 라이브러리를 사용할 수는 있지만 그다지 제어 할 수는 없습니다.

개인적으로 Apache HTTPClient 라이브러리를 사용합니다.
편집 : HTTPClient는 Apache에 의해 수명종료 되도록 설정되었습니다 . 대체는 다음과 같습니다. HTTP 구성 요소


System.Net.WebRequest의 Java 버전이 없습니까?
FlySwat

1
일종의 URL입니다. :-) 예 : new URL ( " google.com"). openStream () // => InputStream
Daniel Spiewak

1
@Jonathan : 대부분의 경우 Daniel이 말한 것입니다. WebRequest는 URL보다 더 많은 제어를 제공합니다. HTTPClient는 기능면에서 더 가깝습니다.
Jon Skeet

9

위에서 언급 한 모든 접근 방식은 브라우저에서 보이는 웹 페이지 텍스트를 다운로드하지 않습니다. 요즘에는 HTML 페이지의 스크립트를 통해 많은 데이터가 브라우저에로드됩니다. 위에서 언급 한 기술은 스크립트를 지원하지 않으며 html 텍스트 만 다운로드합니다. HTMLUNIT는 자바 스크립트를 지원합니다. 따라서 브라우저에서 보이는 웹 페이지 텍스트를 다운로드하려는 경우 HTMLUNIT 를 사용해야합니다 .


1

보안 웹 페이지 (https 프로토콜)에서 코드를 추출해야 할 가능성이 높습니다. 다음 예에서는 html 파일이 c : \ temp \ filename.html에 저장됩니다. Enjoy!

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

Unix / Linux 상자에서는 'wget'만 실행할 수 있지만 크로스 플랫폼 클라이언트를 작성하는 경우 실제로는 옵션이 아닙니다. 물론 이것은 다운로드하는 시점과 디스크에 도달하는 시점 사이에 다운로드 한 데이터로 많은 작업을 수행하고 싶지 않다고 가정합니다.


나는 또한이 접근 방식으로 시작하고 불충분하다면 나중에 리팩토링 할 것입니다
Dustin Getz

0

Jetty에는 웹 페이지를 다운로드하는 데 사용할 수있는 HTTP 클라이언트가 있습니다.

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();
            }
        }
    }
}

이 예제는 간단한 웹 페이지의 내용을 인쇄합니다.

A의 자바 읽고 웹 페이지 나 URL, JSoup, HtmlCleaner, 아파치 HttpClient를, 부두 HttpClient를, 그리고 HtmlUnit과를 사용하여 자바 programmaticaly 웹 페이지를 dowloading의 여섯 예를 작성한 튜토리얼.


0

이 클래스의 도움을 받아 코드를 얻고 일부 정보를 필터링합니다.

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

NIO.2 강력한 Files.copy (InputStream in, Path target)을 사용하여 이렇게하려면 :

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

-1

이 게시물 ( url )에 대한 실제 답변을 사용하고 출력을 파일에 썼습니다.

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) {

        }

    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.