第二次结对编程

做业要求 https://edu.cnblogs.com/campus/fzzcxy/2018SE1/homework/11250
做业目标 <从云班课上爬取经验值数据,计算经验平均值、最高值、最低值,并根据学号(升序)、经验值(降序)列出学生列表>
做业源代码 https://gitee.com/huang-cunhui/team-work_200928
黄存慧 <211806385>
程仕 <211806312>

1、队员介绍

211806385,黄存慧,喜欢象棋、书法,偶尔运动,喜欢写前端代码和java代码php

211806312,程仕,喜欢国学名著,看文艺电视剧,敲代码的一把好手


html

2、题目要求

制做网页爬虫软件,将云班课上全班的课堂完成部分的经验值爬取下来,根据经验值排序,看看本身和本身的同窗在全班第几名,同时计算出平均经验、最低经验、最高经验

3、题目分析(解题步骤)

1.爬取数据(直接爬取网站数据,网站需登陆)
前端

  • 用本身的帐号登录须要爬取数据的网站
  • 经过开发者模式获取网站cookies
  • 复制网站url
  • 将url和cookies信息写入config.properties文件
  • 将配置文件放入resources文件夹中
  • 建立libs文件夹,存放jsoup-1.13.1.jar包
  • 将jsoup-1.13.1.jar包导入eclipse项目
  • 建立类名Team
  • 在Team类中实现爬虫代码

2.分析数据
java

  • 将每一个学生的经验值存储在列表中
  • 遍历列表,寻找最高经验值、最低经验值,并计算总经验值
  • 将总经验值除以学生人数,得出平均经验值
  • 遍历学生列表,寻找最高经验值得到者,将其放进输出列表中,而后重复寻找下一个最高经验者
  • 若是两个学生经验值相同,则先将学号靠前的放进输出列表
  • 未评分者单独处理,放置在末尾

3.输出数据
git

  • 输出最高经验值、最低经验值、平均经验值
  • 打印输出学生经验值排名



4、结对编程照片



5、代码时间占用

代码行数 195行
编写时间 8个小时
分析时间 3.5个小时


6、码云地址

>>点击跳转码云地址<<


web

7、代码说明

1.配置config.properties文件:将URL地址和COOKIE信息写入配置文件编程

url=https://www.mosoteach.cn/web/index.php?c=interaction&m=index&clazz_course_id=9E603F91-4AF8-11EA-9C7F-98039B1848C6 cookie=_uab_collina=158873178646017777712456;login_token=c9f6dc99114336166bd5ac5cec1ecba062ee2232fadca5bd46e1e0514e70ddee;teachweb=e85e83a51f1847bd068f22c9e437501053217534; SERVERID=75616bcd1ea8ec157e112381bf1eec35|1601810787|1601810140网页爬虫


2.在Team类中引入配置文件,建立Properties类对象propcookie

// 导入配置信息:获取properties文件中的url和cookie 
Properties prop = new Properties(); 
      try { 
            prop.load(new FileInputStream("resources/config.properties")); // 文件位置:相对路径引入 
      } catch (Exception e) { 
            e.printStackTrace(); // 出错处理 
      }

3.建立列表和document对象,经过配置信息的url和cookie解析目标网页,获取数据eclipse

// 建立列表
ArrayList<String> baseList = new ArrayList<String>();
		
// 建立document文件,经过url和cookie引入html网页的数据
Document document = (Document) Jsoup.connect(prop.getProperty("url")).header("cookie", prop.getProperty("cookie")).get();
if (document != null) {
      // 经过interaction-row类获取数据
      Elements activDivs = ((Element) document).getElementsByClass("interaction-row");
      for (int i = 0; i < activDivs.size(); i++) {
            if (activDivs.get(i).toString().contains("课堂完成")) {
                  String urlString = activDivs.get(i).attr("data-url").toString();
                  baseList.add(urlString);
            }
      }
} else { // url和cookie正常,但未获取到网页
System.out.println("出错啦!");
}

4.列表赋值,同时将数据写入文件

// 列表赋值
ArrayList<Student> newStudentList=stuList(baseList);
Collections.sort(newStudentList, new Student());
// 数据写入文件
write(newStudentList);

5.建立stuList方法,处理学生信息

