就要放寒假了,总要给自己找点事做,于是想到要将projecteuler
题目下载到本地。我首先想到的是用wget的递归下载,发现projecteuler使用robot.txt阻止了wget下载。看来projecteuler早就想到要防止吾辈这样的小人,但是所谓小人难防,小人自有小人的方法。
我使用的方法就是通过自己编程的方法来实现wget递归下载的功能,当然就不用考虑robot.txt啦
。代码见下,主要是downPage方法,步骤是:
- 得到绝对URL,如果这个URL不属于projecteulr.net域或者已经下载了就直接返回,否则将这个URL添加到下载集合中。
- 如果这个URL是不是HTML页面(图像文件,css,javascript等),直接将它下载到本地对应的目录。下载时文件名要做转换,因为URL中通常包含"?",":"等这个的特殊字符,但是它们一般不允许出现在文件名当中。这里我简单地将这么特殊字符都替换成下划线"_"。
- 如果是HTML页面,那么过程要复杂一些。首先需要搜寻这个页面中所有链接(包括<a>,<img>,<link>中的链接),如果这些链接属于projecteuler.net域,将它们替换成本地路径,并调用downloadPage方法将它们下载到本地,否则保持原地址不变,最后将替换后的页面保存在本地。同样保存在本地的文件名要做转换。
public class ProjectEuler {
private static final String ROOT_URL = "http://projecteuler.net/index.php?section=problems";
private static final String PROJECT_EULER = "http://projecteuler.net";
private static final Pattern LINKS_PATTERN = Pattern.compile("(<(?:a|link|img)\\s+(?:\\w+=\"[^\"]*\"\\s+)*(?:href|src)=\")([^\"]*)(\")");
private static File rootDir = new File("projecteuler");
private static Set<String> downloadingPages = new HashSet<String>();
public static void main(String[] args) throws MalformedURLException, IOException {
downloadPage("", ROOT_URL);
}
private static void downloadPage(String baseUrl, String url) throws MalformedURLException, IOException {
String absUrl = absoluteUrl(baseUrl, url);
if (!absUrl.startsWith(PROJECT_EULER) || downloadingPages.contains(absUrl)) return;
System.out.println("donwloading page: " + absUrl);
downloadingPages.add(absUrl);
HttpURLConnection conn = (HttpURLConnection) new URL(absUrl).openConnection();
InputStream in = conn.getInputStream();
File localFile = new File(rootDir, getPathComp(absUrl));
localFile.getParentFile().mkdirs();
if (conn.getContentType().indexOf("html") != -1) { // html
Reader reader = new InputStreamReader(in, "utf-8");
if (localFile != null) {
StringBuilder sb = new StringBuilder();
while (true) {
int c = reader.read();
if (c == -1) break;
sb.append((char)c);
}
String content = sb.toString();
Matcher matcher = LINKS_PATTERN.matcher(content);
StringBuffer newContent = new StringBuffer();
while (matcher.find()) {
String link = matcher.group(2).replaceAll("&", "&").trim();
// System.out.println("find link: " + link);
if (link.length() > 0) {
downloadPage(absUrl, link);
String absLink = absoluteUrl(absUrl, link);
matcher.appendReplacement(newContent, "$1"+(absLink.startsWith(PROJECT_EULER)?getPathComp(absLink):absLink)+"$3");
} else {
matcher.appendReplacement(newContent, matcher.group());
}
}
matcher.appendTail(newContent);
Writer writer = new OutputStreamWriter(new FileOutputStream(localFile), "utf-8");
writer.write(newContent.toString());
writer.close();
}
} else {
OutputStream os = new FileOutputStream(localFile);
byte[] buf = new byte[1024];
while (true) {
int readSize = in.read(buf);
if (readSize == -1) break;
os.write(buf, 0, readSize);
}
os.close();
}
in.close();
System.out.println("ending downloading page: " + absUrl);
}
private static String correctFileName(String urlName) {
char[] specialChars = "?:&;=".toCharArray();
for (int i = 0; i < specialChars.length; i++) {
urlName = urlName.replace(specialChars[i], '_');
}
return urlName;
}
private static String absoluteUrl(String baseUrl, String url) {
if (url.startsWith("http:") || url.startsWith("https:")) {
return url;
} else {
baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/')+1);
if (url.startsWith("/")) {
return baseUrl.substring(0, baseUrl.indexOf('/'))+url;
} else {
return baseUrl+url;
}
}
}
private static String getPathComp(String absoluteUrl) {
if (absoluteUrl.startsWith(PROJECT_EULER)) {
return correctFileName(absoluteUrl.substring(PROJECT_EULER.length()+1));
} else {
return null;
}
}
}
代码可以从附件中得到,不提供下载后的题目,主要担心有版权限制。如果你需要这些题目并且不想运行程序,可以联系我。
分享到:
相关推荐
ProjectEuler题1-16题代码,直接引入Eclipse就可以用
project euler代码库1,已测试通过
NULL 博文链接:https://linuke.iteye.com/blog/1056283
solution to problem 5
Project Euler solutions in assembler.
NULL 博文链接:https://lampeter123.iteye.com/blog/423036
欧拉计划projecteuler.net
projecteuler.net 我对 Project Euler 问题的一些解决方案: :
project euler代码库第二部分(已测试通过
project euler代码库第三部分(已测试通过
project euler代码库第五部分(已测试通过
项目欧拉解决方案该存储库包含我对 Project Euler (projecteuler.net) 上发现的编程问题的所有答案。 每个解决方案都是用 Java 编写的,旨在从命令行运行。 解决方案文件中将提供指向相关欧拉问题的链接。 某些解决...
ProjectEulerQuestions projecteuler.net 上问题的解决方案
project-euler:多种语言的projecteuler.net问题解决方案
project_euler Project Euler 问题的解决方案 ###Problem 1 - 3 和 5 的倍数### 如果我们列出所有 10 以下是 3 或 5 的倍数的自然数,我们得到 3、5、6 和 9。这些倍数的和是 23。求1000 以下所有 3 或 5 的倍数之...
Algorithm-hacktoberfest-projecteuler.zip,此repo包含多种语言的projecteuler问题的解决方案。为新来者特别设计,作为黑客节挑战的一部分。,算法是为计算机程序高效、彻底地完成任务而创建的一组详细的准则。
投影仪Project Euler 问题的解决方案,请参阅地位# 名称秒1 3 和 5 的倍数0.02 甚至斐波那契数列0.03 最大素因数0.94 最大的回文产品0.15 最小倍数2.56 和平方差0.07 第 10001 个素数0.1解决方案8 系列中最大的产品...
Project-Euler 我使用 C++ 解决 Project Euler 问题 摘自网站: “欧拉计划是一系列具有挑战性的数学/计算机编程问题,需要的不仅仅是数学洞察力来解决。虽然数学可以帮助你找到优雅有效的方法,但解决大多数问题...
ProjectEuler + 我在Java中(仅Java)对HackerRank的解决方案。 有关更多详细信息,请。 相信我,不是一个奇怪的网站。 ##为什么要用Java? 很好的问题。 会的,如果您是在C ++中使用“ unsigned int / long”的,...