ntpu

package
v1.7.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package ntpu provides scrapers for NTPU websites including student ID, course catalog, and contact directory information.

Index

Constants

View Source
const (
	StudentTypeContinuing = "3" // 進修學士班
	StudentTypeUndergrad  = "4" // 大學部/學士班
	StudentTypeMaster     = "7" // 碩士班
	StudentTypePhD        = "8" // 博士班
)

Student type prefixes for scraping

View Source
const (
	DegreeNameContinuing = "進修學士班"
	DegreeNameBachelor   = "學士班"
	DegreeNameMaster     = "碩士班"
	DegreeNamePhD        = "博士班"
	DegreeNameUnknown    = "國立臺北大學" // Fallback for invalid/unknown prefix
)

DegreeTypeName constants for user-facing display (標準名稱)

Variables

View Source
var DepartmentCodes = map[string]string{
	"法律": "71",
	"法學": "712",
	"司法": "714",
	"財法": "716",
	"公行": "72",
	"經濟": "73",
	"社學": "742",
	"社工": "744",
	"財政": "75",
	"不動": "76",
	"會計": "77",
	"統計": "78",
	"企管": "79",
	"金融": "80",
	"中文": "81",
	"應外": "82",
	"歷史": "83",
	"休運": "84",
	"資工": "85",
	"通訊": "86",
	"電機": "87",
}

DepartmentCodes maps department names to codes (大學部). Note: "法律" and base codes for 社學/社工 require 3rd digit from student ID

View Source
var DepartmentNames = reverseMap(DepartmentCodes)

DepartmentNames provides reverse mappings: code -> name

View Source
var FullDepartmentCodes = map[string]string{
	"法律學系":       "71",
	"法律學系法學組":    "712",
	"法律學系司法組":    "714",
	"法律學系財經法組":   "716",
	"公共行政暨政策學系":  "72",
	"經濟學系":       "73",
	"社會學系":       "742",
	"社會工作學系":     "744",
	"財政學系":       "75",
	"不動產與城鄉環境學系": "76",
	"會計學系":       "77",
	"統計學系":       "78",
	"企業管理學系":     "79",
	"金融與合作經營學系":  "80",
	"中國文學系":      "81",
	"應用外語學系":     "82",
	"歷史學系":       "83",
	"休閒運動管理學系":   "84",
	"資訊工程學系":     "85",
	"通訊工程學系":     "86",
	"電機工程學系":     "87",
}

FullDepartmentCodes maps full department names to codes (大學部)

View Source
var MasterDepartmentCodes = map[string]string{
	"企業管理學系碩士班":       "31",
	"會計學系碩士班":         "32",
	"統計學系碩士班":         "33",
	"金融與合作經營學系碩士班":    "34",
	"國際企業研究所碩士班":      "35",
	"資訊管理研究所":         "36",
	"財務金融英語碩士學位學程":    "37",
	"民俗藝術與文化資產研究所":    "41",
	"古典文獻學研究所":        "42",
	"中國文學系碩士班":        "43",
	"歷史學系碩士班":         "44",
	"法律學系碩士班一般生組":     "51",
	"法律學系碩士班法律專業組":    "52",
	"經濟學系碩士班":         "61",
	"社會學系碩士班":         "62",
	"社會工作學系碩士班":       "63",
	"犯罪學研究所":          "64",
	"公共行政暨政策學系碩士班":    "71",
	"財政學系碩士班":         "72",
	"不動產與城鄉環境學系碩士班":   "73",
	"都市計劃研究所碩士班":      "74",
	"自然資源與環境管理研究所碩士班": "75",
	"城市治理英語碩士學位學程":    "76",
	"會計學系碩士在職專班":      "77",
	"統計學系碩士在職專班":      "78",
	"企業管理學系碩士在職專班":    "79",
	"通訊工程學系碩士班":       "81",
	"電機工程學系碩士班":       "82",
	"資訊工程學系碩士班":       "83",
	"智慧醫療管理英語碩士學位學程":  "91",
}

