상황
작년 겨울 프윗 웹 서비스를 개발할 당시, 다음(daum) 뉴스 목록을 크롤링해야 하는 상황이 있었다. 뉴스의 일부를 우리 서비스에서 미리보기로 제공하고, 클릭 시 해당 뉴스 기사 사이트로 이동하도록 해야했다. 메타 태그의 존재를 몰랐던 그 때의 나는, 기사 HTML 파일 내 원하는 태그의 클래스와 아이디를 기준으로 열심히 정보를 추출했다. 그 당시엔 크롤링으로 정보를 가져온 내가 무척 대견했다. 하지만 오픈그래프의 존재를 알아버린 지금, 과거의 내가 더 대단하게 느껴진다.
OG와 메타 태그에 대해 알고 있었다면, 그리고 다음 뉴스가 메타 태그를 제공한다는 사실을 알고 있었다면 더욱 간단하게 코드를 완성했을 것이다. 훨씬 적은 시간 리소스를 들였을 것이다. 겁없이 무식하게 도전해 내 방식대로 성공시킨 과거의 내가 정말 대단하다.
과거의 나는 파이썬 기반 라이브러리 BeautifulSoup을 사용하였고, 현재 글을 쓰는 시점의 나는 Jsoup 라이브러리를 사용할 것이다. 크롤링 방법을 이해하고 있고 BeautifulSoup 라이브러리를 사용한 경험이 있다면, Jsoup 라이브러리 사용은 어렵지 않을 것이다.
OG (Open Graph)
카카오톡에 링크를 전송한 경우 위와 같은 화면을 볼 수 있다. 위 사진과 제목은, 사용자가 링크를 전송하는 시점에 해당 링크의 웹 페이지를 크롤링하여 가져올 것이다. 하지만 웹 페이지의 HTML 파일은 각기 다른 구조로 작성되어있다. 그렇기에 크롤러가 어떤 태그를 크롤링 해야할지 알 수 없다. 이 때, 단순하고 간편한 데이터를 추출하기 위한 일련의 규칙이 오픈 그래프(OG) 프로토콜이다.
즉 OG란, HTML 문서의 메타정보를 쉽게 표시하기 위해 메타정보에 해당하는 다양한 요소들을 사람들이 통일하여 사용할 수 있도록 정의해놓은 프로토콜이다. 컨텐츠의 요약된 내용이 SNS에 게시되는 데에 최적의 데이터를 가지고 갈 수 있도록 도와준다. 미리보기를 제공하는 상황이 아닌 그 반대의 상황에서도(예를 들면 카카오톡에 내가 만든 사이트를 공유했을 때 미리보기로 보여줄 데이터를 지정하는 상황) 마찬가지이다. HTML 파일에 <meta> 태그를 추가함으로써 카카오톡에서 사용자에게 미리 보여줄 데이터를 설정할 수 있다.
기본적으로 웹에서 설정해야 할 OG 메타태그는 아래와 같다. <head> 태그 내 <meta> 태그로 위치한다.
<html>
<head>
<meta property="og:[metadata]" content="">
...
</head>
</html>
추가해야 하는 태그와 추가할 수 있는 태그는 아래와 같다. 기본적으로 컨텐츠의 제목, 타입, 링크, 이미지는 정보를 제공해야 한다.
<!-- 필수 태그 -->
<meta property="og:title" content="The Rock" />
<meta property="og:type" content="video.movie" />
<meta property="og:url" content="https://www.imdb.com/title/tt0117500/" />
<meta property="og:image" content="https://ia.media-imdb.com/images/rock.jpg" />
<!-- 필수는 아니지만, 추가 가능한 태그 -->
<meta property="og:description" content="Description Here">
<meta property="og:site_name" content="Site Name">
<meta property="og:locale" content="en_US">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
Jsoup으로 메타 태그 이미지 크롤링하기
다음(daum) 뉴스 기사에서 메타데이터로 제공하는 이미지를 추출하기 위해 웹 페이지를 크롤링하겠다!
크롤링을 위해 Jsoup 라이브러리를 사용하였다. Jsoup은 자바 HTML 파서 라이브러리로 파이썬의 BeautifulSoup과 같이 크롤링에 많이 사용된다. 작성한 코드는 아래와 같다. 원하는 웹 페이지에 접근하여 property="og:image" 속성을 가진 meta 태그의 content 속성을 가져오는 코드이다.
Document document = Jsoup.connect("https://v.daum.net/v/20240731193413692").get();
Element head = document.head();
Elements tags = head.getElementsByTag("meta");
image = tags.stream()
.filter(tag -> tag.hasAttr("property"))
.filter(tag -> tag.attribute("property").getValue().equals("og:image"))
.map(tag -> tag.attribute("content").getValue())
.toList().get(0);
> [아래] 이해를 돕기 위해 나이브하게 작성한 코드
Document document = Jsoup.connect("https://v.daum.net/v/20240731193413692").get();
Element head = document.head();
Elements tags = head.getElementsByTag("meta");
for (Element tag : tags) {
if (tag.hasAttr("property")) {
Attribute property = tag.attribute("property");
String propertyValue = property.getValue();
if (propertyValue.equals("og:image")) {
image = tag.attribute("content").getValue();
}
}
}
이제 두근두근 개발 중인 서비스 총대마켓에 적용해보자. 🧚
출처
OG 태그
https://ogp.me/
https://developers.facebook.com/docs/sharing/webmasters#markup
Jsoup
https://jsoup.org/
'⛳️ 공동구매 서비스 총대마켓' 카테고리의 다른 글
쿼리 최적화와 인덱스로 API Latency 30배 개선하기 (3) | 2024.11.15 |
---|---|
개발 환경 CI/CD 파이프라인 구축기 | Github Actions, Self-hosted Runner, Docker 기술 선택 이유 (0) | 2024.08.31 |
[협업] 한 달 간의 고진감래 (0) | 2024.07.26 |
CI/CD란 | Github Actions 사용해보기 (3) | 2024.07.22 |
문서화 도구 Swagger vs Spring REST Docs (2) | 2024.07.18 |