第二次结对作业

作业要求 https://edu.cnblogs.com/campus/fzzcxy/2018SE2/homework/11248
作业目标 <实现网页爬取数据,对数据进行进一步的处理分析>
作业源代码 <https://gitee.com/xu-qianlong/pair >
队员1 <211806417 徐千龙>
队员2 <211814113 黄朝阳>

写在开头

可怜的国庆8天假,被砍成了4天,更惨的是4天还要敲代码。

所以我和我的搭档决定,尽量国庆之前搞完uml,放一个相对轻松点的假期。

结对感受

  • 一拍即合,相处融洽。针对结对中遇到的困难,一起突破解决。双方分工明确,互通有无。在过程体会代码的快乐,共同进步,共同提高。

  • 徐:因为是老搭档了,分工明确,合作很默契。

  • 黄:老默契,老摸鱼了。

对方评价

  • 徐:黄朝阳同学,努力又心细,不仅完成了他的那部分代码,还帮我完善了我的代码格式,针不戳(真不错)!

  • 黄:千龙性格良好,且总能提出细节上的重点,补充完善了交互模型的各个方面,nice!

开局一张图,发育去全靠emmmmmmmmmmmmm

1. 需求分析

  • 通过网络爬取数据,需要运用Cookies等信息
  • 数据排序,经验值优先,学号次之
  • IO将获取数据写入 txt 文件
  • Other:这次作业和第一次个人编程作业很像,之前是用html文件抓取内容,这次则是用url和cookie信息在真正的网页上抓取内容,感觉挺有成就感的吧。

2. 时间预计

估计 实际
代码行数 / 182行
思路 10h 24h
理出逻辑 2h 5h
编程 6h 12h
博客 1h 2h
总计 / 43h

3. 作业思路

3.1 抓取课堂完成部分URL

每个小模块都有一个data—url,需要将它们保存到一个数组或集合里。之后访问才能访问到课堂完成部分对应的小模块链接的网址。

如图所示

  • 抓取URL,并访问模块。

  •   Properties prop = new Properties();
      prop.load(new FileInputStream("resources//config.properties"));
      Enumeration fileName = prop.propertyNames();
      String url =prop.getProperty("url");
      String cookie=prop.getProperty("cookie");
    
  • 我们先将所需的URL链接,以及cookie信息,爬取,放入config.properties 的配置文件,然后通过文件的配置,完成访问。

    • 优点:相比本地通过 html 文件爬取数据,更加灵活。
    • 缺点:使用cookie 存在被封禁的可能性。cookie配置信息,有时候会出现意外,需要重新配置。

3.2 访问每个小模块,并抓取最终得分。将抓取的数据保存到对象集合里

抓取最终得分的分数,这里分数与经验值同步。通过 hash 存放数据,以及加强 for 取数据发生比对。

  • 通过 hash 获取学生的姓名学号,以及经验值。这里我们分成了两个小模块,1. 获取学生姓名和学号:Get_Student_snameandsno 2.获取学生经验值:Get_Student_Score

  • Get_Student_snameandsno 模块。

  • for(int i=0;i<es.size();i++) {
    		 String sname = es.get(i).select("span").get(0).text();
    		 String sno = es.get(i).getElementsByClass("member-message").get(0).child(1).text();
    		 Student stu=new Student(sname,sno);
    		 Student_Set.add(stu);
    	}
    
    • 优点:利用hash,更方便的添加所需的数据。
    • 缺点:利用子元素查询,效率较低
  • Get_Student_Score 模块

    • 利用for循环获取拘束,通过 if 判断,避免空指针问题。

3.4 排序,利用IO流将数据写入 TXT 文件

  • 排序模块 Student_Sort(Set Student_Set) 利用hash 进行排序。

    • 优点:取数据方便,能够快捷高效的获取数据
    • 缺点:因为 hash 是无序的,所以排序会变比较麻烦,我们通过两个 hash 来降低排序的麻烦程度。
  • IO流,写入数据

  • BufferedWriter out = new BufferedWriter(new FileWriter(writeName));
    out.write("最高经验值为:" + Sort_student[0].getScore() + "," + " 最低经验值为:" + Sort_student[i - 1].getScore() +
                    "," + " 平均经验值为:" + String.format("%.1f", (sum / i - 1)));
    
  • BufferedWriter outStudent = new BufferedWriter(new FileWriter(writeName,true));
    
  • 写入 统计经验和学生的经验,有一些细微的区别。

    • 统计经验的写入,我们采用了直接写入,每次都是将txt文件清空,重新写入,保证统计值,是显示在第一行,并且不会发现重复

    • 学生经验的写入,我们采用了续写, 在统计经验的后面继续写入。

    • TXT文件展示

4. 作业遇到的问题

  1. 有些课堂完成部分,会遇到同学未提交的情况,这样会造成数据获取时发生越界问题。

    • 解决办法:新增一个判断。—— 判断是否为未提交
    • 在for循环里面加一个 if (!pd) 判断该同学是否未提交,如果为未提交,则跳过后面分数计算部分,成功避免越界问题。
  2. 这类的是有最终得分:但是最终得分是尚无评分,截取的时候也会出现问题

    • 解决办法:新增一个判断 —— 判断是否为 尚无评分,是的话,则跳过。
  3. 解决问题的代码如下。

boolean pd = es.get(i).getElementsByClass("homework-info").text().contains("未提交");
if(!pd) {
	String sname = es.get(i).select("span").get(0).text();
	String xmk = es.get(i).getElementsByClass("appraised-type").get(1).select("span").get(1).text();
if(xmk.equals("尚无评分")) {
			  }
else {
	String score = xmk.substring(0,xmk.indexOf("分"));
	float f = Float.parseFloat(score);  
	for(Student student:Student_Set) {
		if(sname.equals(student.getName())) {
			student.addScore(f);
			break;
		 }
	}
}
}

5. 小结

  • 通过这次作业,加深了结对之间的默契,加强了队 json 相关的能力,以及进一步的学会网页的数据爬取,io 文件写入的熟悉。
  • 学会初步的使用 hash 进行获取数据
原文地址:https://www.cnblogs.com/SakuraHCY/p/13764796.html