private static CourseInfo ExtractCourseInfo(HtmlNodeCollection children) { // Make sure to strip away all whitespaces (trim everything) CourseInfo courseInfo = new CourseInfo(); courseInfo.CourseName = children[0].InnerText.Trim(); courseInfo.Teacher = children[1].InnerText.Trim(); courseInfo.IsElective = children[2].InnerText.Trim() != "Задължителни"; // The text in Grade and IsTaken is put inside a span unlike all the other cells, so find the first span child courseInfo.IsTaken = children[3].SelectSingleNode("span").InnerText.Trim() == "да"; // If the grade is empty, set it to 0 (exam may have not yet passed) string gradeAsText = children[4].SelectSingleNode("span").InnerText.Trim(); if (gradeAsText.Length != 0) { courseInfo.Grade = Double.Parse(gradeAsText.Substring(0, 1)); } else { courseInfo.Grade = 0; } courseInfo.Credits = Double.Parse(children[5].InnerText.Trim()); return(courseInfo); }
/// <summary> /// Gets a collection of <see cref="CourseInfo"/> that shows all courses that the student has passed successfully. /// </summary> public IEnumerable <CourseInfo> GetCourses() { if (this.Cookies.Count == 0) { throw new InvalidOperationException("You must login prior to getting info from SUSI"); } try { // Get the exam page and parse it string examPage = this.GetExamPage(); HtmlDocument document = new HtmlDocument(); document.LoadHtml(examPage); // Use a magical xpath to get all rows of the courses table, there may be header rows though string xpath = @"/html/body/form/table/tr/td/table[@width=""100%""]/tr/td/table/tr[not(@class)]"; var nodes = document.DocumentNode.SelectNodes(xpath); // Set the culture to BG, else parsing doubles will fail CultureInfo culture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("bg-BG"); List <CourseInfo> courseInfos = new List <CourseInfo>(); foreach (HtmlNode node in nodes) { // Each tr has 6 tds inside in the following order: // Subject Teacher Type(elective or not) Taken Grade Credits HtmlNodeCollection children = node.SelectNodes("td"); // If the first cell contains the following magic word, the row is a header, ignore it if (children[0].InnerText.Contains("Предмет")) { continue; } // Make sure to strip away all whitespaces (trim everything) CourseInfo courseInfo = new CourseInfo(); courseInfo.CourseName = children[0].InnerText.Trim(); courseInfo.Teacher = children[1].InnerText.Trim(); courseInfo.IsElective = children[2].InnerText.Trim() != "Задължителни"; // The text in Grade and IsTaken is put inside a span unlike all the other cells, so find the first span child courseInfo.IsTaken = children[3].SelectSingleNode("span").InnerText.Trim() == "да"; courseInfo.Grade = Double.Parse(children[4].SelectSingleNode("span").InnerText.Trim().Substring(0, 1)); courseInfo.Credits = Double.Parse(children[5].InnerText.Trim()); courseInfos.Add(courseInfo); } // Set the culture back to whatever it was Thread.CurrentThread.CurrentCulture = culture; return(courseInfos); } catch (Exception e) { // In case something failed, throw a new exception throw new WebException("Can't load data from SUSI", e); } }
/// <summary> /// Gets a collection of <see cref="CourseInfo"/> that shows all courses that the student has passed successfully. /// </summary> public IEnumerable <CourseInfo> GetCourses(CoursesTakenType coursesType) { if (this.Cookies.Count == 0) { throw new InvalidOperationException("You must login prior to getting info from SUSI"); } #if !DEBUG try { #endif // Get the exam page and parse it string examPage = this.GetExamPage(coursesType); HtmlDocument document = new HtmlDocument(); document.LoadHtml(examPage); // Use a magical xpath to get all rows of the courses table, there may be header rows though string xpath = @"/html/body/form/table/tr/td/table[@width=""100%""]/tr/td/table/tr[not(@class)]"; var nodes = document.DocumentNode.SelectNodes(xpath); // Set the culture to BG, else parsing doubles will fail CultureInfo culture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("bg-BG"); List <CourseInfo> courseInfos = new List <CourseInfo>(); foreach (HtmlNode node in nodes) { // Each tr has 6 tds inside in the following order: // Subject Teacher Type(elective or not) Taken Grade Credits HtmlNodeCollection children = node.SelectNodes("td"); // If the first cell contains the following magic word, the row is a header, ignore it if (children[0].InnerText.Contains("Предмет")) { continue; } CourseInfo courseInfo = ExtractCourseInfo(children); courseInfos.Add(courseInfo); } // Set the culture back to whatever it was Thread.CurrentThread.CurrentCulture = culture; return(courseInfos); #if !DEBUG } catch (Exception e) { // In case something failed, throw a new exception throw new WebException("Can't load data from SUSI", e); } #endif }
private static CourseInfo ExtractCourseInfo(HtmlNodeCollection children) { // Make sure to strip away all whitespaces (trim everything) CourseInfo courseInfo = new CourseInfo(); courseInfo.CourseName = children[0].InnerText.Trim(); courseInfo.Teacher = children[1].InnerText.Trim(); courseInfo.IsElective = children[2].InnerText.Trim() != "Задължителни"; // The text in Grade and IsTaken is put inside a span unlike all the other cells, so find the first span child courseInfo.IsTaken = children[3].SelectSingleNode("span").InnerText.Trim() == "да"; // If the grade is empty, set it to 0 (exam may have not yet passed) string gradeAsText = children[4].SelectSingleNode("span").InnerText.Trim(); if (gradeAsText.Length != 0) { courseInfo.Grade = Double.Parse(gradeAsText.Substring(0, 1)); } else { courseInfo.Grade = 0; } courseInfo.Credits = Double.Parse(children[5].InnerText.Trim()); return courseInfo; }
/// <summary> /// Gets a collection of <see cref="CourseInfo"/> that shows all courses that the student has passed successfully. /// </summary> public IEnumerable<CourseInfo> GetCourses() { if (this.Cookies.Count == 0) { throw new InvalidOperationException("You must login prior to getting info from SUSI"); } try { // Get the exam page and parse it string examPage = this.GetExamPage(); HtmlDocument document = new HtmlDocument(); document.LoadHtml(examPage); // Use a magical xpath to get all rows of the courses table, there may be header rows though string xpath = @"/html/body/form/table/tr/td/table[@width=""100%""]/tr/td/table/tr[not(@class)]"; var nodes = document.DocumentNode.SelectNodes(xpath); // Set the culture to BG, else parsing doubles will fail CultureInfo culture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("bg-BG"); List<CourseInfo> courseInfos = new List<CourseInfo>(); foreach (HtmlNode node in nodes) { // Each tr has 6 tds inside in the following order: // Subject Teacher Type(elective or not) Taken Grade Credits HtmlNodeCollection children = node.SelectNodes("td"); // If the first cell contains the following magic word, the row is a header, ignore it if (children[0].InnerText.Contains("Предмет")) continue; // Make sure to strip away all whitespaces (trim everything) CourseInfo courseInfo = new CourseInfo(); courseInfo.CourseName = children[0].InnerText.Trim(); courseInfo.Teacher = children[1].InnerText.Trim(); courseInfo.IsElective = children[2].InnerText.Trim() != "Задължителни"; // The text in Grade and IsTaken is put inside a span unlike all the other cells, so find the first span child courseInfo.IsTaken = children[3].SelectSingleNode("span").InnerText.Trim() == "да"; courseInfo.Grade = Double.Parse(children[4].SelectSingleNode("span").InnerText.Trim().Substring(0, 1)); courseInfo.Credits = Double.Parse(children[5].InnerText.Trim()); courseInfos.Add(courseInfo); } // Set the culture back to whatever it was Thread.CurrentThread.CurrentCulture = culture; return courseInfos; } catch (Exception e) { // In case something failed, throw a new exception throw new WebException("Can't load data from SUSI", e); } }