Skip to content

blue-ssu/meal-scraper

Repository files navigation

@bluessu/meal-scraper

npm version npm downloads license TypeScript

WIP (Working In Progress)

현재 이 라이브러리는 개발 중인 상태입니다.

프로젝트 출처

이 프로젝트의 초기 구현은 EAT-SSU/Food-Crawling 내부 구현을 바탕으로 작성되었습니다.

지원 환경

  • Node.js: >= 18
  • 공개 라이선스: GPL-3.0
  • OpenAI 파서를 사용하려면 프로젝트에 openai가 별도 설치되어 있어야 합니다. (openai는 선택 의존성입니다)

배포/릴리스

패키지 배포는 다음 스크립트를 사용합니다.

pnpm run release:patch
pnpm run release:minor
pnpm run release:major

설치

Using npm:

npm i @bluessu/meal-scraper

GPT 파서를 사용하려면 먼저 OpenAI 클라이언트를 설치하세요.

pnpm add openai

Using yarn

yarn add @bluessu/meal-scraper

Using pnpm:

pnpm add @bluessu/meal-scraper

특징

  • createMealClient() 또는 new MealClient()로 클라이언트 생성
  • 단건 조회/배치 조회/범위 조회 지원
  • 날짜 입력을 string 또는 Date로 유연하게 지원
  • 내부 구현 분리로 공개 API가 간결하고 유지보수하기 쉬운 구조

공개 API

src/index.ts에서 노출되는 주요 API는 다음과 같습니다.

  • MealClient
  • createMealClient
  • normalizeMenuDate
  • buildDateRange
  • 타입
    • MenuDateInput
    • MenuDate
    • ParserMode
    • MealClientOptions
    • RangeOptions
  • 도메인/설정
    • CafeteriaType
    • RawMenuData
    • DailyMenu
    • FoodCrawlerSettings
    • defaultSettings
  • 예외
    • BaseCafeteriaException
    • HolidayException
    • MenuFetchException
    • MenuParseException

기본 사용법

import {
  MealClient,
  createMealClient,
  CafeteriaType,
  normalizeMenuDate,
  buildDateRange,
} from "@bluessu/meal-scraper";

const client = createMealClient();
await client.getRawMenu(CafeteriaType.DODAM, new Date());
await client.getDailyMenu(CafeteriaType.HAKSIK, "2026-02-28");
await client.getDailyMenusByRange(CafeteriaType.FACULTY, "2026-02-28", "2026-03-02", {
  concurrency: 3,
});

Client 옵션

export type ParserMode = "noop" | "gpt" | "custom";
  • noop(기본): 기본 파서(NoopMenuParser) 사용
  • gpt: OpenAI 파서 사용 (gptApiKey 필수)
  • custom: 직접 구현한 파서를 parserImpl로 주입
import { createMealClient } from "@bluessu/meal-scraper";

// GPT 모드 예시 (키가 없으면 생성 단계에서 에러)
const gptClient = createMealClient({
  parser: "gpt",
  gptApiKey: process.env.OPENAI_API_KEY,
});

// 커스텀 파서 주입 예시
const customClient = createMealClient({
  parser: "custom",
  parserImpl: {
    parseMenu: async (raw) => {
      // 사용자 구현
      return {
        date: raw.date,
        cafeteria: raw.cafeteria,
        status: "open",
        breakfast: {},
        lunch: {},
        dinner: {},
      };
    },
  },
});

날짜 정규화 유틸

import { normalizeMenuDate, buildDateRange } from "@bluessu/meal-scraper";

normalizeMenuDate("2026-02-28"); // "2026-02-28"
normalizeMenuDate(new Date(2026, 1, 28)); // "2026-02-28"

buildDateRange("2026-02-28", "2026-03-02"); // ["2026-02-28","2026-03-01","2026-03-02"]

지원 날짜 포맷은 내부적으로 모두 YYYY-MM-DD로 정규화됩니다.

API 목록

MealClient

  • getRawMenu(cafeteria, date): Promise<RawMenuData>
  • getDailyMenu(cafeteria, date): Promise<DailyMenu>
  • getRawMenus(cafeteria, dates, options?): Promise<RawMenuData[]>
  • getDailyMenus(cafeteria, dates, options?): Promise<DailyMenu[]>
  • getRawMenusByRange(cafeteria, start, end, options?): Promise<RawMenuData[]>
  • getDailyMenusByRange(cafeteria, start, end, options?): Promise<DailyMenu[]>

옵션

  • RangeOptions
    • startInclusive?: boolean (기본값: true)
    • concurrency?: number (기본값: 3)

에러 처리

import { HolidayException, MenuFetchException } from "@bluessu/meal-scraper";

try {
  const menu = await client.getDailyMenu(CafeteriaType.DORMITORY, "2026-02-28");
} catch (error) {
  if (error instanceof HolidayException) {
    console.log("휴일입니다");
  } else if (error instanceof MenuFetchException) {
    console.log("수집 실패");
  } else {
    console.error(error);
  }
}

프로젝트 구조

현재 공개 엔트리는 src/index.ts에 집중하고, 실제 구현은 내부 레이어로 분리되어 있습니다.

  • src/index.ts: 라이브러리 바렐(export hub)
  • src/client/*: 클라이언트 API 및 유틸
  • src/services/*: 수집/파싱 오케스트레이션
  • src/repositories/*: 사이트별 스크래퍼
  • src/parsers/*: 파싱 전략
  • src/domain.ts, src/config.ts, src/errors.ts: 도메인/설정/예외

라이선스

GNU General Public License Version 3 (GPL-3.0) 입니다.
라이선스 파일은 LICENSE를 확인하세요.

About

숭실대학교 학식 스크래퍼 타입스크립트 라이브러리

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors