rssbackend
RSS 수집기를 만들며 겪은 현실적인 문제들
"RSS 긁어서 보여주면 되지"로 시작했는데, 현실의 RSS는 생각보다 거칠었다. 이 블로그의 기술블로그 수집 기능을 만들며 겪은 것들.
1. User-Agent로 거절당한다
기본 UA로 요청하면 406/403을 주는 곳이 꽤 있다. 봇 명시 + 연락처를 넣은 UA로 바꾸면 대부분 풀린다.
const parser = new Parser({
headers: {
"User-Agent": "Mozilla/5.0 (compatible; BacktickBot/1.0; +https://backtick.blog)",
},
});
그래도 WAF가 클라우드 IP 대역을 통째로 막는 곳은 방법이 없다. 포기하고 disabled 플래그를 뒀다.
2. 같은 RSS인데 다 다르다
- 썸네일:
enclosure에 주는 곳,media:content에 주는 곳, 본문 HTML의 첫img를 파싱해야 하는 곳 - 날짜:
isoDate가 없는 피드도 있다 - 본문: CDATA에 HTML 통째로 넣는 곳, 요약만 주는 곳
결국 소스별 차이를 흡수하는 정규화 레이어가 필요하다.
function toThumbnail(item: Item): string | null {
return item.enclosure?.url
?? item.mediaContent?.$?.url
?? firstImgFrom(item.contentEncoded)
?? null;
}
3. 중복과 재수집
수집은 반드시 재실행된다(크론 겹침, 재배포, 수동 실행). 삽입을 멱등하게 만들지 않으면 피드가 도배된다. URL을 유니크 키로 upsert 하면 끝.
await prisma.externalPost.upsert({
where: { url },
update: { likes, tags }, // 변하는 메타데이터만 갱신
create: { ...post },
});
4. HTML 엔티티
"스마트" 글래스 같은 제목이 그대로 노출된다. 태그 제거 후 엔티티 디코딩까지 해야 카드가 깨끗하다.
교훈: 수집기의 본체는 fetch가 아니라 정규화와 멱등성이다.
조회 0