docs: spec 004 (KakaoPage source), its plan, and captured KakaoPage fixtures

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-15 14:17:16 +02:00
1 parent 80185210ac
commit 899e8a0d54
10 files changed
+255

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
---
status: approved
---
# 004 — KakaoPage source
A third source (spec 001 §4.1): covers of a [KakaoPage](https://page.kakao.com) series, comics (웹툰) and
novels (웹소설). Design approved by the user in chat on 2026-10-15. Kakao Webtoon (`webtoon.kakao.com`) is a
different site and out of scope.
## 1. Verified facts (2026-10-15)
Checked against *악역의 엔딩은 죽음뿐* (Villains Are Destined to Die; comic 54845189, novel 52654302) and
*울프 인더 하우스 [19세 완전판]* (63659962, 19+). Fixtures in `test/fixtures/kakaopage/` and
`test/fixtures/wayback/kakaopage-*`.
- **Pages are rendered in the browser.** `page.kakao.com/content/<id>` is an 11 KB shell with a generic
`og:image`; the data comes from
`GET https://bff-page.kakao.com/api/gateway/api/v1/content/overview?series_id=<id>`.
- **That endpoint needs a `page.kakao.com` Referer (or Origin)**; without one it answers 403. It answers 19+
series without a login.
- **Its `result.content`:** `series_id`, `title`, `category` (`웹툰` / `웹소설`), `age_grade` (0, 12, 15, 19),
`lang` (`ko`), `thumbnail` (portrait key, e.g. 720×1030), `land_thumbnail` (landscape key, 540×370; may be null).
An unknown id answers with an error (`상품 정보를 찾을 수 없습니다`, "product not found").
- **Images:** `https://page-images.kakaoentcdn.com/download/resource?kid=<key>&filename=o1` is the original
(`th2`, `th3` and `/dims/resize/…` are smaller). No Referer needed. Older pages use `dn-img-page.kakao.com` with
the same query; old keys answer on the new host.
- **Wayback:** `page.kakao.com/home?seriesId=<id>` (the old address, 2020–2022) and `page.kakao.com/content/<id>`
(2022 on) are captured server-rendered. Every capture's `og:image` is this series' image (landscape in 2020–22,
portrait in 2024). 2020 captures also hold `props.initialState.series.series.thumbnailUrl` and
`landThumbnailUrl` in `__NEXT_DATA__`. Other images on the page (`sameSeriesList`, comments) are other series
or users.
## 2. Behaviour
- **Links:** `page.kakao.com/content/<id>` (with or without a trailing path/query) and
`page.kakao.com/home?seriesId=<id>`; `m.` hosts too.
- **Series:** from the overview endpoint: `externalId` = id, `title`, `language` = `lang` (`ko`),
`canonicalUrl` = `https://page.kakao.com/content/<id>`, `mature` = `age_grade >= 15` (the rating warning),
`flags.novel`, `archiveUrls` = [`page.kakao.com/content/<id>`, `page.kakao.com/home?seriesId=<id>`].
- **Current covers:** `thumbnail` → role `poster` (the suggested main cover), `land_thumbnail` → role `banner`.
- **History:** from a capture: `og:image` (role `other`: portrait or landscape, the shape decides the type) and,
when present, the series' own `thumbnailUrl` (`poster`) and `landThumbnailUrl` (`banner`).
- **Same series:** a link is the same series when its id (`/content/<id>` or `seriesId=<id>`) equals ours exactly,
so `seriesId=548451890` is another series.
- **Image URLs:** both hosts → `page-images.kakaoentcdn.com`, `filename=o1`, the `kid` kept, any `/dims/…`
dropped.
- **Request headers per host:** `requestHeadersFor(url)` in `core/transport.ts` (User-Agent as before, plus
`Referer: https://page.kakao.com/` for `bff-page.kakao.com`). The server proxy and the userscript send them.
- **Hosts:** fetch `page.kakao.com`, `m.page.kakao.com`, `bff-page.kakao.com`, `page-images.kakaoentcdn.com`,
`dn-img-page.kakao.com`; images the last two. The userscript `@connect`s `kakao.com` and `kakaoentcdn.com`.
- **Chrome:** the link hint names "WEBTOON, Tapas or KakaoPage".
## 3. Testing
Offline unit tests on the captures: link parsing, URL normalisation, same-series, overview parsing (comic,
novel, 19+, unknown id), archived pages (2020, 2022, 2024), Wayback rows through both prefixes, request headers.
Then a real run in headless Chrome (current covers, then yearly history).
## 4. Risks
- The overview endpoint is an internal API: its shape or its Referer check can change.
- Sending a `page.kakao.com` Referer is what KakaoPage's own page sends; like the browser User-Agent for
Webtoons, it is a browser-like header, not an identity.