7. 3. 프로젝트 소개
기능
-사용자가 입력한 해시태그 기반으로
인스타툰을 추천 받을 수 있는 서비스
-새로 등록된 인스타툰 추천
-인기 급상승 인스타툰 추천
-인기 인스타툰 추천
8. DATA COLLECT STORE ANALYZE OUTPUT
게시물
게시물
게시물
4. 엔지니어링 플로우
JSON CONNECTOR ELASTIC SEARCH
-HADOOP
CHATBOT
9. {
"key": "https:////w.instagram.com/p/CbrdaDgrJ-T/",
"caption": "Photo by 바찌(Bazzii) on March 29, 2022. May be an illustration of text that
says '보고시포 つC'.",
"img_url": "https://scontent-ssn1-1.cdninstagram.com/v/t51.2885-
15/277401320_307999701402649_4648922632395690540_n.webp?stp=dst-jpg_e35&_nc_ht=scontent-
ssn1-1.cdninstagram.com&_nc_cat=101&_nc_ohc=meBBBHrruEcAX8AC46i&edm=ABZsPhsBAAAA&ccb=7-
4&ig_cache_key=MjgwNDQ2NDUyNjc5Mjg5MjMwNw%3D%3D.2-ccb7-4&oh=00_AT9Jz1MLBKiv4uBpMDeE-
7T6mMFJeZPVwQGqQSfun_D8xA&oe=6248B300&_nc_sid=4efc9f", "username": "/_bazzii_",
"description": "보고싶은 두부~💛💜nn(두부 이모티콘은 네이버 오지큐 마켓과 라인, 스티팝
등 에서 판매 중 입니다. 프로필 링크 클릭 하시면 구매 가능 하세용~😊)", "hashtags": [
"이모티콘", "emoticon", "스티커", "라인", "line", "ogq", "linesticker", "ogqsticker",
"귀여운", "cute", "캐릭터", "이모티콘출시", "드로잉", "그림툰", "인스타툰", "그림",
"프로크리에이트", "procreate", "이모티콘작가", "그림스타그램", "일러스트", "오지큐스티커",
"illust", "drowingart", "drowings", "artwork", "보고시포", "아이패드드로잉", "", "" ],
"datetime": "2022-03-29T07:17:25.000Z",
"likes": "4",
"comments": [ { "author": "pro.game9121", "comment": "Love it dm 💙➡️ @art_colle.ction" },
{ "author": "royal_batlle", "comment": "DM IT 💫 @vission.arts 4M+" }, { "author":
"/_bazzii_", "comment": "❤️" }, { "author": "/_bazzii_", "comment": "@/_bazzii_ #이모티콘
#emoticon #스티커 #라인 #line #ogq #linesticker #ogqsticker #귀여운 #cute #캐릭터
#이모티콘출시 #드로잉 #그림툰 #인스타툰 #그림 #프로크리에이트 #procreate #이모티콘작가
#그림스타그램 #일러스트 #오지큐스티커 #illust #drowingart #drowings #artwork #보고시포
#아이패드드로잉 #イラスト #ドローイング" } ]
}
•key : 게시글 주소
•caption : 사진에 대한 설명
•img_url : 게시글의 이미지 url
•username : 게시글을 올린 사용자 아이디
•description : 게시글의 내용
•hashtags : 사용자가 댓글 또는 게시글에 작성한
해시태그를 태그 별로 구분한 것
•datetime : 게시글을 올린 날짜와 시간
•likes : 좋아요 수
•comments : 댓글과 대댓글
인스타그램 크롤링 예시
5. 데이터 수집
10. Kafka 란 무엇인가?
• 대규모 메시지 데이터를 빠르게 처리하도록
개발된 메시징 플랫폼
• 빅데이터를 분석할 때 여러 스토리지와
분석 시스템에 데이터를 연결하기 위한 필수 도구
6. Kafka
11. 6. Kafka
1. 인스타그램 크롤링을 통해 저장된
json 형식의 파일을 읽어 오는 역할
2. 여러 개의 해시태그로 크롤링 된 데이터를 필요한
기능을 기반으로 통합하는 역할
3. Elastic Search로 효율적으로 전송하는 역할
kafka 를 통해 구현하고자 한 기능
Kafka Topic
12. • 높은 확장성과 안정성을 가짐
• 빠른 데이터 처리 가능
• 많은 양의 데이터 분산 처리 가능
• 카프카의 메시지 시스템은 하나의 토픽에 여러
producer, consumer 접근 가능
→ 메시지를 한 번 읽어도 메세지가 토픽에서
제거되지 않기 때문에 기능별로 중복되는
데이터가 필요한 경우 효율적 처리 가능
(높은 처리량을 위한 메시지 최적화)
Kafka를 사용한 이유
6. Kafka
13. • single broker 사용
• Topic 1 : 전체 카테고리가 포함된 인스타툰
• Topic 2 : 카테고리별 인스타툰
Kafka Cluster
6. Kafka
14. Topic 1
• 카테고리 구분 없이 인스타툰과 관련된 해시태그를 사용하여 크롤링한
데이터를 수집한 데이터를 불러오는 역할
Topic 2
• 사랑,가족 / 캐릭터,동물 / 취미 / 직업 / 감성 다섯가지의 카테고리로
나누고, 카테고리별로 나누어 게시물을 수집한 데이터를 불러오는 역할
• 각 토픽은 인기게시물과 최신게시물로 나누어진 파티션에 저장되고,
topic2는 카테코리 별로 2개의 파티션을 가지게 되는 구조
6. Kafka
15. 6. Kafka
Consumer
• 인기 인스타툰, 급상승 인스타툰, 최신 인스타툰,
해시태그 기반 추천 4개로 이루어 짐
• 서비스에 필요한 기능별로 나누어 구성 함
• 이를 바탕으로 Consumer는 브로커에 저장된
데이터로부터 각 기능에 사용될 데이터를 받아 옴
16. path_dir = './output’
# Producer 1
file_path = os.path.join(path_dir,"p1_hot.json")
with open(file_path, 'r') as file:
data = json.load(file)
p1_all.send('t1_all', value=data, partition=1)
p1_all.flush()
file_path = os.path.join(path_dir,"p1_recent.json")
with open(file_path, 'r') as file:
data = json.load(file)
p1_all.send('t1_all', value=data, partition=2)
p1_all.flush()
# Producer 2 (3~6도 동일하게)
file_path = os.path.join(path_dir,"p2_hot.json")
with open(file_path, 'r') as file:
data = json.load(file)
p2_love.send('t2_category', value=data, partition=1)
p2_love.flush()
file_path = os.path.join(path_dir,"p2_recent.json")
with open(file_path, 'r') as file:
data = json.load(file)
p2_love.send('t2_category', value=data, partition=2)
p2_love.flush()
Producer 구현
Producer 1의 해시태그로 크롤링 한 게시물 정보를 저장한 파일
Partition 2의 해시태그로 크롤링 한 게시물 정보를 저장한 파일
인기 게시물은 Partition 1에, 최신 게시물은 Partition 2에 저장
인기 게시물은 Partition 1에, 최신 게시물은 Partition 2에 저장
6. Kafka
17. # topic, broker list
c1_popular = KafkaConsumer(
bootstrap_servers=['localhost:9092'],
auto_offset_reset='earliest',
enable_auto_commit=True,
group_id='1',
value_deserializer=forgiving_json_deserializer,
consumer_timeout_ms=1000
)
c1_popular.subscribe(topics=['t1_all','t2_category'])
c1_popular.assign([TopicPartition('t1_all', 1),TopicPartition('t2_category',1)])
c2_hot.subscribe(topics=['t1_all','t2_category'])
c2_hot.assign([TopicPartition('t1_all', [2]),TopicPartition('t2_category',[2,3,4,5,6])])
c3_recent.subscribe(topics=['t1_all','t2_category'])
c3_recent.assign([TopicPartition('t1_all',
[1,2]),TopicPartition('t2_category',[1,2,3,4,5,6])])
c4_hashtag.subscribe(topics=['t1_all','t2_category'])
c4_hashtag.assign([TopicPartition('t1_all',
[1,2]),TopicPartition('t2_category',[1,2,3,4,5,6])])
Consumer 구현
Consumer1은 Topic1의 1번 Partition(인기 게시물) 과
Topic 2의 1번 Partition(인기 게시물)을 구독(Subscribe)
6. Kafka
18. JSON 기반의 비정형 데이터 분산 검색 및 분석을 지원
-> 카프카로부터 크롤링한 json 데이터를 받아 전처리
7. Elastic Search
19. 7. Elastic Search
Elastic Search 를 통해 구현하고자 한 기능
1. 광고성 데이터가 삽입 되지 않도록 걸러내는 역할
2. 중복된 데이터가 들어온 경우 전의 데이터와 비교하여
증가된 좋아요 수 변동 수치를 새 변수에 저장하는 역할
3. string 형식인 좋아요 int 형으로 변환하는 변수의
타입을 변환하는 역할
21. 7. Elastic Search
광고성 데이터를 제외한 데이터 삽입
if __name__ == '__main__':
endpoint_url = "127.0.0.1"
endpoint_port = 9200
analysis_index: str = "instagram_toon_crawling"
es: elasticsearch.client.Elasticsearch = Elasticsearch(hosts=endpoint_url ,
port=endpoint_port ,
timeout=30 ,
max_retries=30 ,
retry_on_timeout=True)
for instagram_data in instagram_data_list2:
data=instagram_data
_hashtags = data["hashtags"]
# 들어온 데이터에서 다음과 같은 해시태그가 있을 경우 광고성 데이터로 판단하여 es에
삽입하지 않는다.
if ("좋아요반사" or "좋반" or "셀스타그램" or "국비지원" or "무료교육" or "다꾸" or
"소품샵" or "스꾸" or "좋테") in _hashtags:
print("광고 데이터는 삽입하지 않습니다.")
else :
put_instagram_crawling_data(es=es , data=instagram_data
인스타그램에서 많이 사용되는 광고성 해시태그를 분석하여
광고성 해시태그를 제외한 해시태그 중 유사도 측정
22. 7. Elastic Search
중복 데이터 삽입 시 좋아요 변동 수치 파악
if es.exists(index=analysis_index , id=_id , doc_type="_doc" , pretty=True):
print("여기에서는 이미 데이터가 있기 때문에 데이터를 업데이트만 한다")
_new=es.search(index=analysis_index, body={"query":{"match":{"_id":_id}}})
_newlist=_new['hits']['hits'] #기존 데이터 결과
_newlike=str(_newlist).find("'likes'") #기존 데이터 좋아요 수
print(_newlike)
_newlike=str(_newlist)[_newlike+10:_newlike+15]
_newlike=int(_newlike.replace("'"," ").replace(","," ").replace("}","
").replace("]"," ").replace("}}]"," "))
_number=int(data["likes"])-_newlike
들어온 데이터가 이미 존재할 경우 새로 들어온 데이터의 좋아요 수에서
기존 데이터의 좋아요 수를 빼서 변동 수치 파악
23. 7. Elastic Search
변수 타입 변환
if(data["likes"]==0):
_likes=0
else:
_likes = utils.unquote(data["likes"]).replace(",","")
data["likes"]=_likes
, 와 함께 String 타입인 좋아요 수 데이터를
,를 제거하여 정수형으로 변환
24. Apache Spark는 SQL, 스트리밍, 머신러닝 및 그래프 처리를 위한
기본 제공 모듈이 있는 대규모 데이터 처리용 통합 분석 엔진
Spark 란?
8. Spark
25. Spark 사용 이유
8. Spark
• Elastic Search 에서 전처리를 마친 데이터를 빠른 속도로 분석
• Spark SQL을 통해 구조화된 데이터를 사용
• Spark SQL의 DataFrame API를 통해 Query문을 활용한
질의를 수행하기 위함
26. Spark를 통해 구현하고자 한 기능
8. Spark
1. 보유한 게시글 데이터 중 좋아요가 가장 많은 인기 게시물 추천 기능
2. 일정 기간 동안 좋아요 수가 많이 상승한 급상승 인기 게시물 추천 기능
3. 최신 게시물 추천 기능
4. 사용자가 입력한 키워드와 유사한 내용의 게시물 추천 기능
27. 8. Spark 인기 게시물 추천
Elastic Search를 통해 전송된 인기 게시물 데이터 중에서
좋아요 수가 가장 많은 게시물 5개를 보여주는 역할
좋아요 개수를 기준으로 정렬
key likes …
“https://www.instagram.com/p/CgNWejLhIhb/"
3554 …
“https://www.instagram.com/p/CgMH_XwPIai/"
306 …
“https://www.instagram.com/p/CgImC0DLqfd/"
229 …
“https://www.instagram.com/p/CgMK8oaP-Ti/"
25 …
“https://www.instagram.com/p/CgMwKTGhuvg/"
18 …
{ "key": "https:////w.instagram.com/p/CgImC0DLqfd/",
"likes": "299",
"number": 2,
"hashtags": [ "ENFP ","istj ", "엔프피 ", "잇티제 ",
"mbti", "연서 ", "연더랜드 ", "이모티콘", "인스타툰 ",
"생활툰 ", "그림일기 ", "만화일기 ", "그림스타그램 ",
"만화", "모두의귀요미 ", "커플이모티콘 ", "커플스타그램 ",
"유니콘 ", "유니몽 ", "엔프피만화 ", "잇티제만화 ",
"mbti만화"],
"datetime": "2022-07-18T00:56:26.000Z",
"description": "#ENFP #istj #엔프피 #잇티제 #mbtinnISTJ는
최선을 다해 위로해 주고 있습니다/.n흑흑/. ISTJ의 힘겨운
위로에 또 감동받고 울컥해버리는 ENFPn혹시 주변에 저런
잇티제 친구가 있다면 당신은 정말 사랑받고 있는
겁니다.n그리고 감동덩어리 엔프피😍 😆 사랑해" },
{ "key": "https://www.instagram.com/p/CgMwKTGhuvg/",
"likes": "18",
"number": 0,
"hashtags": [ "커플툰 ", "연애툰 ", "일상툰 ", "인스타툰",
"연애스타그램 ", "커플스타그램 ", "럽스타그램 ", "동갑내기
", "동갑커플 ", "첫만남", "남자친구 ", "여자친구 " ],
"datetime": "2022-07-19T15:41:48.000Z",
"description": "우린 자만추였지..?ˀnn#커플툰 #연애툰
#일상툰 #인스타툰n#연애스타그램 #커플스타그램 #럽스타그램
#동갑내기 #동갑커플 #첫만남n#남자친구 #여자친구 #-18툰💗"
},
{
"key": "https://www.instagram.com/p/CgMK8oaP-Ti/",
"likes": "25",
"number": 8,
"hashtags": [ "점심 ", "인스타툰 ", "요리툰 ", "에세이 ", "생활툰
", "만화 ", "카툰 ", "샐러드 ", "레시피 ", "일상툰 ", "그림 ",
"감성 ", "샐러드레시피 ", "낭만 ", "점심메뉴 ", "webtoon ",
"instatoons ", "요리레시피 ", "illust ", "artwork ", "doodle ",
"아이패드그림 ", "샐러드추천 ", "아이패드만화 ", "cartoon"],
"datetime": "2022-07-19T10:16:38.000Z",
"description": "입맛이 뚝 떨어진 여름에 좋은 샐러드와 소스
레시피에요! 🥗nn소스가 정말 맛있으니 꼭 추천드려요!
😋nnhttps://grafolio.naver.com/works/2290630nn불 쓸 의욕조차
생기지 않는 눅눅하고 더운 여름에 샐러드로 점심을 먹으면 더위도
가시고 편안한 느낌까지 들어요.nn오리엔탈 소스 외에도 가볍게 꿀을
뿌려서 먹거나 유자 드레이싱을 만들어도 좋답니다.
🥗👏👏nn+소스의 메인 포인트는 다진 양파에요!n아삭함이 살아있는
양파가 새콤 짭짤한 소스를 잔뜩 머금어서 정말 상쾌한 기분이
난답니다. (때문에 너무 대량으로 만들어두면 양파가 물러질 수
있어요.)"
},
{ "key": "https://www.instagram.com/p/CgMH_XwPIai/",
"likes": "306",
"number": 6,
"hashtags": [ "조하툰", "일상툰", "생활툰",
"인스타툰", "일상만화", "공감툰", "개그툰",
"그림일기" ],
"datetime": "2022-07-19T09:50:47.000Z",
"description": "💖노안…n이 아닌 어른스러운
나…n.n.n.nn#조하툰#일상툰#생활툰#인스타툰#일상만화#공감툰#
개그툰#그림일기" }
{ "key": "https://www.instagram.com/p/CgNWejLhIhb/",
"likes": "3554",
"number": 302,
"hashtags": [ "인스타툰 ", "그림일기 ", "일상툰 ", "공감툰
", "유머툰 ", "힐링툰 ", "개그툰 ", "데일리툰 ", "웹툰 ",
"일러스트 ", "일러스트레이션 ", "졸전 ", "졸업전시" ],
"datetime": "2022-07-19T21:16:37.000Z",
"description": "뽀꼬의 졸전썰 (5/10)n누가봐도
어깨빵n.n만화에 등장하는 캐릭터에 대한 과도한 비난은
삼가주세요🙏n.n다음화는..내일…? 아님 오늘..?n댓글
많으면 빨리올게요.. 내 원동력💕nn은유적인 표현이지
실제로 제 어깨를 치지 않았습니다 ㅎㅎn카톡으로 시비걸거나
개인정보 유출 등이었슴.." },
28. 8. Spark 급상승 게시물 추천
이전 배치와 비교하여 좋아요 수가 가장 많이 증가한
5개의 게시물을 보여주는 역할
{ "key": "https:////w.instagram.com/p/CgImC0DLqfd/",
"likes": "299",
"number": 2,
"hashtags": [ "ENFP ","istj ", "엔프피 ", "잇티제 ", "mbti",
"연서 ", "연더랜드 ", "이모티콘", "인스타툰 ", "생활툰 ",
"그림일기 ", "만화일기 ", "그림스타그램 ", "만화", "모두의귀요미
", "커플이모티콘 ", "커플스타그램 ", "유니콘 ", "유니몽 ",
"엔프피만화 ", "잇티제만화 ", "mbti만화"],
"datetime": "2022-07-18T00:56:26.000Z",
"description": "#ENFP #istj #엔프피 #잇티제 #mbtinnISTJ는 최선을
다해 위로해 주고 있습니다/.n흑흑/. ISTJ의 힘겨운 위로에 또
감동받고 울컥해버리는 ENFPn혹시 주변에 저런 잇티제 친구가 있다면
당신은 정말 사랑받고 있는 겁니다.n그리고 감동덩어리 엔프피😍 😆
사랑해" },
{ "key": "https://www.instagram.com/p/CgMwKTGhuvg/",
"likes": "18",
"number": 0,
"hashtags": [ "커플툰 ", "연애툰 ", "일상툰 ", "인스타툰",
"연애스타그램 ", "커플스타그램 ", "럽스타그램 ", "동갑내기 ",
"동갑커플 ", "첫만남", "남자친구 ", "여자친구 " ],
"datetime": "2022-07-19T15:41:48.000Z",
"description": "우린 자만추였지..?ˀnn#커플툰 #연애툰 #일상툰
#인스타툰n#연애스타그램 #커플스타그램 #럽스타그램 #동갑내기
#동갑커플 #첫만남n#남자친구 #여자친구 #-18툰💗" },
{
"key": "https://www.instagram.com/p/CgMK8oaP-Ti/",
"likes": "25",
"number": 8,
"hashtags": [ "점심 ", "인스타툰 ", "요리툰 ", "에세이 ", "생활툰
", "만화 ", "카툰 ", "샐러드 ", "레시피 ", "일상툰 ", "그림 ",
"감성 ", "샐러드레시피 ", "낭만 ", "점심메뉴 ", "webtoon ",
"instatoons ", "요리레시피 ", "illust ", "artwork ", "doodle ",
"아이패드그림 ", "샐러드추천 ", "아이패드만화 ", "cartoon"],
"datetime": "2022-07-19T10:16:38.000Z",
"description": "입맛이 뚝 떨어진 여름에 좋은 샐러드와 소스
레시피에요! 🥗nn소스가 정말 맛있으니 꼭 추천드려요!
😋nnhttps://grafolio.naver.com/works/2290630nn불 쓸 의욕조차
생기지 않는 눅눅하고 더운 여름에 샐러드로 점심을 먹으면 더위도
가시고 편안한 느낌까지 들어요.nn오리엔탈 소스 외에도 가볍게 꿀을
뿌려서 먹거나 유자 드레이싱을 만들어도 좋답니다.
🥗👏👏nn+소스의 메인 포인트는 다진 양파에요!n아삭함이 살아있는
양파가 새콤 짭짤한 소스를 잔뜩 머금어서 정말 상쾌한 기분이
난답니다. (때문에 너무 대량으로 만들어두면 양파가 물러질 수
있어요.)"
},
{ "key": "https://www.instagram.com/p/CgMH_XwPIai/",
"likes": "306",
"number": 6,
"hashtags": [ "조하툰", "일상툰", "생활툰", "인스타툰",
"일상만화", "공감툰", "개그툰", "그림일기" ],
"datetime": "2022-07-19T09:50:47.000Z",
"description": "💖노안…n이 아닌 어른스러운
나…n.n.n.nn#조하툰#일상툰#생활툰#인스타툰#일상만화#공감툰#개그툰#
그림일기" }
{ "key": "https://www.instagram.com/p/CgNWejLhIhb/",
"likes": "3554",
"number": 302,
"hashtags": [ "인스타툰 ", "그림일기 ", "일상툰 ", "공감툰 ",
"유머툰 ", "힐링툰 ", "개그툰 ", "데일리툰 ", "웹툰 ", "일러스트
", "일러스트레이션 ", "졸전 ", "졸업전시" ],
"datetime": "2022-07-19T21:16:37.000Z",
"description": "뽀꼬의 졸전썰 (5/10)n누가봐도 어깨빵n.n만화에
등장하는 캐릭터에 대한 과도한 비난은
삼가주세요🙏n.n다음화는..내일…? 아님 오늘..?n댓글 많으면
빨리올게요.. 내 원동력💕nn은유적인 표현이지 실제로 제 어깨를
치지 않았습니다 ㅎㅎn카톡으로 시비걸거나 개인정보 유출
등이었슴.." },
증가한 좋아요 개수를 기준으로 정렬
key number …
“https://www.instagram.com/p/CgNWejLhIhb/"
302 …
“https://www.instagram.com/p/CgMK8oaP-Ti/"
8 …
“https://www.instagram.com/p/CgMH_XwPIai/"
6 …
“https://www.instagram.com/p/CgImC0DLqfd/"
2 …
“https://www.instagram.com/p/CgMwKTGhuvg/"
0 …