public static ArrayList<Student> stuList(ArrayList<String> baseList) throws IOException {
      // 获取另外一个配置信息的对象prop1
      Properties prop1 = new Properties();
      try {
            prop1.load(new FileInputStream("resources/config.properties"));
      } catch (Exception e) {
            e.printStackTrace();
      }
      // 列表
      ArrayList<Document> baseActives = new ArrayList<Document>(baseList.size());
      ArrayList<Student> studentList = new ArrayList<>();

      for (int i = 0; i < baseList.size(); i++) {
            Document document1 = (Document) Jsoup.connect(baseList.get(i)).header("cookie", prop1.getProperty("cookie")).get();
            baseActives.add(document1);
      }

      for (int j = 0; j < baseActives.size(); j++) {
            Elements baseStuDivs = ((Element) baseActives.get(j)).getElementsByClass("homework-item");
                  for (int k = 0; k < baseStuDivs.size(); k++) {
                        try {
                              Student stu = new Student();
                              stu.setId(baseStuDivs.get(k).child(0).child(1).child(1).text().toString());
		              stu.setName(baseStuDivs.get(k).child(0).child(1).child(0).text().toString());
			      String score = baseStuDivs.get(k).child(3).child(1).child(1).text();
			      // 未评分的学生
			      if (baseStuDivs.get(k).child(3).child(0).child(1).text().contains("尚无评分")) {
			            stu.setScore(0.0);
			      }
			      // 未提交的学生
			      else if (baseStuDivs.get(k).child(1).child(0).text().contains("未提交")) {
			            stu.setScore(0.0);
			      } else {
			            stu.setScore(Double.parseDouble(score.substring(0, score.length() - 2)));
			      }
			            studentList.add(stu);
			      } catch (Exception e) {
		   }
      }
      ArrayList<Student> newStudentList = new ArrayList<>();
		Double totalScore;
		for (int i = 0; i < studentList.size(); i++) {
			totalScore = 0.0;
			Student student = new Student();
			for (int j = i + 1; j < studentList.size(); j++) {
				if (studentList.get(i).getName().contains(studentList.get(j).getName())) {
					totalScore += studentList.get(j).getScore();
					studentList.remove(j);
				}
			}
			student.setId(studentList.get(i).getId());
			student.setName(studentList.get(i).getName());
			student.setScore(totalScore);
			newStudentList.add(student);
		}
		return newStudentList;
       }
}

6.建立write方法,按照要求输出计算的数据

public static void write(ArrayList<Student> newStudentList) throws FileNotFoundException {
      File file = new File("score.txt");
      PrintWriter printWriter = new PrintWriter(new FileOutputStream(file), true);
      double ave = 0.0;
      for (int j = 0; j < newStudentList.size(); j++) {
            ave += newStudentList.get(j).getScore();
      }
      ave = ave / newStudentList.size();
      printWriter.println("最高经验值" + newStudentList.get(0).getScore() + ",最低经验值"
            + newStudentList.get(newStudentList.size() - 1).getScore() + ",平均经验值" + ave);
      for (int i = 0; i < newStudentList.size(); i++) {
            printWriter.println(newStudentList.get(i).toString());
      }
            printWriter.close();
}

7.建立学生类,代码完成

import java.util.Comparator;

public class Student implements Comparator<Student>{
	public String id;
	public String name;
	public double score;
	
	public Student() {
		super();
	}
	
	public Student(String id, String name, double score) {
		super();
		this.id = id;
		this.name = name;
		this.score = score;
	}
	
	public  String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}

	@Override
	public String toString() {
		return id + "," + name + "," + score;
	}

	@Override
	public int compare(Student o1, Student o2) {
		int sort1 = Integer.parseInt(o1.getId()) - Integer.parseInt(o2.getId());
		int sort2 = (int) (o2.getScore() - o1.getScore());
		return sort2==0?sort1:sort2;
	}
}

8、运行结果



9、相互评价

黄存慧对程仕的评价
程仕的idea很是多,不拘泥于传统的编程思惟,能够在项目规划的时候提出不少新的创意和点子,这对咱们这个小团队来讲相当重要,虽然程仕的编程基础误差,可是最近几回的结对做业都能积极主动地完成,能够明显感觉到他的努力,但愿咱们能够相互促进相互监督,在接下来的学习中收获更多的知识财富。

程仕对黄存慧的评价
此次结队做业对我的的要求比较高,就代码实现中第一步文件的获取和配置都很难对付。个人基础又过于薄弱,在课外知识的获取和运用上提供不了更有利的帮助。好在存慧力挽狂澜,用时间推动进度,用勤勉换取效率。


10、结对感觉

结对编程由最初的不习惯,到如今彼此熟悉,分工配合没有了当初的不适应感,取而代之的是不用多加说明的默契,此次的编程效率比上一次有明显的进展,可是仍是存在两我的意见分歧的时候,或许从此更多的磨合可让咱们两我的扬长避短,以更快的效率更高质量的代码来完成做业
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息