def check_selected_course(s): # html_object # args: # keywords: 任意长,检索关键字参数 # school: 开课院系列表 # request_left: Boolean, 只接受有余量的课程 = True s.update_origin() if s.is_ok(): raw_html = (s.get(elect_url + s.student_id).content.decode()) else: return None ele_htm = etree.HTML(raw_html) is_kxk = ele_htm.xpath('//*[@id="iskxk"]/@value') if len(is_kxk) == 0 or is_kxk[0] == '0': raise RequestError( "Failed to communicate with elect system. Check if the service is available.") params = { } for par in hidden_params: if par == 'jg_id': fix_par = 'jg_id_1' else: fix_par = par try: value = ele_htm.xpath('//*[@id="%s"]/@value' % fix_par)[0] params[par] = value # print("Parsed param %s as %s" % (par, value)) except IndexError: raise ParseError("Failed to parse website element %s." % fix_par) resp = s.post(check_url + s.student_id, params) if resp.status_code == 200: resource = json.loads(resp.content.decode()) data_list = [] # 如果有数据 try: for item in resource: data_list.append(ElectCourse(**item)) except ParseError: # 抛异常结束 raise ParseError("Failed to check selected course data.") else: return data_list raise RequestError("Failed to query elect system.")
def get_course_list(s, year, term): if s.is_ok(): if term == 1: xqm = '3' elif term == 2: xqm = '12' elif term == 3: xqm = '16' else: raise TypeError("Invalid term code.") params = {'xnm': str(year), 'xqm': xqm} resp = s.post(course_table_url, params) if resp.status_code == 200: resource = json.loads(resp.content.decode()) if 'kbList' in resource: data_list = [] # 如果有数据 success = 0 fail = 0 for item in resource['kbList']: try: data_list.append(PersonalCourse(**item)) except ParseError: # 抛异常结束 fail += 1 else: success += 1 logging.info("Course Parsing complete. %d success, %d fail." % (success, fail)) return data_list raise RequestError("Failed to request course schedule.")
def get_exam_list(s, year, term, course_name="", exam_location="", course_date="", max_limit=15): if term == 1: term_code = '3' elif term == 2: term_code = '12' elif term == 3: term_code = '16' else: raise TypeError("Invalid term code.") params = { 'xnm': str(year), 'xqm': term_code, 'ksmcdmb_id': course_name, 'kch': course_name, 'kc': exam_location, 'ksrq': course_date, '_search': 'false', 'nd': s.get_session_id(), 'queryModel.showCount': str(max_limit), 'queryModel.currentPage': '1', 'queryModel.sortName': '', 'queryModel.sortOrder': 'asc', 'time': '0' } resp = s.post(exam_check_url + s.student_id, params) if resp.status_code == 200: resource = json.loads(resp.content.decode()) if 'items' in resource: data_list = [] # 如果有数据 try: for item in resource['items']: data_list.append(PersonalExam(**item)) except ParseError: # 抛异常结束 raise ParseError("Failed to parse exam dictionary.") else: return data_list raise RequestError("Failed to request exam arrangement.")
def get_score_list(s, year, term, max_limit=30): if term == 1: term_code = '3' elif term == 2: term_code = '12' elif term == 3: term_code = '16' else: raise TypeError("Invalid term code.") params = { 'xnm': str(year), 'xqm': term_code, '_search': 'false', 'nd': s.get_session_id(), 'queryModel.showCount': str(max_limit), 'queryModel.currentPage': '1', 'queryModel.sortName': '', 'queryModel.sortOrder': 'asc', 'time': '0' } resp = s.post(score_check_url, params) if resp.status_code == 200: resource = json.loads(resp.content.decode()) if 'items' in resource: data_list = [] # 如果有数据 try: for item in resource['items']: data_list.append(PersonalScore(**item)) except ParseError: # 抛异常结束 raise ParseError("Failed to parse score dictionary.") else: return data_list raise RequestError("Failed to request score data.")
def conditional_query(s, year, term, name=None, weekday=None, teacher=None, max_limit=30): if term == 1: term_code = '3' elif term == 2: term_code = '12' elif term == 3: term_code = '16' else: raise TypeError("Invalid term code.") if weekday != None: if type(weekday) != int: raise TypeError("Weekday must be integer.") if weekday < 1 or weekday > 7: raise TypeError("Weekday must lies in range(1, 8) but not %d." % weekday) resp = s.get(index_url + s.student_id) if resp.status_code == 200: resource = resp.content.decode() if not 'data-func_widget_guid="' in resource: raise ParseError("Failed to get functional widget GUID.") func_widget_guid = resource.split('data-func_widget_guid="')[1].split( '"')[0] params = { 'xnm': str(year), 'xqm': term_code, '_search': 'false', 'nd': s.get_session_id(), 'queryModel.showCount': max_limit, 'queryModel.currentPage': '1', 'queryModel.sortName': '', 'queryModel.sortOrder': 'asc' } if name != None: # Must quote params before post them. params.update({'kch_id': quote(str(name))}) if teacher != None: params.update({'js': quote(str(teacher))}) if weekday != None: params.update({'xqj': str(weekday)}) post_resp = s.post( post_to_url.replace('FUNCWIDGETGUID', func_widget_guid) + s.student_id, params) # print("Going to %s." % (post_to_url.replace( # 'FUNCWIDGETGUID', func_widget_guid) + s.student_id)) # print(params) if post_resp.status_code == 200: resource = json.loads(post_resp.content.decode()) else: raise RequestError("Failed to post parameters. Status Code: %d" % post_resp.status_code) if 'items' in resource: data_list = [] # 如果有数据 success = 0 fail = 0 for item in resource['items']: try: data_list.append(ElectCourse(**item)) except ParseError: # 抛异常结束 fail += 1 else: success += 1 logging.info("Course Parsing complete. %d success, %d fail." % (success, fail)) return data_list raise RequestError("Failed to request course schedule.")
def query_course(s, *keywords, **args): # html_object # args: # keywords: 任意长,检索关键字参数 # school: 开课院系列表 # request_left: Boolean, 只接受有余量的课程 = True s.update_origin() if s.is_ok(): raw_html = (s.get(query_url + s.student_id).content.decode()) else: return None ele_htm = etree.HTML(raw_html) is_kxk = ele_htm.xpath('//*[@id="iskxk"]/@value') if len(is_kxk) == 0 or is_kxk[0] == '0': raise RequestError( "Failed to communicate with elect system. Check if the service is available." ) params = { 'rwlx': '1', 'xkly': '0', 'bklx_id': '0', 'sfkknj': '0', 'sfkkzy': '0', 'sfznkx': '0', 'zdkxms': '0', 'kkbkdj': '0', 'sfkxq': '1', 'sfkcfx': '0', 'kkbk': '0', 'kklxdm': '01', 'sfkgbcx': '1', 'sfrxtgkcxd': '0', 'tykczgxdcs': '0', 'rlkz': '0', 'kspage': '1', 'jspage': '10' } for par in hidden_params: # 有一项不一致的情况 if par == 'jg_id': fix_par = 'jg_id_1' else: fix_par = par value = ele_htm.xpath('//*[@id="%s"]/@value' % fix_par) if len(value) != 0: params[par] = value[0] else: raise ParseError("Failed to get control value %s." % fix_par) # print("Parsed param %s as %s" % (par, value)) if 'request_left' in args: if args['request_left']: params['yl_list[0]'] = 1 count = 0 for kw in keywords: if len(kw) == 0: continue params["filter_list[%d]" % count] = str(kw) count += 1 if 'school' in args: if isinstance(args['school'], list): count = 0 for school in args['school']: params["kkbm_id_list[%d]" % count] = school count += 1 else: params["kkbm_id_list[0]"] = str(args['school']) # print(post_url + s.student_id) # s.print_headers() resp = s.post(post_url + s.student_id, params) if resp.status_code == 200: resource = json.loads(resp.content.decode()) if 'tmpList' in resource: data_list = [] # 如果有数据 try: for item in resource['tmpList']: data_list.append(ElectCourse(**item)) except ParseError: # 抛异常结束 raise ParseError("Failed to parse course data.") else: raise RequestError("Failed to query course library.") for course in data_list: course_detail = query_course_detail(s, course) if type(course_detail) == CourseDetail: try: course.sksj = course_detail.sksj course.jxdd = course_detail.jxdd except: logging.warn( "Failed to obtain ['sksj', 'jxdd'] detail of <ElectCourse>: %s. Use carefully." % course['kcmc']) else: logging.warn( "Failed to obtain ['sksj', 'jxdd'] detail of <ElectCourse>: %s. Use carefully." % course['kcmc']) return data_list
def query_course_detail(s, elect_course_type): if type(elect_course_type) != ElectCourse: return None s.update_origin() if s.is_ok(): raw_html = (s.get(query_url + s.student_id).content.decode()) else: return None ele_htm = etree.HTML(raw_html) params = { 'kch_id': str(elect_course_type.kch_id), 'rwlx': '1', 'xkly': '0', 'bklx_id': '0', 'sfkknj': '0', 'sfkkzy': '0', 'sfznkx': '0', 'zdkxms': '0', 'kkbkdj': '0', 'sfkxq': '1', 'sfkcfx': '0', 'kkbk': '0', 'kklxdm': '01', 'sfkgbcx': '1', 'sfrxtgkcxd': '0', 'tykczgxdcs': '0', 'rlkz': '0', 'kspage': '1', 'jspage': '10' } for par in hidden_params: # 有一项不一致的情况 if par == 'jg_id': fix_par = 'jg_id_1' else: fix_par = par value = ele_htm.xpath('//*[@id="%s"]/@value' % fix_par)[0] params[par] = value # print("Parsed param %s as %s" % (par, value)) # print(post_url + s.student_id) # s.print_headers() resp = s.post(detail_url + s.student_id, params) if resp.status_code == 200: resource = json.loads(resp.content.decode()) # 如果有数据 try: return CourseDetail(**resource[0]) except: # 抛异常结束 raise ParseError("Failed to parse course detail.") raise RequestError("Failed to query course library.")