Як програмно завантажувати веб-сторінку на Java


117

Я хотів би мати змогу отримати html веб-сторінки та зберегти її в a String, тому я можу зробити якусь обробку на ній. Крім того, як я міг обробляти різні види стиснення.

Як би я міг робити це за допомогою Java?


В основному це особливий випадок stackoverflow.com/questions/921262/…
Робін Грін

Відповіді:


110

Ось кілька перевірених кодів за допомогою класу URL-адреси Java Я б рекомендував зробити кращу роботу, ніж я роблю тут обробку винятків або передачу їх до стека викликів.

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 () я використав InputStreamReader (), загорнутий у BufferedReader ().
mjh2007

2
При цьому не враховується кодування символів, тому, мабуть, це працює для тексту ASCII, воно в кінцевому підсумку призведе до появи "дивних символів", коли буде невідповідність.
artbristol

У 3-му рядку замінити DataInputStreamна BufferedReader. І замінити "dis = new DataInputStream(new BufferedInputStream(is));"на"dis = new BufferedReader(new InputStreamReader(is));"
колобок

1
@akapelko Дякую Я оновив свою відповідь, щоб видалити дзвінки до застарілих методів.
Білл Ящірка

2
як щодо закриття InputStreamReader?
Олександр - Відновіть Моніку

170

Я б використав гідний HTML-аналізатор, як Jsoup . Тоді це так просто, як:

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

Він обробляє GZIP і чіткі відповіді та кодування символів повністю прозоро. Він також пропонує більше переваг, як пересування HTML та маніпуляції селекторами CSS, як, наприклад, jQuery. Вам потрібно лише схопити це як Document, а не як String.

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

Ви дійсно не хочете запускати основні методи String або навіть повторно виражати HTML на обробці.

Дивитися також:


3
Хороша відповідь. Трохи пізно. ;)
jjnguy

59
Краще, ніж ніколи.
BalusC

Фантастична бібліотека :) Thx для цього.
Якуб П.

Чому раніше мені ніхто не розповідав про .html (). Я так важко роздивився, як легко зберігати html, отриманий Jsoup, і це дуже допомагає.
Avamander

для новачків, якщо ви використовуєте цю бібліотеку в android, вам потрібно використовувати її в різних потоках, оскільки вона за замовчуванням працює на тій самій програмі, що призведе до викидання програмиNetworkOnMainThreadException
Mohammed Elrashied

25

Відповідь Білла дуже хороша, але ви, можливо, захочете виконати деякі запити, такі як стиснення або користувальницькі агенти. Наступний код показує, як ви можете здійснювати різні типи стиснення до ваших запитів.

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 у рядок, дивіться цю відповідь .
SSight3

setFollowRedirects допомагає, я використовую setInstanceFollowRedirects в моєму випадку, я отримував порожні веб-сторінки в багатьох випадках, перш ніж використовувати це. Я припускаю, що ви намагаєтесь скористатися стисненням, щоб швидше завантажити файл.
gouessej

12

Що ж, ви можете користуватися вбудованими бібліотеками, такими як URL та URLConnection , але вони не дуже контролюють.

Особисто я б поїхав з бібліотекою Apache HTTPClient .
Редагувати: HTTPClient був встановлений до кінця життя Apache. Заміна: HTTP Components


Немає версії Java для System.Net.WebRequest?
FlySwat

1
Сорт, це буде URL. :-) Наприклад: нова URL-адреса (" google.com"). OpenStream () // => InputStream
Daniel Spiewak

1
@Jonathan: Здебільшого, що сказав Даніель, хоча WebRequest дає вам більше контролю, ніж URL. HTTPClient наближений до функціональності, IMO.
Джон Скіт

9

Усі вищезазначені підходи не завантажують текст веб-сторінки так, як це виглядає в браузері. в наші дні велика кількість даних завантажується в браузери за допомогою скриптів на html-сторінках. жодна з вищезгаданих методик не підтримує сценарії, вони просто завантажують лише HTML-текст. HTMLUNIT підтримує Java-скрипти. тому якщо ви хочете завантажити текст веб-сторінки, як він виглядає у браузері, тоді вам слід використовувати HTMLUNIT .


1

Вам, швидше за все, потрібно буде витягнути код із захищеної веб-сторінки (протокол https). У наступному прикладі файл HTML зберігається у c: \ temp \ filename.html Насолоджуйтесь!

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", але це насправді не варіант, якщо ви пишете крос-платформний клієнт. Звичайно, це передбачає, що ви насправді не хочете багато робити з даними, які ви завантажуєте між моментом завантаження та потраплянням на диск.


Я також почав би з цього підходу і переробляти його пізніше, якщо недостатньо
Дастін Гец

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

Приклад друкує вміст простої веб-сторінки.

У розділі " Читання веб-сторінки" в підручнику Java я написав шість прикладів завантаження програмної програми веб-сторінки на Java за допомогою URL, JSoup, HtmlCleaner, Apache HttpClient, Jetty HttpClient та HtmlUnit.


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

        }

    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.