听风起的乐天派 发表于 2022-8-17 19:42

[python]nonebot2插件---正方课表推送

# 基本思路

- 课表几乎不会变动,一次爬取可以用一学期
- 教务系统爬下来的课表直接就是json格式,容易处理
- 平时看课表还得出去专门开个软件,远没有在QQ里搞个机器人方便
- 恰好有这方面的知识

# 效果展示

# 代码简析

### 创建全局变量,方便别人直接使用

``` python
global furl
global key
#配置文件的地址
furl="/root/bot/lolbot/lolbot/src/plugins/nonebot_plugin_kebiao/qqinfo.json"
#和风天气的个人开发者key
key="4e7fe30df877*******************"
```

### 课表信息很多,只取需要的一小部分
``` python
#初步处理课表
def get_kb(fileurl):
    original_content=open(fileurl,"r",encoding='UTF-8')
    original_content=json.load(original_content)
    sjklist=original_content["sjkList"]
    sjk=[]
    for i in sjklist:
      sjk.append(,i["kcmc"]])
    kblist=original_content["kbList"]
    kb=[]
    for i in kblist:
      kb.append(,i["xqj"],i["xqjmc"],i["jc"],i["kcmc"],i["cdmc"],i["xm"]])
    kkb=[]
    for i in kb:
      kkb.append(i)
    for i in sjk:
      kkb.append(i)
    return kkb
    #处理后单个课程信息:['1-6周', '6', '星期六', '1-2节', '电力系统分析', '莲32号教学楼501', '邵锐']
```

### 处理的周数是1-11周的格式,有的还有单双周,主要对周数进行处理,存到列表里,方便判断周数

``` python
#再次处理课表
def handleweeknum(kb):
    afterhand=[]
    for i in kb:
      weeklist=[]
      a=i.split(",")
      k=0
      #单双周处理
      for j in a:
            if "(单)" in j:
                j=j.replace("(单)","")
                k=1
            if "(双)" in j:
                j=j.replace("(双)","")
                k=2
            j=j[:-1]
            if "-" in j:
                b=j.split("-")
                for m in range(int(b),int(b)+1):
                  if k==0:
                        weeklist.append(m)
                  if k==1:
                        if m%2==1:
                            weeklist.append(m)
                  if k==2:
                        if m%2==0:
                            weeklist.append(m)
            else:
                weeklist.append(int(j))
      after=[]
      after.append(weeklist)
      for n in i:
            after.append(n)
      afterhand.append(after)
    return afterhand
周数处理后单课信息:[, '6', '星期六', '1-2节', '电力 系统分析', '莲32号教学楼501', '邵锐']
```

### 有现成的获取某一天是今年的第几周的周几的库,直接拿来用
算出开学日是第几周,然后让现在是第几周,相减可以得到开学了几周
``` python
#获取今天周数和是周几
def gettime_today(startweeknum):
    tdweeknum=datetime.datetime.now().isocalendar()
    nowweeknum=tdweeknum-startweeknum+1
    weekdaynum=datetime.datetime.today().weekday()+1
    return nowweeknum,weekdaynum
#获取明天周数和是周几
#写的有点臃肿了,但是就这样吧
def gettime_tom(startweeknum):
    tomweeknum=(datetime.datetime.now()+datetime.timedelta(days=1)).isocalendar()
    tomweeknum=tomweeknum-startweeknum+1
    tomweekdaynum=(datetime.datetime.today()+datetime.timedelta(days=1)).weekday()+1
    return tomweeknum,tomweekdaynum
```

### 对课表的美化,加入了今日明日的天气直接嵌入课表中,用emoji表示
``` python
#根据城市信息返回对应的emoji
def getwea_toady_and_tom(city):
    weapi="https://devapi.qweather.com/v7/weather/3d?"
    idapi="https://geoapi.qweather.com/v2/city/lookup?"
    city=ast.literal_eval(requests.get(idapi+"key="+key+"&"+"location="+city).text)["location"]["id"]
    wea=ast.literal_eval(requests.get(weapi+"key="+key+"&"+"location="+city).text)
    todaywea=wea["daily"]["textDay"]
    tomwea=wea["daily"]["textDay"]
    weathertab={
      "雨":"🌧",
      "雪":"❄",
      "晴":"☀",
      "云":"☁",
      "阴":"⛅"
    }
    todw="🌟"
    tomw="🌟"
    for i in weathertab:
      if i in todaywea:
            todw=weathertab
      if i in tomwea:
            tomw=weathertab
    return todw,tomw
```

