feat(B09): 유가 지역 단가를 물림 — 시도를 고르면 그 값으로 기계 연료비가 다시 섬

품셈 8-1-7 5호 「유류가격은 해당지역의 가격으로 한다」. 칸은 있었으나 시도별 값이
없어 잠겨 있었음. 오피넷 avgSidoPrice.do 스냅샷을 받아 데이터셋으로 세우고 물림.

- 안 고르면 전국평균 그대로 — 현장 소재지를 임의로 찍지 않음.
- 판에 없는 지역은 조용히 전국평균으로 눕지 않고 사유를 남김.
- 「지역 공시가」를 고를 수 있는지는 코드가 아니라 판이 정함.
- ⚠ 원천의 시도 가름이 행정구역과 다름(20=전남광주 한 줄, 07·16 없음) — 원문 그대로 둠.
- 수집 스크립트에 시도별 호출을 더함(전국평균과 두 벌로 보존).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-09 21:22:15 +09:00
co-authored by Claude Opus 5
parent 92ba0780cd
commit f39c195b52
12 changed files with 786 additions and 46 deletions
@@ -8,7 +8,7 @@
4. 자재단가 스냅샷 : 나라장터 가격정보현황서비스 API → 자재단가/ (CSV+JSON, 수집일 파일명)
5. 환율 스냅샷 : 한국은행 ECOS API 731Y001 → 환율_한국은행ECOS/ (CSV, 연초~수집일 일별)
6. 유가 스냅샷 : 오피넷 API → 유가_오피넷/ (JSON, 수집일)
6. 유가 스냅샷 : 오피넷 API → 유가_오피넷/ (JSON, 수집일 — 전국평균·시도별 두 벌)
사용법:
python collect_cost_sources.py docs # 1~3 문서 다운로드 (게시판 최신글 자동 탐색은 미구현 —
@@ -171,6 +171,20 @@ def collect_values():
out.write_text(json.dumps(data, ensure_ascii=False, indent=1), encoding="utf-8")
print(f"saved {out.name}")
# 유가: 시도별 (품셈 8-1-7 5호 「유류가격은 해당지역의 가격」 — 지역 단가의 원천)
sido = {"수집일": today, "시도별": {}}
for prod in ["B027", "D047"]: # 휘발유, 자동차용경유
j = json.loads(
fetch(
f"https://www.opinet.co.kr/api/avgSidoPrice.do?out=json&code={opinet}&prodcd={prod}",
timeout=60,
)
)
sido["시도별"][prod] = j.get("RESULT", {}).get("OIL", [])
out = BASE / "유가_오피넷" / f"유가_시도별_{today}.json"
out.write_text(json.dumps(sido, ensure_ascii=False, indent=1), encoding="utf-8")
print(f"saved {out.name}")
def collect_snapshot(outdir=None):
key = read_g2b_key()
@@ -9,6 +9,11 @@
| 파일 | 내용 | 수집일 |
|---|---|---|
| 유가_전국평균_2026-08-14.json | 전국 평균 판매가 (휘발유·경유 등 5유종) | 2026-08-14 |
| 유가_시도별_2026-09-09.json | 시도별 판매가 (`avgSidoPrice.do` — 휘발유 B027·경유 D047) | 2026-09-09 |
⚠ **시도 가름이 행정구역과 다르다** — 원천이 17줄을 주는데 `00` 이 전국이고 `20` 이
「전남광주」 한 줄이며 `07`(전남)·`16`(광주)은 아예 없다. **원문 이름·코드를 그대로 두고
우리가 쪼개지 않는다.**
## 원천 현황
@@ -17,7 +22,7 @@
| 원천 | 한국석유공사 오피넷 무료 OpenAPI (`www.opinet.co.kr`) |
| 갱신 주기 | **주간** (주유소 판매가 기준) |
| 수집 주기 | 견적 기준일 확정 시점마다 — 내역서에 **기준일 명기** 필요 |
| 지역 파라미터 | 품셈 8-1-7의 5 "유류가격은 **해당지역의 가격**으로 한다" — 지역별 조회 지원(현재 스냅샷은 전국 평균) |
| 지역 파라미터 | 품셈 8-1-7의 5 "유류가격은 **해당지역의 가격**으로 한다" — 2026-09-09 시도별 스냅샷 수집(전국 평균 판과 **두 벌**로 보존) |
| 수집 범위 | 휘발유·경유 중심. **선박용경유·중유 제외** (2026-08-14 사용자 결정, 필요 시 재편입) |
## 사용처
@@ -0,0 +1,247 @@
{
"수집일": "2026-09-09",
"시도별": {
"B027": [
{
"SIDOCD": "00",
"SIDONM": "전국",
"PRODCD": "B027",
"PRICE": 1858.93,
"DIFF": 1858.93
},
{
"SIDOCD": "01",
"SIDONM": "서울",
"PRODCD": "B027",
"PRICE": 1905.02,
"DIFF": -0.43
},
{
"SIDOCD": "02",
"SIDONM": "경기",
"PRODCD": "B027",
"PRICE": 1855.78,
"DIFF": -0.45
},
{
"SIDOCD": "03",
"SIDONM": "강원",
"PRODCD": "B027",
"PRICE": 1870.23,
"DIFF": -0.03
},
{
"SIDOCD": "04",
"SIDONM": "충북",
"PRODCD": "B027",
"PRICE": 1866.12,
"DIFF": -0.2
},
{
"SIDOCD": "05",
"SIDONM": "충남",
"PRODCD": "B027",
"PRICE": 1864.78,
"DIFF": -0.57
},
{
"SIDOCD": "06",
"SIDONM": "전북",
"PRODCD": "B027",
"PRICE": 1859.7,
"DIFF": 0.33
},
{
"SIDOCD": "08",
"SIDONM": "경북",
"PRODCD": "B027",
"PRICE": 1852.71,
"DIFF": -0.05
},
{
"SIDOCD": "09",
"SIDONM": "경남",
"PRODCD": "B027",
"PRICE": 1854.71,
"DIFF": -0.11
},
{
"SIDOCD": "10",
"SIDONM": "부산",
"PRODCD": "B027",
"PRICE": 1842.66,
"DIFF": -0.25
},
{
"SIDOCD": "11",
"SIDONM": "제주",
"PRODCD": "B027",
"PRICE": 1889.27,
"DIFF": 0.05
},
{
"SIDOCD": "14",
"SIDONM": "대구",
"PRODCD": "B027",
"PRICE": 1831.78,
"DIFF": -0.07
},
{
"SIDOCD": "15",
"SIDONM": "인천",
"PRODCD": "B027",
"PRICE": 1845.64,
"DIFF": 0.09
},
{
"SIDOCD": "17",
"SIDONM": "대전",
"PRODCD": "B027",
"PRICE": 1836.79,
"DIFF": -1.07
},
{
"SIDOCD": "18",
"SIDONM": "울산",
"PRODCD": "B027",
"PRICE": 1838.49,
"DIFF": -0.01
},
{
"SIDOCD": "19",
"SIDONM": "세종",
"PRODCD": "B027",
"PRICE": 1855.8,
"DIFF": 0.16
},
{
"SIDOCD": "20",
"SIDONM": "전남광주",
"PRODCD": "B027",
"PRICE": 1862.28,
"DIFF": -0.64
}
],
"D047": [
{
"SIDOCD": "00",
"SIDONM": "전국",
"PRODCD": "D047",
"PRICE": 1843.79,
"DIFF": 1843.79
},
{
"SIDOCD": "01",
"SIDONM": "서울",
"PRODCD": "D047",
"PRICE": 1886.15,
"DIFF": -0.21
},
{
"SIDOCD": "02",
"SIDONM": "경기",
"PRODCD": "D047",
"PRICE": 1838.22,
"DIFF": -0.45
},
{
"SIDOCD": "03",
"SIDONM": "강원",
"PRODCD": "D047",
"PRICE": 1859.9,
"DIFF": -0.09
},
{
"SIDOCD": "04",
"SIDONM": "충북",
"PRODCD": "D047",
"PRICE": 1851.55,
"DIFF": -0.07
},
{
"SIDOCD": "05",
"SIDONM": "충남",
"PRODCD": "D047",
"PRICE": 1850.08,
"DIFF": -0.32
},
{
"SIDOCD": "06",
"SIDONM": "전북",
"PRODCD": "D047",
"PRICE": 1846.86,
"DIFF": 0.39
},
{
"SIDOCD": "08",
"SIDONM": "경북",
"PRODCD": "D047",
"PRICE": 1838.1,
"DIFF": -0.58
},
{
"SIDOCD": "09",
"SIDONM": "경남",
"PRODCD": "D047",
"PRICE": 1837.71,
"DIFF": -0.16
},
{
"SIDOCD": "10",
"SIDONM": "부산",
"PRODCD": "D047",
"PRICE": 1825.55,
"DIFF": -0.16
},
{
"SIDOCD": "11",
"SIDONM": "제주",
"PRODCD": "D047",
"PRICE": 1869.16,
"DIFF": 0.02
},
{
"SIDOCD": "14",
"SIDONM": "대구",
"PRODCD": "D047",
"PRICE": 1815.72,
"DIFF": -0.19
},
{
"SIDOCD": "15",
"SIDONM": "인천",
"PRODCD": "D047",
"PRICE": 1829.14,
"DIFF": -1.55
},
{
"SIDOCD": "17",
"SIDONM": "대전",
"PRODCD": "D047",
"PRICE": 1824.58,
"DIFF": 0.12
},
{
"SIDOCD": "18",
"SIDONM": "울산",
"PRODCD": "D047",
"PRICE": 1826.63,
"DIFF": -0.29
},
{
"SIDOCD": "19",
"SIDONM": "세종",
"PRODCD": "D047",
"PRICE": 1841.72,
"DIFF": -0.94
},
{
"SIDOCD": "20",
"SIDONM": "전남광주",
"PRODCD": "D047",
"PRICE": 1850.47,
"DIFF": -0.68
}
]
}
}