`
lifethinker
  • 浏览: 72086 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

下载Project Euler题目

    博客分类:
  • java
阅读更多

就要放寒假了,总要给自己找点事做,于是想到要将projecteuler 题目下载到本地。我首先想到的是用wget的递归下载,发现projecteuler使用robot.txt阻止了wget下载。看来projecteuler早就想到要防止吾辈这样的小人,但是所谓小人难防,小人自有小人的方法。

 

我使用的方法就是通过自己编程的方法来实现wget递归下载的功能,当然就不用考虑robot.txt啦 。代码见下,主要是downPage方法,步骤是:

  1. 得到绝对URL,如果这个URL不属于projecteulr.net域或者已经下载了就直接返回,否则将这个URL添加到下载集合中。
  2. 如果这个URL是不是HTML页面(图像文件,css,javascript等),直接将它下载到本地对应的目录。下载时文件名要做转换,因为URL中通常包含"?",":"等这个的特殊字符,但是它们一般不允许出现在文件名当中。这里我简单地将这么特殊字符都替换成下划线"_"。
  3. 如果是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("&amp;", "&").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代码

    【标题】"ProjectEuler1-16代码"所涉及的知识点主要集中在计算机编程和算法设计上,尤其针对初学者和编程爱好者。Project Euler是一个在线平台,它提供了一系列的数学和计算机科学问题,旨在通过解决这些问题来提升...

    Project Euler 第22题

    实际问题的规则可能更复杂,需要根据Project Euler的完整题目描述来调整算法。记住,Project Euler的目的是理解问题、设计有效的算法,而不是仅仅找到答案。因此,代码的效率和可读性同样重要。

    project euler problem 5

    题目:Project Euler问题5——寻找最小公倍数 在Project Euler的问题集中,问题5要求我们找到能被1至20所有数字整除的最小正整数。这个问题实际上是在寻找这组数字的最小公倍数(LCM)。对于较小的参数值,如本例中...

    project euler1.rar_ACM_project_project euler

    【项目欧拉(Project Euler)】是一个非常受欢迎的在线数学和计算机编程挑战平台,它吸引着全球的程序员和数学爱好者参与。项目欧拉的问题通常涉及数学、算法和计算机科学,鼓励解决问题并学习新技能。本压缩包...

    project euler5.rar_ACM_project

    【描述】"project euler代码库第五部分(已测试通过)"表明这些代码是用于解决Project Euler系列问题中的第五部分题目,而且所有的代码都已经经过了测试,确保能够正确地计算出每个问题的答案。这通常意味着代码具有...

    projecteuler.net:我对 Project Euler 问题的一些解决方案

    在这个"projecteuler.net:我对 Project Euler 问题的一些解决方案"中,我们可以预见到包含的是作者对 Project Euler 题目的Java实现。 在项目中,"projecteuler.net-master"很可能是一个GitHub仓库的名字,通常这样...

    project euler欧拉工程1-50题代码golang版

    全部在linux下运行通过...因为是个人联系所做,所以代码中没有注释,不过我相信只要你真的有去思考题目也是能知道我为什么这样做 另外用的是LF换行,也就是linux系统的换行,在windows下请用notpad++等高级编辑器打开

    Project Euler_Eulerproject_fasmg_x86_windows_math_

    《使用汇编语言解决Project Euler问题的探索》 在IT领域,编程挑战是提升技能、锻炼思维的重要方式,其中Project Euler以其独特的数学与计算机科学相结合的特性,深受程序员喜爱。本项目聚焦于"Project Euler",它...

    matlab用不同编程语言实现的各种Project Euler问题的解决方案.zip

    《MATLAB实现Project Euler问题详解》 Project Euler是一个著名的在线数学和计算机科学挑战平台,它提供了许多具有挑战性的问题,旨在提升编程技能和数学理解。本资料包“matlab用不同编程语言实现的各种Project ...

    project euler3.rar_ACM_project

    《ACM项目:Project Euler第三部分解题代码详解》 Project Euler是一个著名的在线数学与计算机科学问题集,旨在挑战编程者的思维能力和算法技巧。在这个压缩包"project euler3.rar_ACM_project"中,包含了10个已经...

    projecteuler-solutions:所有700多个Euler项目问题​​的数值答案

    顾名思义,projecteuler-solutions是站点Project Euler的解决方案的集合。 该站点旨在为Euler项目提供完整而准确的解决方案清单。这个网站的目的是什么? 在一个棘手的问题上奋斗了数小时或数天之后,您最终可能会...

    project-euler-源码.rar

    2. **数学知识**:Project Euler题目与数学密切相关,可能涉及素数、同余方程、组合数学、数论函数(如欧拉函数、阶乘)、几何公式(平面几何、立体几何)等。通过阅读源码,我们可以学习如何将数学理论应用于编程...

    project_euler:应对Project Euler挑战(https:projecteuler.net)

    在数学方面,Project Euler 题目涵盖了广泛的领域,包括但不限于: 1. **基础数学**:加减乘除、整数、分数和小数的运算。 2. **算术与几何**:比例、面积、体积、勾股定理等。 3. **代数**:方程求解、多项式运算...

    ProjectEuler:我放置 ProjectEuler 代码的地方

    "ProjectEuler:我放置 ProjectEuler 代码的地方"这个标题揭示了一个专注于解决Project Euler问题的项目。Project Euler是一个在线平台,提供了一系列富有挑战性的数学和计算机科学问题,旨在提高编程技能并推动对...

    ProjectEuler:欧拉计划工作的地方

    "ProjectEuler:欧拉计划工作的地方" 指的是一个与 Project Euler 相关的项目或代码库,Project Euler 是一个在线平台,提供了许多数学和计算机科学问题供用户解决,以此来提升编程技巧和数学理解。 **描述分析:** ...

    Project-Euler.chm

    Project-Euler的chm版,制作时间2014‎年‎9‎月‎4‎日,题目截止到478题. 欢迎交流.

    projecteuler_test:project euler python 训练

    在"projecteuler_test-master"这个目录下,你可能找到了包含练习题目、解决方案以及测试脚本的文件。通过逐步学习和实践这些内容,你将在Python编程和数学应用方面得到显著提升,同时也能更好地应对Project Euler和...

    project-euler:各种 Project Euler 问题的 Javascript 解决方案

    11. **算法设计**:理解并能应用各种算法,如动态规划、贪心算法、回溯、分治等,是解决 Project Euler 题目的核心。 12. **性能优化**:由于许多 Project Euler 问题涉及到大量的计算,了解如何优化代码以减少运行...

    project_euler:我的项目euler文件

    项目Euler(Project Euler)是一个非常受欢迎的在线问题解决平台,专注于数学和计算机科学的交叉领域。它提供了一系列具有挑战性的题目,旨在提高编程技能,尤其是数学应用和算法设计方面的能力。这个"project_euler...

Global site tag (gtag.js) - Google Analytics