**核心所在,处理课表信息在QQ中的格式**
~~但是写的有点凌乱和稀烂~~
``` python
#处理发出去的课表信息
def judge(weeknum,weekday,handkb,citywea="🌟"):
    daymap={1:"⏳星期一⏳",2:"⏳星期二⏳",3:"⏳星期三⏳",4:"⏳星期四⏳",5:"⏳星期五⏳",6:"⏳星期六⏳",7:"⏳星期日⏳"}
    if weekday in daymap:
      msg=daymap+"\n-------------------------------------\n"
    for i in handkb:
      timetab={
            "1":"🕗",
            "2":"🕘",
            "3":"🕙",
            "4":"🕚",
            "5":"🕝",
            "6":"🕞",
            "7":"🕟",
            "8":"🕠",
            "9":"🕢",
            "10":"🕣",
            "11":"🕘",
            "12":"🕤",
      }
      #根据第几节返回对应的emoji
      try:
            if i in timetab:
                kbtime=timetab]
            else:
                kbtime="🕘"
            if weeknum in i and weekday==int(i):
                msg=msg+kbtime+i+citywea+i+"\n\n"+"🏠"+i+"🏠\n🚶"+i+"🚶\n-------------------------------------\n"
      except:
            if weeknum in i:
                if msg[-1] !=":":
                  msg=msg+"🕹实践课:"
                if msg[-1] ==":":
                  msg=msg+i+" "   
    return msg
```
### 接下来是Nonebot2的一些处理,不再进行说明
``` python
#各个监听器
kebiao = on_command("kebiao", aliases={"今日课表","课表","课程表"}, priority=5)
tomkebiao = on_command("tomkebiao", aliases={"明日课表"}, priority=5)
weekkebiao = on_command("weekkebiao", aliases={"本周课表"}, priority=5)
nextweekkebiao = on_command("nextweekkebiao", aliases={"下周课表"}, priority=5)
kebiaohelp = on_command("kebiaohelp", aliases={"课表帮助"}, priority=5)

#课表帮助
@kebiaohelp.handle()
async def send_kebiaohelp(matcher: Matcher, args: Message = CommandArg()):
    msg="课表,今日课表\n明日课表\n本周课表\n下周课表"
    await kebiaohelp.finish(msg)

#今日课表
@kebiao.handle()
async def send_today_kb(event: Event,matcher: Matcher, args: Message = CommandArg()):
    try:
      qqinfo=str(event)
      qq=re.split(' from |@| ',qqinfo)
      qqtoinfo=json.load(open(furl,"r",encoding="utf-8"))
      y=qqtoinfo["starttime"]
      m=qqtoinfo["starttime"]
      d=qqtoinfo["starttime"]
      try:
            city=qqtoinfo["city"]
      except:
            city="☀"
      todaywea=getwea_toady_and_tom(city=city)
      a=judge(gettime_today(startweeknum(y,m,d)),gettime_today(startweeknum(y,m,d)),handleweeknum(get_kb(qqtoinfo["kbinfo"])),todaywea)
      msg="今日课表📝📝📝:\n\n"+a
      await kebiao.finish(msg)
    except:
      print("未绑定课表信息")
```
# 如何使用
### 前置条件
- 假定你有一定的基础
- 假定你会搭建nonebot2机器人,不会可以百度到官方文档看教程
- 假定你会往机器人里扔插件
- 假定你会一点点抓包

### 简易抓课表
1. 进入你的正方教务课表信息页
2. 按F12进入开发者页面

3. 再点一次查询抓一下课表
4. 找到课表信息,直接复制

5. 新建一个kebiao.json文件, 把刚刚复制的课表信息粘贴进去
6. 配置好在py文件的最开始的两个全局变量,和风天气API可以免费申请
7. 在qqinfo.json文件里填入你的相关信息,支持多人
8. 扔进去插件运行机器人
9. 配置结束,可以食用

# 附件 - 源代码示例

听风起的乐天派 发表于 2022-11-28 01:12

Panda269 发表于 2022-11-26 22:12
未绑定课表信息怎么解决
如何去绑定呢

如果能正常使用的话,这个报错可以不用管,是我代码的问题,如果是没有绑定无法使用,在附件里的那个json配置文件里修改QQ号,课表json文件路径等信息,然后用对应的QQ号才能触发.

听风起的乐天派 发表于 2022-8-30 16:30

CainY 发表于 2022-8-30 14:53
楼主你的响应器是on_command啊,为什么直接发普通消息就能得到回复?我的要在前面加/才行

我命令前缀列表里加了个个空字符,也就是什么都不加也作为命令响应

lsy832 发表于 2022-8-17 22:56

思路不错谢谢分享

feiyu361 发表于 2022-8-18 09:06

厉害了,我的哥

余烬。 发表于 2022-8-22 01:17

感谢分享,大佬可以出一个更详细一点的步骤吗,小白不太会用

Re12 发表于 2022-8-29 09:32

感谢分享

nanqian 发表于 2022-8-29 20:34

真好,返回的是json。我们学校的直接返回一张图片

CainY 发表于 2022-8-30 14:53

楼主你的响应器是on_command啊,为什么直接发普通消息就能得到回复?我的要在前面加/才行

virsnow 发表于 2022-10-6 22:32

6666666666666666楼主威武

li083m 发表于 2022-11-13 11:34

能出个视频吗
页: [1] 2
查看完整版本: [python]nonebot2插件---正方课表推送