MasterDepartmentCodes maps master's program department names to codes (碩士班)

View Source
var MasterDepartmentNames = reverseMap(MasterDepartmentCodes)

MasterDepartmentNames provides reverse mappings for master degree programs: code -> name.

View Source
var MasterDeptCodes = []string{
	"31",
	"32",
	"33",
	"34",
	"35",
	"36",
	"37",
	"41",
	"42",
	"43",
	"44",
	"51",
	"52",
	"61",
	"62",
	"63",
	"64",
	"71",
	"72",
	"73",
	"74",
	"75",
	"76",
	"77",
	"78",
	"79",
	"81",
	"82",
	"83",
	"91",
}

MasterDeptCodes contains master's program department codes for scraping.

View Source
var PhDDepartmentCodes = map[string]string{
	"企業管理學系博士班":       "31",
	"會計學系博士班":         "32",
	"法律學系博士班":         "51",
	"經濟學系博士班":         "61",
	"公共行政暨政策學系博士班":    "71",
	"不動產與城鄉環境學系博士班":   "73",
	"都市計劃研究所博士班":      "74",
	"自然資源與環境管理研究所博士班": "75",
	"電機資訊學院博士班":       "76",
}

PhDDepartmentCodes maps PhD program department names to codes (博士班)

View Source
var PhDDepartmentNames = reverseMap(PhDDepartmentCodes)

PhDDepartmentNames provides reverse mappings for PhD programs: code -> name.

View Source
var PhDDeptCodes = []string{
	"31",
	"32",
	"51",
	"61",
	"71",
	"73",
	"74",
	"75",
	"76",
}

PhDDeptCodes contains PhD program department codes for scraping.

View Source
var UndergradDeptCodes = []string{
	"71", "712", "714", "716",
	"72",
	"73",
	"742", "744",
	"75",
	"76",
	"77",
	"78",
	"79",
	"80",
	"81",
	"82",
	"83",
	"84",
	"85",
	"86",
	"87",
}

UndergradDeptCodes contains undergraduate department codes for scraping.

Functions

func BuildContactSearchURL added in v1.2.6

func BuildContactSearchURL(searchTerm string) string

BuildContactSearchURL generates the URL for viewing contact search results. The search term is encoded in Big5 format as required by the NTPU directory. Returns empty string if encoding fails. This is used for the "資料來源" button to open the original contact page.

func ExtractYear added in v1.3.5

func ExtractYear(studentID string) int

ExtractYear extracts the academic year from a student ID. Example: 410571074 -> 105, 41121074 -> 112, 414185001 -> 114

func GetDegreeTypeName added in v1.3.6

func GetDegreeTypeName(studentID string) string

GetDegreeTypeName returns the degree type display name based on student ID prefix. Returns the standard Chinese name: 進修學士班, 學士班, 碩士班, 博士班. Falls back to "國立臺北大學" if the prefix is invalid or empty.

func IsLawDepartment

func IsLawDepartment(deptCode string) bool

IsLawDepartment returns true if the department code belongs to Law School (71x). Used to determine if "組" should be used instead of "系" in display text.

func ProbeCoursesExist added in v1.3.6

func ProbeCoursesExist(ctx context.Context, client *scraper.Client, year, term int) (bool, error)

ProbeCoursesExist performs a lightweight check if courses exist for a semester. Uses a single education code (U = undergraduate) to minimize HTTP requests. Returns true if any courses are found, false otherwise. This is specifically designed for warmup probing and should not be used for data collection.

func ScrapeAcademicContacts

func ScrapeAcademicContacts(ctx context.Context, client *scraper.Client) ([]*storage.Contact, error)

ScrapeAcademicContacts scrapes all academic contacts Supports automatic URL failover across multiple SEA endpoints

