Чтение содержимого веб-сайта в строку
В настоящее время я работаю над классом, который можно использовать для чтения содержимого веб-сайта, указанного в 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));
, но я не смог выразить это по-другому. Хорошо ли создавать новую строку на каждой итерации? Я полагаю, нет.
Любые другие слабые точки?
Спасибо заранее!
Ответы
Ответ 1
Рассмотрим вместо этого 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);
Ответ 2
Я настоятельно рекомендую использовать выделенную библиотеку, например 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")));
Ответ 3
Если это не какое-то упражнение, которое вы хотите закодировать ради обучения... Я бы не изобретал велосипед, и я бы использовал HttpURLConnection.
HttpURLConnection
обеспечивает хорошие механизмы инкапсуляции для работы с протоколом HTTP. Например, ваш код не работает с перенаправлением HTTP, HttpURLConnection
исправит это для вас.
Ответ 4
Вы можете обернуть InputStream
в InputStreamReader
и использовать it read()
method для непосредственного чтения символьных данных (обратите внимание, что вы должны указать кодировку при создании Reader
, но определение кодировки произвольных URL-адресов является нетривиальным). Затем просто вызовите sb.append()
с помощью char[]
, который вы только что прочитали (и правильное смещение и длина).
Ответ 5
Эй, пожалуйста, используйте эти строки кодов, это поможет вам...
<!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());
Ответ 6
Я знаю, что это старый вопрос, но я уверен, что другие люди тоже его найдут.
Если вы не возражаете против дополнительной зависимости, здесь очень простой способ
Jsoup.connect("http://example.com/").get().toString()
Вам понадобится библиотека Jsoup, но вы можете быстро добавить ее с помощью maven/gradle, а также манипулировать содержимым страницы и находить определенные узлы.