Чтение содержимого сайта в строку - PullRequest
15 голосов
/ 03 мая 2011

В настоящее время я работаю над классом, который можно использовать для чтения содержимого сайта, указанного в URL.Я только начинаю свои приключения с java.io и java.net, поэтому мне нужно проконсультироваться с моим дизайном.

Использование:

TextURL url = new TextURL(urlString);
String contents = url.read();

Мой код:

package pl.maciejziarko.util;

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

public final class TextURL
{
    private static final int BUFFER_SIZE = 1024 * 10;
    private static final int ZERO = 0;
    private final byte[] dataBuffer = new byte[BUFFER_SIZE];
    private final URL urlObject;

    public TextURL(String urlString) throws MalformedURLException
    {
        this.urlObject = new URL(urlString);
    }

    public String read() 
    {
        final StringBuilder sb = new StringBuilder();

        try
        {
            final BufferedInputStream in =
                    new BufferedInputStream(urlObject.openStream());

            int bytesRead = ZERO;

            while ((bytesRead = in.read(dataBuffer, ZERO, BUFFER_SIZE)) >= ZERO)
            {
                sb.append(new String(dataBuffer, ZERO, bytesRead));
            }
        }
        catch (UnknownHostException e)
        {
            return null;
        }
        catch (IOException e)
        {
            return null;
        }

        return sb.toString();
    }

    //Usage:
    public static void main(String[] args)
    {
        try
        {
            TextURL url = new TextURL("http://www.flickr.com/explore/interesting/7days/");
            String contents = url.read();

            if (contents != null)
                System.out.println(contents);
            else
                System.out.println("ERROR!");
        }
        catch (MalformedURLException e)
        {
            System.out.println("Check you the url!");
        }
    }
}

Мой вопрос: это хороший способ добиться того, чего я хочу?Есть ли лучшие решения?

Мне особенно не понравился sb.append(new String(dataBuffer, ZERO, bytesRead));, но я не смог выразить это по-другому.Хорошо ли создавать новую строку для каждой итерации?Полагаю, нет.

Есть ли другие слабые места?

Заранее спасибо!

Ответы [ 6 ]

18 голосов
/ 03 мая 2011

Попробуйте вместо этого использовать URLConnection. Кроме того, вы можете использовать IOUtils из Apache Commons IO , чтобы упростить чтение строк. Например:

URL url = new URL("http://www.example.com/");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();  // ** WRONG: should use "con.getContentType()" instead but it returns something like "text/html; charset=UTF-8" so this value must be parsed to extract the actual encoding
encoding = encoding == null ? "UTF-8" : encoding;
String body = IOUtils.toString(in, encoding);
System.out.println(body);

Если вы не хотите использовать IOUtils Я бы, вероятно, переписал эту строку над чем-то вроде:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
int len = 0;
while ((len = in.read(buf)) != -1) {
    baos.write(buf, 0, len);
}
String body = new String(baos.toByteArray(), encoding);
6 голосов
/ 03 мая 2011

Я настоятельно рекомендую использовать выделенную библиотеку, например HtmlParser :

Parser parser = new Parser (url);
NodeList list = parser.parse (null);
System.out.println (list.toHtml ());

Написание собственного html-парсера - такая потеря времени. Вот его maven зависимость . Посмотрите на его JavaDoc для поиска его возможностей.

Глядя на следующий образец должно быть убедительно:

Parser parser = new Parser(url);
NodeList movies = parser.extractAllNodesThatMatch(
    new AndFilter(new TagNameFilter("div"),
    new HasAttributeFilter("class", "movie")));
2 голосов
/ 03 мая 2011

Вы можете обернуть InputStream в InputStreamReader и использовать это read() метод для непосредственного чтения символьных данных (обратите внимание, что следует указать кодировку при создании Reader, но выяснить кодировку произвольных URL-адресов нетривиально). Затем просто позвоните sb.append() с char[], который вы только что прочитали (и с правильным смещением и длиной).

2 голосов
/ 03 мая 2011

Если это не какое-то упражнение, которое вы хотите написать для обучения ... Я бы не стал изобретать велосипед и использовал бы HttpURLConnection .

HttpURLConnection предоставляет хорошие механизмы инкапсуляции для работы с протоколом HTTP. Например, ваш код не работает с перенаправлениями HTTP, HttpURLConnection исправит это для вас.

0 голосов
/ 24 февраля 2018

Я знаю, что это старый вопрос, но я уверен, что другие люди тоже найдут его.

Если вы не возражаете против дополнительной зависимости, вот очень простой способ

Jsoup.connect("http://example.com/").get().toString()

Вам понадобится библиотека Jsoup , но вы можете быстро добавить ее с помощью maven / gradle, а также она позволяет манипулировать содержимым страницы и находить конкретные узлы.

0 голосов
/ 12 декабря 2013

Эй, пожалуйста, используйте эти строки кодов, это поможет вам ..

 <!DOCTYPE html>
    <html>
        <head>
            <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>JSP Page</title>

        </head>
        <body>
            <h1>Hello World!</h1> 






        URL uri= new URL("Your url");
        URLConnection ec = uri.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(
                ec.getInputStream(), "UTF-8"));
        String inputLine;
        StringBuilder a = new StringBuilder();
        while ((inputLine = in.readLine()) != null)
            a.append(inputLine);
        in.close();

        out.println(a.toString());   
...