就要放寒假了,总要给自己找点事做,于是想到要将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;
}
}
}
代码可以从附件中得到,不提供下载后的题目,主要担心有版权限制。如果你需要这些题目并且不想运行程序,可以联系我。
分享到:
相关推荐
【标题】"ProjectEuler1-16代码"所涉及的知识点主要集中在计算机编程和算法设计上,尤其针对初学者和编程爱好者。Project Euler是一个在线平台,它提供了一系列的数学和计算机科学问题,旨在通过解决这些问题来提升...
实际问题的规则可能更复杂,需要根据Project Euler的完整题目描述来调整算法。记住,Project Euler的目的是理解问题、设计有效的算法,而不是仅仅找到答案。因此,代码的效率和可读性同样重要。
题目:Project Euler问题5——寻找最小公倍数 在Project Euler的问题集中,问题5要求我们找到能被1至20所有数字整除的最小正整数。这个问题实际上是在寻找这组数字的最小公倍数(LCM)。对于较小的参数值,如本例中...
【项目欧拉(Project Euler)】是一个非常受欢迎的在线数学和计算机编程挑战平台,它吸引着全球的程序员和数学爱好者参与。项目欧拉的问题通常涉及数学、算法和计算机科学,鼓励解决问题并学习新技能。本压缩包...
【描述】"project euler代码库第五部分(已测试通过)"表明这些代码是用于解决Project Euler系列问题中的第五部分题目,而且所有的代码都已经经过了测试,确保能够正确地计算出每个问题的答案。这通常意味着代码具有...
在这个"projecteuler.net:我对 Project Euler 问题的一些解决方案"中,我们可以预见到包含的是作者对 Project Euler 题目的Java实现。 在项目中,"projecteuler.net-master"很可能是一个GitHub仓库的名字,通常这样...
全部在linux下运行通过...因为是个人联系所做,所以代码中没有注释,不过我相信只要你真的有去思考题目也是能知道我为什么这样做 另外用的是LF换行,也就是linux系统的换行,在windows下请用notpad++等高级编辑器打开
《使用汇编语言解决Project Euler问题的探索》 在IT领域,编程挑战是提升技能、锻炼思维的重要方式,其中Project Euler以其独特的数学与计算机科学相结合的特性,深受程序员喜爱。本项目聚焦于"Project Euler",它...
《MATLAB实现Project Euler问题详解》 Project Euler是一个著名的在线数学和计算机科学挑战平台,它提供了许多具有挑战性的问题,旨在提升编程技能和数学理解。本资料包“matlab用不同编程语言实现的各种Project ...
《ACM项目:Project Euler第三部分解题代码详解》 Project Euler是一个著名的在线数学与计算机科学问题集,旨在挑战编程者的思维能力和算法技巧。在这个压缩包"project euler3.rar_ACM_project"中,包含了10个已经...
顾名思义,projecteuler-solutions是站点Project Euler的解决方案的集合。 该站点旨在为Euler项目提供完整而准确的解决方案清单。这个网站的目的是什么? 在一个棘手的问题上奋斗了数小时或数天之后,您最终可能会...
2. **数学知识**:Project Euler题目与数学密切相关,可能涉及素数、同余方程、组合数学、数论函数(如欧拉函数、阶乘)、几何公式(平面几何、立体几何)等。通过阅读源码,我们可以学习如何将数学理论应用于编程...
在数学方面,Project Euler 题目涵盖了广泛的领域,包括但不限于: 1. **基础数学**:加减乘除、整数、分数和小数的运算。 2. **算术与几何**:比例、面积、体积、勾股定理等。 3. **代数**:方程求解、多项式运算...
"ProjectEuler:我放置 ProjectEuler 代码的地方"这个标题揭示了一个专注于解决Project Euler问题的项目。Project Euler是一个在线平台,提供了一系列富有挑战性的数学和计算机科学问题,旨在提高编程技能并推动对...
"ProjectEuler:欧拉计划工作的地方" 指的是一个与 Project Euler 相关的项目或代码库,Project Euler 是一个在线平台,提供了许多数学和计算机科学问题供用户解决,以此来提升编程技巧和数学理解。 **描述分析:** ...
Project-Euler的chm版,制作时间2014年9月4日,题目截止到478题. 欢迎交流.
在"projecteuler_test-master"这个目录下,你可能找到了包含练习题目、解决方案以及测试脚本的文件。通过逐步学习和实践这些内容,你将在Python编程和数学应用方面得到显著提升,同时也能更好地应对Project Euler和...
11. **算法设计**:理解并能应用各种算法,如动态规划、贪心算法、回溯、分治等,是解决 Project Euler 题目的核心。 12. **性能优化**:由于许多 Project Euler 问题涉及到大量的计算,了解如何优化代码以减少运行...
项目Euler(Project Euler)是一个非常受欢迎的在线问题解决平台,专注于数学和计算机科学的交叉领域。它提供了一系列具有挑战性的题目,旨在提高编程技能,尤其是数学应用和算法设计方面的能力。这个"project_euler...