'''
Created on Dec 5, 2018
@author: QiZhao
'''
import re
import requests
from bs4 import BeautifulSoup
from requests.exceptions import ConnectionError, ReadTimeout
from snnusdk.exceptions import BuildingNotFoundError, RoomNotFoundError
dic = {
'崇鋈楼': '0101',
'积学堂': '0102',
'学院教室': '0103',
'雁塔教学八楼': '0104',
'雁塔教学九楼': '0105',
'雁塔教学六楼': '0106',
'雁塔教学四楼': '0107',
'雁塔教学五楼': '0108',
'雁塔教学一楼': '0109',
'雁塔体育场地': '0110',
'雁塔田家炳楼': '0111',
'雁塔语音': '0112',
'逸夫楼': '0113',
'教学七楼': '0114',
'长安体育场地': '0201',
'长安文津楼': '0202',
'长安文渊楼': '0203',
'长安语音': '0204',
'六艺楼': '0205',
'学院教室': '0206'
}
host = 'http://kb.snnu.edu.cn/room/index/'
re_p = re.compile('<P>([^<]*?)</p>')
week_key = ['', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
jieshu = [
'9-10节',
'1-2节',
'3-4节',
'5-6节',
'7-8节',
]
[文档]class Room:
"""陕师大教室状态查询
:param int week: 周次
:param str building: 教学楼
:raise: :class:`snnusdk.exceptions.BuildingNotFoundError`
:raise: :class:`snnusdk.exceptions.RoomNotFoundError`
>>> room = Room(week=14, building='雁塔教学八楼')
"""
def __init__(self, week, building):
self.week = week
self.building = building
self.soup = self._get_Soup()
self.Rooms = self._get_Rooms()
def _get_Soup(self):
"""依据构造参数,获取BeautifulSoup对象对象
:raise: :class:`snnusdk.exceptions.BuildingNotFoundError`
:raise: :class:`requests.exceptions.ConnectionError`
:rtype: bs4.BeautifulSoup对象
:return: 依据构造参数获得的BeautifulSoup对象
"""
try:
url = '{}?jxz={}&lh={}'.format(host, self.week, dic[self.building])
r = requests.get(url, timeout=10)
soup = BeautifulSoup(r.text, 'lxml')
# print(type(soup))
except KeyError:
raise BuildingNotFoundError('不存在该教学楼!')
except ReadTimeout:
raise ConnectionError('网络连接失败')
return soup
def _get_Rooms(self):
"""
:rtype: list of str
:retuen: 本教学楼内的所有教室名称
>>> room._getRooms()
['8101', '8102', ...]
"""
ret = []
trs = self.soup.find(name='tbody').find_all(name='tr')
for tr in trs:
tds = tr.find_all(name='td')
for td in tds:
if not td.has_attr('align'):
ret.append(td.find(name='a')['title'])
break
return ret
def _get_one_room(self, tr):
"""依据选中的tr标签,获得tr标签所对应的教室一周内的状态
:param bs4.element.Tag tr:
:rtype: dict
:return: 参照例子
>>> room._get_one_room(tr)
{
'id': '8104',
'教室类型': '多媒体教室',
'上课座位': '60',
'星期一':
[
{
'状态': '排课',
'info':
{
'科目': '高等数学(一)-3',
'教师': '吴洪博',
'班级':'数学与信息科学学院 恒元物理实验班1701',
'时间': '1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18 周1 1-2节',
'地点': '雁塔教学八楼 8104'
}
'节数':'1-2节'
},
...
]
...
}
"""
tds = tr.find_all(name='td')
dic = {}
flag = 0
oneday = []
for td in tds:
if td.has_attr('align'):
flag += 1
one_class = self._get_one_class(td)
one_class['节数'] = jieshu[int(flag) % 5]
oneday.append(one_class)
else: # 教室整体信息
dic['id'] = td.find(name='a')['title']
ls = re.findall('(\sbody=\[|>\s)([^:]*?):([^\s]*?)\s',
td['title'])
for tup in ls:
dic[tup[1]] = tup[2]
if int(flag) % 5 == 0 and flag != 0:
dic[week_key[int(flag / 5)]] = oneday
oneday = []
return dic
def _get_one_class(self, td):
"""依据选中的td标签,获得td标签所对应的某教室某节课的状态
:param bs4.element.Tag td:
:rtype: dict
:return: 参照例子
>>> room._get_one_class(td)
{
'状态': '排课',
'info':
{
'科目': '高等数学(一)-3',
'教师': '吴洪博',
'班级':'数学与信息科学学院 恒元物理实验班1701',
'时间': '1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18 周1 1-2节',
'地点': '雁塔教学八楼 8104'
}
'节数':'1-2节'
}
"""
one_class = {}
div = td.find(name='div')
status = str(div['class'])[2:-2]
one_class['状态'] = status
info_list = re_p.findall(div['onclick']) # list
temp_keys = [item.split(':')[0] for item in info_list]
temp_values = [item.split(':')[1] for item in info_list]
info_dic = dict(zip(temp_keys, temp_values))
one_class['info'] = info_dic
return one_class
[文档] def query_all(self):
"""该教学楼该周所有教室的状态
:rtype: list of dict
:return: 参见例子
>>> room.query_all()
[
{
'id': '8101',
'教室类型': '多媒体教室',
'上课座位': '60',
'星期一': [
{
'状态': '排课',
'节数':'1-2节'
'info':
{
'科目': '数学分析(一)',
'教师': '曹小红',
...
}
},
...
]
},
..,
]
"""
trs = self.soup.find(name='tbody').find_all(name='tr')
ret = []
for tr in trs:
ret.append(self._get_one_room(tr))
return ret
[文档] def get_all_rooms(self):
"""教学楼内的所有教室名称
:rtype: list of str
:return: 本教学楼内的所有教室名称
>>> room.get_all_rooms()
['8101', '8102', ...]
"""
return self.Rooms
[文档] def query_one_room(self, room):
"""
查询该教学楼某一教室该周的所有状态
:param str room: 教室号 8014
:raise: :class:`snnusdk.exceptions.RoomNotFoundError`
:rtype: dic
:return: 参照例子
>>> room.query_one_room(room='8014')
{
'id': '8104',
'教室类型': '多媒体教室',
'上课座位': '60',
'星期一':
[
{
'状态': '排课',
'info':
{
'科目': '高等数学(一)-3',
'教师': '吴洪博',
'班级':'数学与信息科学学院 恒元物理实验班1701',
'时间': '1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18 周1 1-2节',
'地点': '雁塔教学八楼 8104'
}
'节数':'1-2节'
},
...
]
...
}
"""
trs = self.soup.find(name='tbody').find_all(name='tr')
if room not in self.Rooms:
raise RoomNotFoundError('不存在该教室')
tr = trs[self.Rooms.index(room)]
# print(type(tr))
return self._get_one_room(tr)
if __name__ == '__main__':
a = Room(12, '雁塔教学八楼')
print(a.query_one_room('8104'))
# print(a.QueryAll())