-학기 시간표 종합- 19.11.29 ~ 19.12.10

crawl_table.py

from bs4 import BeautifulSoup as bs
from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time
from webdriver_manager.chrome import ChromeDriverManager

from Class_Define import Department, Class

class Crwal_Table:
    def __init__(self):
        self.options = webdriver.ChromeOptions()
        # self.options.add_argument('headless')
        self.options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) "
                             "Chrome/61.0.3163.100 Safari/537.36")

        self.browser = None
        self.year = None
        self.semester = None
        self.dept_list = []
        self.semester_trans = {'1' : '1', '2' : '3', '여름' : '2', '겨울' : '4'}
        self.dept_eles = None

    def get_year_obj(self, rq_year):
        year = self.browser.find_element_by_name('ag_ledg_year')
        self.year = Select(year)
        self.year.select_by_value('20' + rq_year)

    def get_semester_obj(self, rq_semester):
        semester = self.browser.find_element_by_name('ag_ledg_sessn')
        self.semester = Select(semester)
        self.semester.select_by_value(self.semester_trans[rq_semester])

    def lecture_home(self, year, semester):
        if self.browser.current_url != "<https://wis.hufs.ac.kr/src08/jsp/lecture/LECTURE2020L.jsp>":
            self.browser.get("<https://wis.hufs.ac.kr/src08/jsp/lecture/LECTURE2020L.jsp>")

        if not self.year:
            self.get_year_obj(year)
            time.sleep(0.3)
            self.get_semester_obj(semester)

        dept_eles = self.browser.find_element_by_name('ag_crs_strct_cd')
        if len(self.dept_list) == 0:
            for i in dept_eles.find_elements_by_tag_name('option'):
                self.dept_list.append(i.text.strip()[6:].split('(')[0].strip())

        self.dept_eles = Select(dept_eles)
        return self.dept_eles

    def make_timetable(self, major, rq_year, rq_semester):

        if major == None:
            return None

        try:
            with open(rq_year + '-' + rq_semester + ' ' + major + '.txt', 'r', encoding="UTF-8") as file:
                class_list = file.readlines()
                depart = Department(major)
                print(depart.name, '데이터 수집 중')
                for i in class_list:
                    i = i.split(" # ")
                    area, year, subject, syllabus, required, online, foreign, team_teaching, prof, credit, class_time, restrict_num, note, stars = i
                    depart.insert_class(Class(area, year, subject, syllabus, required, online, foreign,
                                              team_teaching, prof, credit, class_time, restrict_num, note, stars))
            print("데이터 수집 완료")
            return depart

        except:
            if not self.browser:
                self.browser = webdriver.Chrome(ChromeDriverManager().install(), options=self.options)
            dept_eles = self.lecture_home(rq_year, rq_semester)

            major_index = None
            for i in range(len(self.dept_list)):
                if major.lower() in self.dept_list[i].lower():
                    major_index = i
                    break
            print(self.dept_list[major_index], '데이터 수집 중')

            if major_index == None:
                raise Exception("학과를 정확히 입력해주세요!")

            # major_index = self.dept_list.index(major)
            depart = Department(self.dept_list[major_index])
            dept_eles.select_by_index(major_index)

            time.sleep(0.5)
            html = bs(self.browser.page_source, 'html.parser')

            tbody = html.findAll('tbody')
            trs = tbody[-1].findAll('tr')[1:]

            for i in trs:
                tds = i.findAll('td')
                area = tds[1].get_text().strip()
                year = tds[2].get_text().strip()
                subject = tds[4].get_text().strip().splitlines()
                subject = " / ".join(subject)
                try:
                    syllabus = tds[5].find('a')['href'].split('\\'')
                    ag_1 = syllabus[1]
                    ag_2 = syllabus[3]
                    ag_3 = syllabus[5]
                    ag_4 = syllabus[7]
                    syllabus = "<https://wis.hufs.ac.kr/src08/jsp/lecture/syllabus.jsp?mode=print&ledg_year=>" \\
                               +str(ag_1)+"&ledg_sessn="+str(ag_2)+"&org_sect="+str(ag_3)+"&lssn_cd="+str(ag_4)
                except:
                    syllabus = 'None'

                required = tds[6]
                if required.find('img'):
                    required = 'O'
                else:
                    required = required.get_text()

                online = tds[7]
                if online.find('img'):
                    online = 'O'
                else:
                    online = online.get_text()

                foreign = tds[9]
                if foreign.find('img'):
                    foreign = 'O'
                else:
                    foreign = foreign.get_text()

                team_teaching = tds[10]
                if team_teaching.find('img'):
                    team_teaching = 'O'
                else:
                    team_teaching = team_teaching.get_text()

                prof = tds[11].get_text().strip().split('(')[0].strip()
                credit = tds[12].get_text().strip()
                class_time = tds[14].get_text().strip()
                restrict_num = tds[15].get_text().strip()
                note = tds[16].get_text().strip()

                if len(note) == 0:
                    depart.insert_class(Class(area, year, subject, syllabus, required, online, foreign,
                                              team_teaching, prof, credit, class_time, restrict_num))
                else:
                    depart.insert_class(Class(area, year, subject, syllabus, required, online, foreign,
                                              team_teaching, prof, credit, class_time, restrict_num, note))

            self.all_courses(depart, rq_year, rq_semester)
        print("데이터 수집 완료")
        return depart

    def get_avg_stars(self, dept_obj1, dept_obj2, grade):
        if not self.browser:
            self.browser = webdriver.Chrome(ChromeDriverManager().install(), options=self.options)
        browser = self.browser
        browser.get("<https://everytime.kr/lecture>")
        try:
            print('로그인 시도')
            id = browser.find_element_by_name("userid")
            id_input = input('아이디 입력 : ')
            id.send_keys(id_input)

            pw = browser.find_element_by_name("password")
            pw_input = input('비밀번호 입력 : ')
            pw.send_keys(pw_input)

            login = browser.find_element_by_class_name('submit')
            login.click()
            print('에브리타임 로그인 성공')
        except:
            print('로그인 실패')
            return

        fst_class_list = dept_obj1.classes
        scd_class_list = None
        if dept_obj2 != None:
            scd_class_list = dept_obj2.classes

        def course_insert(class_list):
            for course in class_list:

                if course.year not in grade or len(course.prof) == 0:
                    continue
                else:
                    if (fst_class_list == class_list and '이중' in course.area) \\
                            or (scd_class_list == class_list and '1전공자 전용' in course.note):
                        continue

                while True:
                    try:
                        input_box = browser.find_element_by_name('keyword')
                        submit_btn = browser.find_element_by_class_name('submit')
                        input_box.send_keys(' ')
                        input_box.send_keys(course.subject.split(' / ')[0])
                        browser.execute_script("arguments[0].click();", submit_btn)
                        time.sleep(0.5)
                        if course.prof in browser.page_source:
                            profs= browser.find_element_by_xpath("//*[contains(text(), '" + course.prof + "')]")
                        else:
                            course.stars = '-'
                            browser.back()
                            break
                        browser.execute_script("arguments[0].click();", profs)
                        time.sleep(0.5)
                        stars = browser.find_element_by_class_name('value').text
                        if stars == '0':
                            stars = '-'
                        course.stars = stars
                        browser.back()
                        browser.back()
                        break

                    except:
                        pass
                    try:
                        popup = browser.find_element_by_class_name('close')
                        browser.execute_script("arguments[0].click();", popup)
                    except:
                        continue
        print('강의평 가져오는중...')
        course_insert(fst_class_list)
        print('1전공 완료')
        if scd_class_list:
            course_insert(scd_class_list)
            print('2전공 완료')
        # browser.close()

    def all_courses(self, dept_obj, year, semester):
        with open(year + '-' + semester + ' ' + dept_obj.name + '.txt', 'w', encoding="UTF-8") as file:
            for course in dept_obj.classes:
                file.write(" # ".join(course()) + "\\n")

class_define.py

class Department:
    def __init__(self, name):
        self.name = name
        self.classes = []

    def __str__(self):
        return self.name

    def insert_class(self, class_obj):
        self.classes.append(class_obj)

class Class:
    def __init__(self, area, year, subject, syllabus, required, online, foreign, team_teaching, prof,
                 credit, class_time, restrict_num, note = '-', avg_stars = ' - '):
        self.area = area
        self.year = year
        self.subject = subject
        self.syllabus = syllabus
        self.required = required
        self.online = online
        self.foreign = foreign
        self.team_teaching = team_teaching
        self.prof = prof
        self.credit = credit
        self.class_time = class_time
        self.restrict_num = restrict_num
        self.stars = avg_stars
        self.note = note

    def __str__(self):
        return self.subject

    def __call__(self):
        return (self.area, self.year, self.subject, self.syllabus, self.required, self.online, self.foreign,
                self.team_teaching, self.prof, self.credit, self.class_time, self.restrict_num, self.note, self.stars)

class User:
    def __init__(self, course_evl, grade, first_major, second_major = None):
        self.first_major = first_major
        self.second_major = second_major
        self.grade = grade
        self.courses = []
        self.course_evl = course_evl

class User_Table(User):
    def __init__(self, course_evl, grade, first_major, second_major = None):
        self.credits = 0
        self.longest = 0
        self.time_table = None
        super().__init__(course_evl, grade, first_major, second_major)

    def insert_course(self, course_obj):
        self.courses.append(course_obj)
        class_time = course_obj.class_time.split('(')[0].strip()
        try:
            class_time = int(class_time.split()[-1])
            if class_time > self.longest:
                self.longest = class_time
        except:
            pass
        self.credits += int(course_obj.credit)

    def make_txt(self, fst_obj, sec_obj):
        first_major_obj = fst_obj
        for course in first_major_obj.classes:
            if (self.course_evl and ' - ' in course.stars) or not course.year in self.grade or '이중' in course.area:
                continue
            self.insert_course(course)

        print('1전공 조건 추출 완료')

        if sec_obj:
            second_major_obj = sec_obj
            for course in second_major_obj.classes:
                if (self.course_evl == True and ' - ' in course.stars) or not course.year in self.grade or '1전공자 전용' in course.note:
                    continue
                self.insert_course(course)
            print('2전공 조건 추출 완료')

        self.time_table = {
            'Mon': [[] for i in range(self.longest)],
            'Tue': [[] for i in range(self.longest)],
            'Wed': [[] for i in range(self.longest)],
            'Thu': [[] for i in range(self.longest)],
            'Fri': [[] for i in range(self.longest)],
        }
        return self.credits

    def make_time_dict(self):
        print('시간표 만드는 중입니다.')
        course_list = self.courses
        for i in course_list:
            s = Stack()
            if len(i.class_time) > 3:
                time = i.class_time.split('(')[2].strip().split()
            else:
                continue
            for j in time:
                if not j.isdigit():
                    if not s.isEmpty():
                        s.pop()
                    s.push(j)
                else:
                    subject_information = {'sub': i.subject, 'syllabus': i.syllabus, 'prof': i.prof, 'stars': i.stars, 'credit' :  i.credit}
                    self.time_table[s.peek()][int(j) - 1].append(subject_information)
            while not s.isEmpty:
                s.pop()

        return self.time_table

class Stack:
    def __init__(self):
        self.item = []
        self.size = 0

    def push(self, value):
        self.item.append(value)
        self.size += 1

    def pop(self):
        if self.size != 0:
            self.size -= 1
            return self.item.pop()
        return print("Stack is Empty")

    def peek(self):
        if self.size != 0:
            return self.item[-1]
        return print("Stack is Empty")

    def __len__(self):
        return len(self.item)

    def isEmpty(self):
        return self.__len__() == 0

quick_sort.py

def quick_sort_by_stars(list, p, r):
    if p < r:
        q = partition_by_stars(list, p, r)
        quick_sort_by_stars(list, p, q - 1)
        quick_sort_by_stars(list, q + 1, r)

def partition_by_stars(list, p, r):
    x = list[r].stars
    i = p - 1
    for j in range(p, r):
        if list[j].stars > x:
            i += 1

            list[j], list[i] = list[i], list[j]

    list[i + 1], list[r] = list[r], list[i + 1]

    return i + 1

def quick_sort_by_time(list, p, r):
    if p < r:
        q = partition_by_time(list, p, r)
        quick_sort_by_time(list, p, q - 1)
        quick_sort_by_time(list, q + 1, r)

def partition_by_time(list, p, r):
    refer = {
        '월' : 10,
        '화' : 30,
        '수' : 50,
        '목' : 70,
        '금' : 90,
        'x' : 120
    }
    x = list[r].class_time.split()
    if len(x) > 1:
        x = refer[x[0]] + int(x[1])
    else:
        x = refer['x']
    i = p - 1
    for j in range(p, r):
        value = list[j].class_time.split()
        if len(value) > 1:
            value = refer[value[0]] + int(value[1])
        else:
            value = refer['x']

        if value < x:
            i += 1

            list[j], list[i] = list[i], list[j]

    list[i + 1], list[r] = list[r], list[i + 1]

    return i + 1

html_making.py

from Quick_sort import quick_sort_by_stars, quick_sort_by_time

class HTML:
    def __init__(self):
        self.main_head_html ="""
        <!DOCTYPE html>
        <html lang="ko">
                <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <link rel="stylesheet" href="<https://use.fontawesome.com/releases/v5.5.0/css/all.css>">
                                                <style>
    @import url(<https://fonts.googleapis.com/css?family=Open+Sans:300,400>);
    @font-face { font-family: 'silgothic'; src: url('<https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/silgothic.woff>') format('woff'); font-weight: normal; font-style: normal; }
    @font-face { font-family: 'DungGeunMo'; src: url('<https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/DungGeunMo.woff>') format('woff'); font-weight: normal; font-style: normal; }
    @font-face { font-family: 'KCC-eunyoung'; src: url('<https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/KCC-eunyoung-Regular.woff>') format('woff'); font-weight: normal; font-style: normal; }
    body {
      padding: 10px;
      background: #eee;
      background: linear-gradient(0deg, rgba(0, 0, 200, 0.2), rgba(0, 0, 200, 0));
      background-attachment: fixed;	
	background-size: cover;
    }
    .background {
      background: #eee;
      background: linear-gradient(120deg, rgba(50, 150, 100, 0.2), rgba(0, 0, 100, 0));
    }
    *,
    *:before,
    *:after {
      margin-bottom: 10px;
      padding: 0;
      /* border: 0; */
      outline: 0;
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
    }
    table {
      width: 78% !important;
      font-family: 'Open Sans', Helvetica;
      color: #efefef;
      text-align: center;
      /* margin: auto; */
      padding: auto;
      /* margin-top: 10px; */
      /* margin-bottom: 10px; */
      position: relative;
      float: left;
    }
    a {
      color: #2f3b72;
      text-decoration: none
    }
    table tr:nth-child(2n) {
      background: #eff0f1;
    }
    table tr:nth-child(2n+3) {
      background: #fff;
    }
    td {
      color: #2f3b72;
      font-weight: 1000;
      font-family: 'DungGeunMo';
      font-size: 12px !important;
    }
    table th,
    table td {
      padding: 0.7em;
      width: 10em;
    }
    .days,
    .time {
      background: #34495e;
      text-transform: uppercase;
      font-size: 0.8em;
      text-align: center;
    }
    #left_side {
      width: 3em !important;
      background: #34495e;
      font-size: 0.6em;
      text-align: center;
    }
    /* Add this attribute to the element that needs a tooltip */
    [data-tooltip] {
      position: relative;
      z-index: 2;
      cursor: pointer;
    }
    /* Hide the tooltip content by default */
    [data-tooltip]:before,
    [data-tooltip]:after {
      visibility: hidden;
      filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
      opacity: 0;
      pointer-events: none;
      -moz-transition: ease 0.5s all;
      -o-transition: ease 0.5s all;
      -webkit-transition: ease 0.5s all;
      transition: ease 0.5s all;
    }
    /* Position tooltip above the element */
    [data-tooltip]:before {
      position: absolute;
      bottom: 110%;
      left: 50%;
      margin-bottom: 5px;
      margin-left: -80px;
      padding: 7px;
      width: 160px;
      -moz-border-radius: 6px;
      -webkit-border-radius: 6px;
      border-radius: 6px;
      background-color: black;
      color: #fff;
      content: attr(data-tooltip);
      text-align: center;
      font-size: 14px;
      line-height: 1.2;
    }
    /* Triangle hack to make tooltip look like a speech bubble */
    [data-tooltip]:after {
      position: absolute;
      bottom: 110%;
      left: 50%;
      margin-left: -5px;
      width: 0;
      border-top: 5px solid black;
      border-right: 5px solid transparent;
      border-left: 5px solid transparent;
      content: " ";
      font-size: 0;
      line-height: 0;
    }
    /* Show tooltip content on hover */
    [data-tooltip]:hover:before,
    [data-tooltip]:hover:after {
      visibility: visible;
      bottom: 90%;
      filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
      opacity: 1;
    }
    #container{
      position: relative;
      float: left;
      margin-left: 10px;
  width: 20%;
  background: rgba(0, 0, 200, 0.2);
  padding: 15px;
  border: 2px solid #fff;
  border-radius: 5px;
  background-clip: padding-box;
  text-align: center;
  font-family: 'silgothic';
    font-size: 1em;
    color: black;
    font-weight: 1000;
    white-space: nowrap;
    box-shadow: 0 15px 30px 1px rgba(128, 128, 128, 0.31);
    height: 120px;
    }
    #container1{
      position: relative;
      float: left;
      margin-left: 10px;
  width: 20%;
  /* background: rgba(0, 0, 200, 0.2); */
  padding: 15px;
  border: 2px solid #fff;
  border-radius: 5px;
  background-clip: padding-box;
  text-align: center;
  font-family: 'silgothic';
    font-size: 1em;
    color: black;
    font-weight: 1000;
    white-space: nowrap;
    box-shadow: 0 15px 30px 1px rgba(128, 128, 128, 0.31);
    height: 100px;
    }
    h2{
      margin-top: 0px;
    }
    p {
      margin-top: auto;
    }
    .explore{
      float:left;
      font-size: 20px;
      
      margin-top: 10px;
      margin-left: 30px;
      padding-top: 10px;
    }
    i  {
      float:right;
      font-size: 40px;
      margin: auto;
      padding: 10px;
    }
    .created{
      position: relative;
      float: left;
      display: table;
      vertical-align: middle;
      font-size: 20px;
      width: 320px;
      height: 150px;
      margin-top: 30px;
    }
    img{
      float: left;
      margin-left: 10px;
      /* position: relative; */
      border-radius: 10px;
      margin-right: 10px;
    }
    #made{
      
      display: table-cell;
      vertical-align: middle;
      text-align: center;;
      margin-top: 20px !important;
      margin-left: 30px;
      font-family: 'KCC-eunyoung';
      font-size: 1.5em;
      font-weight: 600;
    }
  </style>
          <title>Time Table</title>
        </head>
        """

        self.main_body_html = """
        
        
        <body>
          <!-- <div class='tab'> -->
          <table border='0' cellpadding='0' cellspacing='0'>
            <tr class='days'>
              <th id='left_side'>#</th>
        
              <th>Mon</th>
              <th>Tue</th>
              <th>Wed</th>
              <th>Thu</th>
              <th>Fri</th>
        
        
            </tr>
        """

        self.main_bottom_html = """    
       </table>
      <!-- </div> -->
 <div id='container'>
        <h2>총 <a href="Course_List.html"><U><b>{credit}</b>학점</a></U></h2>
        <p>강의계획서 - 강의명 클릭!</p>
        <p>강의평 - 강의명에 마우스 올리기!</p>
        
               
      </div>
      <div id='container1'>
        <div class='explore'>E x p l o r e !</div>
        <a href="<https://github.com/kjh03160>" target="_blank"><i class="fab fa-github"></i></a>
        
      </div>
    </body>
    
    </html>
    """

        self.list_head_html = """
        
        <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Time List</title>
    <style>
html{
    height: 100%;
    overflow:hidden;
}
h1{
    margin-top:-10px;
  font-size: 30px;
  color: rgb(25, 83, 34);
  text-transform: uppercase;
  font-weight: 1000;
  text-align: center;
  margin-bottom: 15px;
}
table{
  width:100%;
  table-layout: fixed;
}
.tbl-header{
  background-color: rgba(231, 203, 247, 0.377);
 }
.tbl-content{
  height:500px;
  overflow-x:auto;
  margin-top: 0px;
  border: 1px solid rgba(121, 120, 120, 0.3);
}
th{
  padding: 20px 15px;
  text-align: center;
  font-weight: 500;
  font-size: 12px;
  font-weight: 1000;
  color: rgb(233, 87, 51);
  text-transform: uppercase;
}
td{
  padding: 15px;
  text-align: center;
  vertical-align:middle;
  font-weight: 300;
  font-size: 15px;
  color: rgba(32, 26, 25, 0.993);
  border-bottom: solid 1px rgba(128, 126, 126, 0.212);
  word-break: keep-all;
}
a {
      color: #c2306d;
      text-decoration: none
    }
/* demo styles */
@import url(<https://fonts.googleapis.com/css?family=Roboto:400,500,300,700>);
body{
  background: linear-gradient(0deg, rgba(0, 0, 200, 0.2), rgba(0, 0, 200, 0));
  font-family: 'Roboto', sans-serif;
  background-attachment: fixed;	
	background-size: cover;
    height: 100%;
}
section{
  margin: 50px;
  height: 80%;
}
/* follow me template */
.made-with-love {
  margin-top: 30px;
  padding: 5px;
  /* clear: left; */
  text-align: center;
  font-size: 20px;
  font-family: arial;
  color: rgb(85, 66, 66);
position: relative;
left:-73px;
}
.made-with-love i {
  font-style: normal;
  color: rgb(168, 51, 92);
  font-size: 24px;
  position: relative;
  top: 0px;
}
.made-with-love a {
  color: rgb(53, 43, 43);
  text-decoration: none;
}
.made-with-love a:hover {
  text-decoration: underline;
}
/* for custom scrollbar for webkit browser*/
::-webkit-scrollbar {
    width: 6px;
} 
::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 
} 
::-webkit-scrollbar-thumb {
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 
}
.buttons-con{
    z-index: 3;
  position: relative;
  float: left;
}
.buttons-con .action-link-wrap {
  margin-top: 8px;
  margin-left: 50px;
}
.buttons-con .action-link-wrap a {
  background: #c47ace;
  padding: 8px 25px;
  border-radius: 4px;
  color: #FFF;
  font-weight: bold;
  font-size: 14px;
  transition: all 0.3s linear;
  cursor: pointer;
  text-decoration: none;
  margin-right: 10px
}
.buttons-con .action-link-wrap a:hover {
  background: rgb(112, 17, 190);
  color: #fff;
}
.required {
    color : red;
}
.team {
    color : green;
}
.foreign{
    color : purple;
}
.online {
    color : blue;
}
</style>
</head>
<body>
        <section>
                <!--for demo wrap-->
                <h1>HUFS User Time Table</h1>
                <div class="tbl-header">
                  <table cellpadding="0" cellspacing="0" border="0">
                    <thead>
                      <tr>
                        <th width="30px">Area</th>
                        <th width="350px">Subject Name</th>
                        <th width="60px">전필</th>
                        <th width="60px">온라인</th>
                        <th width="60px">원어</th>
                        <th width="60px">팀티칭</th>
                        <th width="80px">담당교수</th>
                        <th width="30px">학점</th>
                        <th width="50px">강의시간</th>
                        <th width="50px">제한인원</th>
                        <th>비고</th>
                        <th width="50px">강의평가</th>
                      </tr>
                    </thead>
                  </table>
                </div>
                <div class="tbl-content">
                  <table cellpadding="0" cellspacing="0" border="0">
                    <tbody>
        """

        self.list_body_html = """
        
        """

        self.list_bottom_html = """
                            </tbody>
                  </table>
                </div>
              </section>
              <div class="buttons-con">
                  <div class="action-link-wrap">
                    <a href="Result.html" class="link-button link-back-button">Go Back</a>
                  </div>
                </div>
              <!-- follow me template -->
</body>
</html>
        """

    def make_result_html(self, user):
        print('웹페이지 제작중...')
        for time in range(user.longest):
            td_html = '''
                    <tr>
                      <th id='left_side'>{time}</th>
                      <td {stars1}>{Mon}</td>
                      <td {stars2}>{Tue}</td>
                      <td {stars3}>{Wed}</td>
                      <td {stars4}>{Thu}</td>
                      <td {stars5}>{Fri}</td>
                    </tr>
                        '''
            html_list = []
            stars_list = []

            Mon = user.time_table['Mon'][time]
            Tue = user.time_table['Tue'][time]
            Wed = user.time_table['Wed'][time]
            Thu = user.time_table['Thu'][time]
            Fri = user.time_table['Fri'][time]
            def day_table(day, html_list):
                temp_stars = []
                insert_html = ""
                for i in day:
                    sub = i['sub'].split(' / ')[0]
                    syllabus = i['syllabus']
                    prof = i['prof']
                    stars = i['stars']
                    sub = sub + '<br>' + '(' + prof + ')'
                    insert_html += '<a href="' + syllabus + '" target="_blank">' + sub + '</a>' + '<br><br>\\n'
                    temp_stars.append(stars)
                html_list.append(insert_html[:-9])
                stars_list.append(" / ".join(temp_stars))

            day_table(Mon, html_list)
            day_table(Tue, html_list)
            day_table(Wed, html_list)
            day_table(Thu, html_list)
            day_table(Fri, html_list)
            for i in range(5):
                if len(stars_list[i]) == 0:
                    stars_list[i] = ''
                else:
                    stars_list[i] = 'data-tooltip=' + "'" + stars_list[i] + "'"

            self.main_body_html += td_html.format(time=str(time + 1), Mon=html_list[0], Tue=html_list[1], Wed=html_list[2],
                                     Thu=html_list[3], Fri=html_list[4], stars1=stars_list[0],
                                     stars2=stars_list[1], stars3=stars_list[2], stars4=stars_list[3],
                                     stars5=stars_list[4])

        self.main_bottom_html = self.main_bottom_html.format(credit=user.credits)

    def make_list_html(self, user):
        courses = user.courses
        if user.course_evl:
            quick_sort_by_stars(courses, 0, len(courses) - 1)
        else:
            quick_sort_by_time(courses, 0, len(courses) - 1)

        inserted_html = """
                              <tr>
                        <td width="30px">{area}</td>
                        <td width="350px">{subject}</td>
                        <td width="60px" class="required"><b>{required}</b></td>
                        <td width="60px" class="online"><b>{online}</b></td>
                        <td width="60px" class="foreign"><b>{foreign}</b></td>
                        <td width="60px" class="team"><b>{team_teaching}</b></td>
                        <td width="80px">{prof}</td>
                        <td width="30px">{credit}</td>
                        <td width="50px">{class_time}</td>
                        <td width="50px">{restrict_num}</td>
                        <td >{note}</td>
                        <td width="50px">{stars}</td>
                      </tr>
        """
        for i in courses:
            area = i.area
            name = i.subject.split(' / ')
            if len(name) > 1:
                name = name[0] + '<br>' + name[1]
            else:
                name = name[0]
            subject = '<a href="' + i.syllabus + '" target="_blank">' + name + '</a>'
            required = i.required
            online = i.online
            foreign = i.foreign
            team_teaching = i.team_teaching
            prof = i.prof
            credit = i.credit
            class_time = i.class_time
            restrict_num = i.restrict_num
            note = i.note
            stars = i.stars
            self.list_body_html += inserted_html.format(area = area, subject = subject, required = required, online = online,
                                                             foreign = foreign, team_teaching = team_teaching, prof = prof,
                                                             credit = credit, class_time = class_time, restrict_num = restrict_num,
                                                             note = note, stars = stars)

    def make_by_pandas(self, dict):
        tds_list = []
        # with open(user.first_major + '1.txt', 'r', encoding='UTF-8') as first:
        #     with open(user.second_major + '1.txt', 'r', encoding='UTF-8') as second:
        with open('temp.html', 'r', encoding='UTF-8') as file:
            a = file.readline()
            time = 1
            while a != "":
                a = file.readline()
                if '<td>' in a:
                    td_html = '''
                            <tr>
              <th id='left_side'>{time}</th>
              <td {stars1}>{Mon}</td>
              <td {stars2}>{Tue}</td>
              <td {stars3}>{Wed}</td>
              <td {stars4}>{Thu}</td>
              <td {stars5}>{Fri}</td>
            </tr>
            '''
                    k = 0
                    html_list = []
                    stars = []

                    def table_make(line):
                        print(line)
                        line = line.strip()[5:-7:1].split(',,')  # <td>[ , ]</td> 제거후 2 과목 이상 있으면 분리
                        insert_html = ""
                        if len(line) == 0:
                            html_list.append(insert_html)
                        temp_stars =[]
                        for i in line:
                            i = i.split('::')
                            i = i[1:]
                            if len(i) == 0:
                                continue
                            subject = i[0].split(' / ')

                            temp_stars.append(i[1])
                            if len(i) > 1:
                                insert_html += '<a href=' + i[2] + '>' + '<br>'.join(subject) +'</a>' + '<br><br>\\n'
                            else:
                                insert_html += ('<a href=' + i[2] + '>' + subject[0] + '</a>' + '<br>' + '\\n')
                        stars.append(' / '.join(temp_stars))
                        html_list.append(insert_html[:-9] + '\\n')

                    for i in range(5):
                        table_make(a)
                        k += 1
                        a = file.readline()

                    for i in range(5):
                        if len(stars[i]) == 0:
                            stars[i] = ''
                        else:
                            stars[i] = 'data-tooltip=' + "'" + stars[i] + "'"
                    td_html = td_html.format(time = time, Mon = html_list[0], Tue = html_list[1], Wed = html_list[2],
                                             Thu = html_list[3], Fri = html_list[4], stars1 = stars[0],
                                             stars2 = stars[1], stars3 = stars[2], stars4 = stars[3],
                                             stars5 = stars[4])
                    tds_list.append(td_html)
                    time += 1

        return tds_list

Main.py

from Class_Define import User_Table
from Crwal_Table import Crwal_Table
from html_making import HTML
import os
from sys import exit

def main():
    while True:
        year, semester = input('학기를 입력해주세요 (Ex 20-1 or 20-여름) : ').split('-')
        majors = input('1전공, 2전공을 입력해주세요 (띄어쓰기로 구분), 종료(q 입력) : ').split()
        if majors[0] == 'q':
            exit()
        grade = input('듣고 싶은 수업의 학년을 입력해주세요 (띄어쓰기로 구분) : ').split()
        course_evl = input('강의 평가를 추가하시겠습니까? (에브리타임 로그인 필요, y/n) : ')

        try:
            crawling = Crwal_Table()

            if len(majors) > 1:
                first_major, second_major = majors
            else:
                first_major = majors[0]
                second_major = None

            first_major_obj = crawling.make_timetable(first_major, year, semester)
            second_major_obj = crawling.make_timetable(second_major, year, semester)

            user1 = User_Table(False, grade, first_major, second_major)

            if course_evl == 'y':
                user1.course_evl = True
                crawling.get_avg_stars(first_major_obj, second_major_obj, grade)
            if crawling.browser:
                crawling.browser.close()

            user1.make_txt(first_major_obj, second_major_obj)

            user1.make_time_dict()

            html = HTML()
            html.make_result_html(user1)
            html.make_list_html(user1)

            with open('Result.html', 'w', encoding='UTF-8') as file:
                file.write(html.main_head_html + html.main_body_html + html.main_bottom_html)

            with open('Course_List.html', 'w', encoding='UTF-8') as file:
                file.write(html.list_head_html + html.list_body_html +html.list_bottom_html)
            print('완료!')
            os.startfile('Result.html')
            print()
            print()

        except Exception as e:
            print(e)
            print('다시 시도해주세요')
            print()
        # finally:
        #     os.system('cls')

if __name__ == "__main__":
    main()
    input()