# 10/17 Discord Bot 開發(四) :::info 時間:2023/10/17 22:20~23:30 地點:線上會議(Discord) 參與:xiaojie4082 ![](https://hackmd.io/_uploads/BJhqrEhZp.png) ::: ## 本次討論事項 - 講解選課相關指令 - ~~公車資訊~~ (延至下次討論) - 機器人短時間內重複發布2000則以上訊息事件 ## 講解選課相關指令 ### /搜尋課程 [老師/課程] [關鍵字] ```python! def search(course_teacher:str,keyword: str): try: if(course_teacher == "課程"): # 課程名稱 url = "https://alcat.pu.edu.tw/2011courseAbstract/main.php?" + "ls_yearsem=1121&selectno=&weekday=&section=&cus_select=&classattri=1&subjname=" + keyword + "&teaname=&opunit=&opclass=&lessonlang=&search=%E6%90%9C%E5%B0%8B&click_ok=Y" else: # 教師姓名 url = "https://alcat.pu.edu.tw/2011courseAbstract/main.php?" + "ls_yearsem=1121&selectno=&weekday=&section=&cus_select=&classattri=1&subjname=&teaname=" + keyword + "&opunit=&opclass=&lessonlang=&search=%E6%90%9C%E5%B0%8B&click_ok=Y" response = requests.get(url) if response.status_code == 200: soup = BeautifulSoup(response.text, "html.parser") table = soup.find('table', class_='table_info') rows = table.find_all('tr') course_data = [] for row in rows: cells = row.find_all('td') if len(cells) >= 8: course_code = cells[0].text.strip() class_name = cells[1].text.strip() course_type = cells[2].text.strip() course_name = cells[3].text.strip() credit = cells[5].text.strip() teacher = cells[6].text.strip() schedule = cells[7].text.strip() course_info = { '選課代號': course_code, '上課班級': class_name, '修別': course_type, '科目名稱': course_name, '學分數': credit, '授課老師': teacher, '上課時間地點': schedule } course_data.append(course_info) return course_data else: course_info = { '選課代號': "", '上課班級': "", '修別': "", '科目名稱': "", '學分數': "", '授課老師': "", '上課時間地點': "" } return course_data except Exception as e: print(e) course_info = { '選課代號': "", '上課班級': "", '修別': "", '科目名稱': "", '學分數': "", '授課老師': "", '上課時間地點': "" } return course_data ``` ### /課程綱要 [課程代號] ```python! def syllabus(selectno: str): try: url = 'https://alcat.pu.edu.tw/2011courseAbstract/main.php?ls_yearsem=1121&selectno=' + selectno + '&weekday=&section=&cus_select=&classattri=1&subjname=&teaname=&opunit=&opclass=&lessonlang=&search=%E6%90%9C%E5%B0%8B&click_ok=Y' response = requests.get(url) if response.status_code == 200: soup = BeautifulSoup(response.text, "html.parser") all_a_elements = soup.find_all('a', href=True) for a_element in all_a_elements: href = a_element['href'] if "list_abstract_content_100.php?pkey=" in href: new_href = href.replace("..", "https://alcat.pu.edu.tw/") response = requests.get(new_href) soup = BeautifulSoup(response.text, 'html.parser') # 課程名稱 course_name_element = soup.find(text="課程名稱") if course_name_element: course_name = course_name_element.find_next('td').get_text(strip=True) else: course_name = "未找到課程名稱" # 授課教師 instructor_element = soup.find(text="授課教師") if instructor_element: instructor = instructor_element.find_next('td').get_text(strip=True) else: instructor = "未找到授課教師" # 上課時段 class_time_element = soup.find(text="上課時段") if class_time_element: class_time = class_time_element.find_next('td').get_text(strip=True) else: class_time = "未找到上課時段" # 中文版課程簡介 course_description = soup.find('th', string='中文版課程簡介Course Description(Chinese Version)').find_next('td').text.strip() if len(course_description) > 500: course_description = course_description[:500] + "\n\n...略" # 評分方式及比重 grading_content = soup.find('th', string="評分方式及比重Grading Methods and Ratio ").find_next('td').text.strip() # 提取各科授課進度與內容Course Syllabus and Teaching Content syllabus_and_content = soup.find('th', string='各科授課進度與內容Course Syllabus and Teaching Content').find_next('td').text.strip() syllabus_and_content = syllabus_and_content.replace("週次", "").replace("Week(Time)", "").replace("主題內容/章節/或活動", "").replace("Topic/Chapter/Classroom Activities", "").replace("備註", "").replace("Remark(s)", "") lines = syllabus_and_content.strip().split('\n\n') weekly_contents = [line.strip() for line in lines if line.strip()] syllabus_and_content = "" for week, content in enumerate(weekly_contents, start=1): syllabus_and_content = syllabus_and_content + content + "\n\n" # PUHub 課程評論 url = "https://puhub.org/api/course_evaluation.php?course=" + course_name + "&teacher=" + instructor response = requests.get(url) datas = response.json() evaluation = "" temp = 0 for data in datas: temp = temp + 1 evaluation = evaluation + "```" + data[6] + "``` " if temp == 0: evaluation = "```目前沒有任何評論```" # AI 分析 # info = "## 課程名稱:" + course_name + "\t授課教師:" + instructor + "\t上課時段:" + class_time + "\n### 課程簡介:\n```" + course_description + "```\n### 評分方式:\n```" + grading_content + "```" # messages = [{'role': 'user','content': "我是個大學生,正在尋找適合自己的課程,請透過下面的資訊向我提供選課分析。(200字以內)\n" + info + syllabus_and_content}] # gpt_35_api_stream(messages) # content = messages[1]['content'] content = "" return course_name, instructor, class_time, course_description, grading_content, evaluation, content, new_href, url except Exception as e: print(e) return "", "", "", "", "", "", "", "", "" ``` ### /課程餘額 [課程代號] ```python! def person(selectno: int): try: url = 'https://alcat.pu.edu.tw/choice/q_person.html' data = { 'selectno': selectno } response = requests.post(url, data=data) if response.status_code == 200: soup = BeautifulSoup(response.text, "html.parser") course_name = soup.find('h2', string=lambda text: text and '科目名稱:' in text).text course_name = course_name.replace('科目名稱:', '') rows = soup.find_all('tr') limit = None enrollment = None remaining = None for row in rows: cells = row.find_all('td') if len(cells) == 2: key = cells[0].text.strip() value = cells[1].text.strip() if key == '人數上限': limit = value elif key == '修課人數': enrollment = value # elif key == '人數餘額': # remaining = value remaining = int(limit) - int(enrollment) return course_name,enrollment,remaining else: return "輸入的資料有誤","輸入的資料有誤","輸入的資料有誤" except Exception as e: print(e) return "輸入的資料有誤","輸入的資料有誤","輸入的資料有誤" ``` ## 機器人短時間內重複發布2000則以上訊息事件 - 事件名稱:Discord Bot 持續發送訊息 - 事件時間:2023-10-16 早上 6. ~ 7.30 - 事件緣起:因 API 資料錯誤(缺漏),導致機器人持續發送訊息(陷入無限迴圈直至API資料恢復),造成所有成員困擾。 - 事件經過: 1. 2023-10-16 上午 6 點,成員反應 Discord Bot 持續發送訊息。 2. 管理團隊調查後發現,是 Bot 的 API 資料錯誤,導致 Bot 陷入無限迴圈,不斷發送訊息。 3. 管理團隊已將頻道暫時關閉,並對 Bot 添加 API 資料偵測,以防止此類事件再次發生。 4. 目前,已對機器人添加例外處理,避免發生相同狀況陷入無限迴圈。 - 事件分析:此次事件的原因是 中央氣象署 的 API 資料錯誤 以及 程式碼缺陷。造成此錯誤的原因可能是: - 程式碼有 bug。 - API 資料有問題。 - 事件後續: - 服務頻道改為選擇制 - 程式碼添加例外處理 ## 下次會議討論事項 - 10/21 Discord Bot 開發(五) - 公車資訊 - 添加按鈕