是否有任何有效的方法可以在Java中并行化大量的GET请求。我有一个200,000行的文件,每个行都需要来自Wikimedia的GET请求。然后我必须将一部分响应写入一个公共文件。我已将下面代码的主要部分粘贴为参考。
while ((line = br.readLine()) != null) {
count++;
if ((count % 1000) == 0) {
System.out.println(count + " tags parsed");
fbw.flush();
bw.flush();
}
//System.out.println(line);
String target = new String(line);
if (target.startsWith("\"") && (target.endsWith("\""))) {
target = target.replaceAll("\"", "");
}
String url = "http://en.wikipedia.org/w/api.php?action=query&prop=revisions&format=xml&rvprop=timestamp&rvlimit=1&rvdir=newer&titles=";
url = url + URLEncoder.encode(target, "UTF-8");
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
//con.setRequestProperty("User-Agent", USER_AGENT);
int responsecode = con.getResponseCode();
//System.out.println("Sending 'Get' request to URL: " + url);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
Document doc = loadXMLFromString(response.toString());
NodeList x = doc.getElementsByTagName("revisions");
if (x.getLength() == 1) {
String time = x.item(0).getFirstChild().getAttributes().item(0).getTextContent().substring(0,10).replaceAll("-", "");
bw.write(line + "\t" + time + "\n");
} else if (x.getLength() == 2) {
String time = x.item(1).getFirstChild().getAttributes().item(0).getTextContent().substring(0, 10).replaceAll("-", "");
bw.write(line + "\t" + time + "\n");
} else {
fbw.write(line + "\t" + "NULL" + "\n");
}
}
我用Google搜索,似乎有两种选择。一种是创建线程,另一种是使用称为Executor的东西。有人可以就哪一个更适合这项任务提供一些指导吗?
答案 0 :(得分:5)
如果您确实需要通过GET请求来实现,我建议您使用带有小线程池(2或3)的ThreadPoolExecutor,以避免重载维基百科服务器。这将避免大量编码...
还要考虑使用Apache HttpClient库(具有持久连接!)。
但更好的想法是使用数据库下载选项。根据您的操作,您可以选择较小的下载之一。 This page讨论了各种选项。
注意:Wikipedia 更喜欢人们下载数据库转储(等等),而不是在他们的Web服务器上敲击。
答案 1 :(得分:0)
你需要的是:
答案 2 :(得分:0)
如上所述,您应该根据服务器的容量确定并行GET请求的数量。如果你想坚持使用JVM但想要使用Groovy,这里是一个非常简短的并行GET请求示例。
最初有一个您要提取的网址列表。 完成后,任务列表包含可通过get()方法访问的所有结果,以便以后处理。这里只是打印出来作为例子。
import groovyx.net.http.AsyncHTTPBuilder
def urls = [
'http://www.someurl.com',
'http://www.anotherurl.com'
]
AsyncHTTPBuilder http = new AsyncHTTPBuilder(poolSize:urls.size())
def tasks = []
urls.each{
tasks.add(http.get(uri:it) { resp, html -> return html })
}
tasks.each { println it.get() }
请注意,您在生产环境中需要注意超时,错误响应等。