目录
前几日和一位带佬交谈了一番,觉得自己刷题的效率太慢了,简直是蜗牛速度,甚至连acm的基本都还没,于是决定奋发图强,利用碎片时间来思考题目,而手机上看HDU是很难受的,所以我想到离线题目,在空闲的时候可以在手机上看。于是就有了本文,离线HDU的题目。
参考
题目的灵感是来自于·使用python爬取HDU文章(除了图),但是我发现了他的一个问题就是,他的图片没法保存。
Java本身也有HTML解析的框架叫做 Jsoup,这个之前也只是听过,没有使用过,所以就按照网上教程,走一波。
原理
首先,我们知道HDU的题目是根据编号来取的,编号从1000-6543,中间好像有几个没有,不过不影响。
其次,找到HDU根据编号来获取题目页面的链接:这个链接 http://acm.hdu.edu.cn/showproblem.php?pid=1000
后面的PID就是我们需要变换的编号。可以使用Jsoup的页面来尝试进行元素的选择:Try Jsoup
将上文中的题目链接填入Fetch URL,页面会自动帮你做userAgent字段,我们就可以在页面中得到请求后的HTML代码,使用页面上自带的css Query测试可以得出这样几个选择的元素。
代码
首先我们使用Jsoup帮助我们发起请求抓取网页。
Document document = Jsoup.connect("http://acm.hdu.edu.cn/showproblem.php?pid=" + num)
.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '\n" +
" 'Chrome/51.0.2704.63 Safari/537.36")
.get();
1.使用h1这个元素可以获得每个题目的标题,比如1000这道题就是A + B Problem。
Elements elementList= document.getElementsByTag("h1");
/**
* 每个问题的标题
*/
if(elementList.size() == 1){
title = elementList.get(0).html();
}
2.使用span这个元素选择可以获得每个题目的语言内存限制与时间限制,以及AC/ToTal等信息。
/*** Limits */
Elements limites = document.getElementsByTag("span");
limits = limites.get(0).html();
3.使用panel_title以及panel_content可以分别获取以下几个部分的标题与内容:
1)Problem Description
2)Input
3)Output
4)Sample Input
5)Sample Output
6)Author
7)Recommend
得到之后发现一个问题,每个部分得到的内容都或多或少有HTML标签,不过markdown无惧,直接输出即可,代码中还包含了图片的处理。
Elements elements = document.getElementsByClass("panel_title");
Elements elements1 = document.getElementsByClass("panel_content");
if( elements.size() == elements1.size() ){
for(int i=0;i<elements.size();i++){
//System.out.println("=====================");
elements.get(i).html() ;//title
//System.out.println("====================");
Element contentElement = elements1.get(i);
if(contentElement.select("img[src$=.gif]") != null){
//说明这个tag中有img标签
Elements images = contentElement.select("img[src$=.gif]");
for(Element e : images){
String tmp = e.attr("src");
String imgPath = "http://acm.hdu.edu.cn" + tmp;
//System.out.println(imgPath);
e.attr("src",imgPath);
}
//tag处理完毕
}
sb.append(contentElement.html() + "\n");
}
}
最后,我们将得到的东西稍加一些处理,输出到markdown中,就会得到这样子:HDU 1067题目。
因为手机并不支持markdown格式,所以我将所有的题目上传至有道云笔记,在手机上安装有道云笔记,即可实现手机端查看题目。
缺点
1.目前爬下来的题目中有些题目中包含latex数学公式,而目前的markdown查看器并没有对其做支持,所以暂时还是以原来的格式。
2.目前的就内容来说,样例输入和样例输出和官网对比会有位置的变化,后续有空了优化。
3.其他地方的不适暂未发现,如有发现的话可以在评论区提出。
源码
最后的最后,全部代码将开源在我本人的Github仓库中。有兴趣的可以参考下,代码本身写的很菜,还望轻喷。另外,,使用前记得添加Jsoup的支持。hdu_problem_offline