Add vts-fetch script for fetching and saving data from the API

This commit is contained in:
암냥 2025-09-22 00:01:41 +09:00
commit e108d901e2

66
vts-fetch.ts Normal file
View file

@ -0,0 +1,66 @@
// vts-fetch.ts
const BASE = "https://isangjeong.icems.kr";
async function main() {
const listUrl = `${BASE}/boardCnts/list.do?boardID=33523&m=0601&s=isangjeong`;
const listRes = await fetch(listUrl, {
headers: {
'User-Agent': 'today.isangjeong'
}
});
if (!listRes.ok) throw new Error(`list fetch failed: ${listRes.status}`);
const listHtml = await listRes.text();
// 더 안정적으로: 먼저 subject_ID 검사, 없으면 goView의 3번째 인자 사용
let boardSeq: string | null = null;
const idMatch = listHtml.match(/id=["']subject_(\d+)["']/);
if (idMatch) boardSeq = idMatch[1];
else {
const gv = listHtml.match(/goView\(\s*['"]\d+['"]\s*,\s*['"]\d+['"]\s*,\s*['"](\d+)['"]/);
if (gv) boardSeq = gv[1];
}
if (!boardSeq) {
console.error("게시글 번호( boardSeq )를 찾을 수 없음.");
return;
}
console.log("게시글 번호:", boardSeq);
const viewUrl = `${BASE}/boardCnts/updateCnt.do?boardID=33523&viewBoardID=33523&boardSeq=${boardSeq}&lev=0&action=view`;
console.log("상세 페이지 URL:", viewUrl);
const viewRes = await fetch(viewUrl, {
headers: {
'User-Agent': 'today.isangjeong'
}
});
if (!viewRes.ok) throw new Error(`view fetch failed: ${viewRes.status}`);
const viewHtml = await viewRes.text();
// 첨부파일 링크 추출 (첫 번째 fileDown 링크 사용)
const fileHrefMatch = viewHtml.match(/href=["'](\/boardCnts\/fileDown\.do\?fileSeq=[^"']+)["']/i);
if (!fileHrefMatch) {
console.error("파일 다운로드 링크 없음.");
return;
}
const fileUrl = BASE + fileHrefMatch[1];
console.log("파일 URL:", fileUrl);
const fileRes = await fetch(fileUrl, {
headers: {
'User-Agent': 'today.isangjeong'
}
});
if (!fileRes.ok) throw new Error(`file fetch failed: ${fileRes.status}`);
const ab = await fileRes.arrayBuffer();
const outputPath = "/var/static/f.imnya.ng/.today.isangjeong/vts.xlsx";
await Bun.write(outputPath, new Uint8Array(ab));
console.log("저장됨:", outputPath);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});