使用Jsoup实现批量下载HDU的题目

目录

起因

参考

原理

代码

缺点

源码  


前几日和一位带佬交谈了一番,觉得自己刷题的效率太慢了,简直是蜗牛速度,甚至连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

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值