这是我在Java中遇到的最奇怪的事情。在这种情况下。我尝试在没有任何API的情况下阅读80多个网址(这真的很糟糕)。网页有一种显示我需要的信息的常用方式,因此我通常可以使用一些正则表达式语句找到感兴趣的项目。
这是我想要阅读的示例网页。 Webpage
我有两个非常草率的课程来实现这个目标:
Tester.java。 这里的Main方法只是从我的计算机上读取URL,并且每个方法都从Tools类调用一个方法,该方法返回一个ArrayList。然后它将ArrayList中的所有项添加到一个更大的ArrayList中,这是我想要的输出。我的程序从未实现过这一点。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Tester
{
public static int d2counter = 0;
public static void main(String[] args)
{
ArrayList<String> database = new ArrayList<>();
ArrayList<String> urls = new ArrayList<>();
try
{
FileReader writer = new FileReader("res/URLs.txt");
BufferedReader reader = new BufferedReader(writer);
while (reader.ready())
{
urls.add(reader.readLine());
}
for (String i : urls)
{
System.out.println(++d2counter + " " + i);
ArrayList<String> temp = Tools.readURL(i);
for (String h : temp)
{
database.add(h);
}
}
Tools.outputArraysToFile(database, "output.txt");
reader.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Tools.java。这是一个充满静态方法的辅助类。这里唯一感兴趣的方法是readURL()方法。
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
/**
* Class which will house useful tools for other classes in this program.
*/
public abstract class Tools
{
public static ArrayList<String> readURL(String address)
{
ArrayList<String> temp = new ArrayList<>();
try
{
// Create a reader to read the webpage.
BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(address).openStream()));
// Line variable to be used by Reader.
String line = "";
// Phase 1: Navigate to the desired section of the webpage.
int counter2 = 1;
while (reader.ready())
{
line = reader.readLine();
counter2++;
if (line.contains("MAIN CONTENT"))
{
break;
}
}
if (!reader.ready())
{
System.err.println("ERROR: Reached bottom of document without finding page title.");
System.exit(1);
}
String name, url, type;
type = "Default";
// Find the type.
for (int i = 0; i < 3; i++)
{
line = reader.readLine();
if (line.matches(".*<B>[A-Za-z\\s]+</b>.*"))
{
line = line.substring(line.indexOf("<B>") + 3, line.indexOf("</b>"));
line = line.replace("Normal", "");
line = line.replace("Exquisite", "");
line = line.replace("Elite", "");
line = line.trim();
if (line.endsWith("s"))
{
line = line.substring(0, line.length() - 1);
}
type = line;
break;
}
}
// Phase 2: Add data:
while (!line.contains("END MAIN CONTENT"))
{
line = reader.readLine();
if (line.contains(".gif"))
{
line = line.replaceFirst(".*src=\"", "");
url = "classic.battle.net" + line.substring(0, line.indexOf("\""));
for (int i = 0; i < 5; i++)
{
line = reader.readLine();
if (line.matches(".*<b>[-A-Za-z\\s]+</b>.*"))
{
line = line.replaceFirst(".*<b>", "");
line = line.replaceFirst("</b>.*", "");
name = line;
temp.add(name + "," + type + "," + url);
break;
}
}
}
}
reader.close();
}
catch (IOException e)
{
System.err.println("Unable to read from URL.");
e.printStackTrace();
}
return temp;
}
}
这是一个奇怪的部分:每次运行时程序都会随机失败。
甚至更多:如果您访问这些网页,您会发现他们都拥有&#34;主要内容&#34;在他们的代码中,我的.contains(&#34; MAIN CONTENT&#34;)行应检测到。我在帮助器打印语句中添加了它,以显示它所粘贴的URL以及该行是否存在。每次我使用调试器时,它都会按照我的说法运行。由于成千上万的输入线,我似乎无法通过这一切有效地打破我的方式。我不明白 - 这里肯定有我遗漏的东西。
谢谢大家!
答案 0 :(得分:2)
您错误地使用ready()
方法 - 事实上,您根本不应该使用它。当仍有数据要读取时,它会导致程序停止读取。
readLine()
方法就是您所需要的。当您到达文本末尾时,它会返回null
, 用于控制循环的内容。标准习语是:
String line = null;
while ((line = reader.readLine()) != null) {
// process the line
}
当ready()
返回false
时,它并不意味着没有任何内容可供阅读,这意味着基础流目前还没有准备好阅读,并且缓冲区中没有字符。换句话说,BufferedReader必须等待 - 可能是几毫秒 - 才能访问更多字符。在我看来,它是一种低级别的方法,甚至不应该具有public
可见性。许多人在你之前陷入了这个陷阱。