func ScrapeAdministrativeContacts

func ScrapeAdministrativeContacts(ctx context.Context, client *scraper.Client) ([]*storage.Contact, error)

ScrapeAdministrativeContacts scrapes all administrative contacts Supports automatic URL failover across multiple SEA endpoints

func ScrapeContacts

func ScrapeContacts(ctx context.Context, client *scraper.Client, searchTerm string) ([]*storage.Contact, error)

ScrapeContacts scrapes contacts by search term URL: {baseURL}/pls/ld/CAMPUS_DIR_M.pq?q={searchTerm} The search term must be URL-encoded in Big5 encoding Supports automatic URL failover across multiple SEA endpoints with cache invalidation

func ScrapeCourseByUID

func ScrapeCourseByUID(ctx context.Context, client *scraper.Client, uid string) (*storage.Course, error)

ScrapeCourseByUID scrapes a specific course by its UID (year+term+no) Example UID: 11312U123 (year=113, term=1, no=2U123) Supports automatic URL failover across multiple SEA endpoints

func ScrapeCourses

func ScrapeCourses(ctx context.Context, client *scraper.Client, year, term int, title string) ([]*storage.Course, error)

ScrapeCourses scrapes courses by year, term, and optional filters For title search: uses POST to {baseURL}/pls/dev_stud/course_query_all.queryByAllConditions with 'cour' parameter For general query: uses GET to {baseURL}/pls/dev_stud/course_query_all.queryByKeyword with 'courseno' parameter When term=0, queries both semesters at once (more efficient for historical searches) Supports automatic URL failover across multiple SEA endpoints

func ScrapeCoursesByTeacher added in v1.1.2

func ScrapeCoursesByTeacher(ctx context.Context, client *scraper.Client, year, term int, teacherName string) ([]*storage.Course, error)

ScrapeCoursesByTeacher scrapes courses by teacher name Uses POST to {baseURL}/pls/dev_stud/course_query_all.queryByAllConditions with 'teach' parameter

func ScrapeCoursesByYear

func ScrapeCoursesByYear(ctx context.Context, client *scraper.Client, year int) ([]*storage.Course, error)

ScrapeCoursesByYear scrapes ALL courses for a given year (both semesters) This is a convenience wrapper around ScrapeCourses with term=0 and empty title Note: Current warmup uses per-semester scraping (ScrapeCourses) for precise control

func ScrapeStudentByID

func ScrapeStudentByID(ctx context.Context, client *scraper.Client, studentID string) (*storage.Student, error)

ScrapeStudentByID scrapes a specific student by their student ID URL: {baseURL}/portfolio/search.php?fmScope=2&page=1&fmKeyword={studentID} Supports automatic URL failover across multiple LMS endpoints

func ScrapeStudentsByYear

func ScrapeStudentsByYear(ctx context.Context, client *scraper.Client, year int, deptCode, studentType string) ([]*storage.Student, error)

ScrapeStudentsByYear scrapes students by year, department code and student type. URL: {baseURL}/portfolio/search.php?fmScope=2&page=1&fmKeyword={studentType}{year}{deptCode} studentType: "4" for undergrad, "7" for master's, "8" for PhD Returns a list of students matching the criteria. Supports automatic URL failover across multiple LMS endpoints.

Types

type ProgramFolder added in v1.2.0

type ProgramFolder struct {
	ID       string
	Category string
}

ProgramFolder represents a category of programs on the LMS.

type ProgramInfo added in v1.2.0

type ProgramInfo struct {
	Name     string
	Category string
	URL      string
}

ProgramInfo contains information about an academic program.

func ScrapePrograms added in v1.2.0

func ScrapePrograms(ctx context.Context, client *scraper.Client) ([]ProgramInfo, error)

ScrapePrograms dynamically discovers all programs by crawling the LMS folders. It handles pagination automatically by detecting "Next" links. Supports automatic URL failover via URLCache.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL