프로그래밍 방식으로 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

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

개인적으로 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.