Github地址:https://github.com/qwe8/pair-project
队友博客: 
林志华: 完成爬虫及将第一次作业C++代码转化为JAVA代码
王焕仁: 使用JAVA实现其余功能
这次作业我们选择用JAVA来写,是经过深思熟虑的。其一是觉得用C++来写爬虫的话,对我们来说都没有接触过,而且听说很麻烦的。其二是觉得需要学习一下JAVA的用法,毕竟是现在最火的语言。其三,是我其实大一下学期有自学过JAVA,但长时间没用变得很生疏,现在重新拾起来感觉也不错。由上三点我们选择了JAVA来解题。


从单单这个标题我们还看不出什么东西,我们再复制一下下一篇论文的CSS选择器:dt.ptitle:nth-child(4) > a:nth-child(2),可以发现第一个选择参数的括号里的值增加了三,那么再多复制几个,即可发现所有标题的选择器是dt.ptitle:nth-child(1+3n) > a:nth-child(2)。所以我们即可利用下面的代码来爬取所有标题:
                   Elements test=document.select("dt.ptitle:nth-child(1)").select("a:nth-child(2)");
           String str=test.text();//返回的是标题
           String url2=test.attr("href"); // 爬取
爬取到标题后,可以用爬取标题的超链接,然后爬取这个超链接指向的网站,使用上述的方法继续爬取即可。
       String url2=test.attr("href");//爬取标题的 href 值
           Document document2 = Jsoup.connect("http://openaccess.thecvf.com/"+ url2).userAgent("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)").timeout(50000).get();//下个网页可以直接使用jsoup来爬取html。
我们把所有的功能都封装成一个类,结构图如下:

类中具体函数如下:
public class WordCount {
    private static List<HashMap.Entry<String, Integer>> words = null;  //存放单词
    private static List<HashMap.Entry<String, Integer>> phrases = null; //存放词组
    public WordCount(File fileIn); // 类构造函数
    public int getcharnum();  // 获取字符数
    public int getlinenum();   // 获取行数
    public int getwordnum(); // 获取单词数
    public int getphrasenum(int gs); //获取词组数
}
爬虫部分:
   public static void main(String []args)throws IOException{
       String URL="http://openaccess.thecvf.com/CVPR2018.py";
       String content= getHtmlByUrl(URL); //使用httpclient 爬取网页html
       Document document = Jsoup.parse(content); //使用Jsoup来解析html
       String num,left="dt.ptitle:nth-child(",right="a:nth-child(2)"; //设定CSS选择器
       int t=1,nb=0; //t为left的参数
       File f=new File("result.txt");
       PrintWriter pw=new PrintWriter( new FileWriter(f,true) );
       while(t<=2935){
           num=t+"";
           Elements test=document.select(left+num+")" ).select(right);//利用CSS选择器来抓取标题那部分的html
           String str=test.text();// 获取标题
           String url2=test.attr("href"); //获取标题的超链接
           //根据超链接利用jsoup爬取下个网页的html
           Document document2 = Jsoup.connect("http://openaccess.thecvf.com/"+ url2).userAgent("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)").timeout(50000).get();
           Elements test2=document2.select("#abstract"); // 选择abstract部分
           String str2=test2.text();
           System.out.println("输出到第"+nb+"个");
           pw.write(""+nb);pw.write("\r\n");
           pw.write("Title: "+ str);pw.write("\r\n");
           pw.write("Abstract: "+str2);pw.write("\r\n\r\n\r\n");
           t+=3;nb++;
       }
       pw.close();
       System.out.println("爬取完成");
   }
性能分析图如下:


通过性能分析我发现HashMap这个容器使用耗时非常多,后来发现当用户需要经行词组统计时,程序还是会进行单词统计的一些步骤,就是把单词给丢到HashMap中,可实际上这是不需要的。所以我们在类中设置一个boolean参数来表示是要经行单词统计还是要经行词组统计,不统计的那部分就不需要再使用HashMap,理论上这可将时间优化将近一倍。

十个单元测试如下:
测试结果如下:

以下给出三个测试代码:
@Test
public void test4(){// 测试  不出现-m 的  -w 1 
        File file = new File("4.txt");
        WordCount count = new WordCount(file);//实例话WordCount类
        count.set_quan(true);
        int wordnum = count.getwordnum();//读取单词数
        int linenum = count.getlinenum();//获取有效行数
        assertEquals(wordnum, 29);
        assertEquals(linenum, 3);
        List<HashMap.Entry<String, Integer>> m = count.getWords();
        int aa=m.get(0).getValue();
        String bb=m.get(0).getKey();
        assertEquals( aa , 51);
        assertEquals(bb, "embodied");
}
@Test
public void test6(){ // 测试 出现-m 的 -w 1
        File file = new File("6.txt");
        WordCount count = new WordCount(file);//实例话WordCount类
        count.set_quan(true);
        int wordnum = count.getwordnum();//读取单词数
        int linenum = count.getlinenum();//获取有效行数
        int phrasenum = count.getphrasenum(3);//获取有效词组数
        assertEquals(wordnum, 29);
        assertEquals(linenum, 3);
        List<HashMap.Entry<String, Integer>> m = count.getPharses();
        int aa=m.get(0).getValue();
        String bb=m.get(0).getKey();
        assertEquals( aa , 20);
        assertEquals(bb, "embodied embodied embodied");
}
@Test
public void test8(){ // 测试 -m 参数 接收
    File file = new File("8.txt");
        WordCount count = new WordCount(file);//实例话WordCount类
        int wordnum = count.getwordnum();//读取单词数
        int linenum = count.getlinenum();//获取有效行数
        int phrasenum = count.getphrasenum(8);//获取有效词组数
        assertEquals(wordnum, 64);
        assertEquals(linenum, 3);
        List<HashMap.Entry<String, Integer>> m = count.getPharses();
        int aa=m.get(0).getValue(),cc=m.get(9).getValue();
        String bb=m.get(0).getKey(),dd=m.get(9).getKey();
        assertEquals( aa , 4);
        assertEquals(bb, "asdf zxcv jklq aaaa asdf zxcv jklq aaaa");
        assertEquals( cc , 1);
        assertEquals(dd, "aaaa wjoi oifvf nvxlj qwoei jfsiod fdss vffr2f4");
}

原文:https://www.cnblogs.com/qwe1/p/9763963.html