오늘은 SNS(Reddit, DCinside) model과 serializer, service을 작성했다.
그래서 먼저 Reddit의 공식 RSS로 가져오는 데이터를 살펴보기로했다
왜냐하면, 거기서 자료를 가지고 와야하니까 어떤 형식으로 보내주는지 알아보기위해 테스트rss 주소를 받아 확인해보니
너무 읽기가 어려웠다
</subtitle><title>r/Apple: 비공식 애플 커뮤니티</title><entry><author><name>/u/AutoModerator</name><uri>https://www.reddit.com/user/AutoModerator</uri></author><category term="apple" label="r/apple"/><content type="html"><!-- SC_OFF --><div class="md"><p><a href="/r/Apple">/r/Apple</a>의 일일 조언 스레드에 오신 것을 환영합니다. 이 게시판은 Apple 소프트웨어 및 하드웨어 관련 기술적인 조언을 구하거나, Apple 제품 구매 또는 판매에 대한 질문을 하거나, 기타 간단한 질문을 게시하는 데 사용할 수 있습니다.</p> <p>답변이 필요한 질문이 있으신가요? 마음껏 질문하세요! 사이드바에 있는 규칙을 준수해 주시기 바랍니다.</p> <p>지원을 위해 Discord 및 IRC 채팅방에 참여하세요.</p> <ul> <li><a href="https://discord.gg/apple"></a> Discord</a> <li> <a href="https://kiwiirc.com/client/irc.snoonet.org/apple?nick=CHANGE_ME"></a> IRC</a> <ul> <p>참고: 편의를 위해 댓글은 최신순으로 정렬되어 있습니다.</p> <p><a href="https://www.reddit.com/r/apple/search?q=author%3A%22AutoModerator%22+title%3A%22Daily+Advice+Thread%22+or+title%3A%22Daily+Tech+Support+Thread%22&sort=new&t=all">여기에 이전의 모든 일일 조언 스레드 아카이브가 있습니다.</a> 브라우저에서 보는 것이 가장 좋습니다. 모바일에서는 검색창에 [작성자:"AutoModerator" 제목:"일일 조언 스레드"]를 입력하세요. 또는 제목:"일일 기술 지원 스레드"] (대괄호 없이, 제목과 작성자 주위에 따옴표를 포함하여 입력하세요.)<p>><strong>일일 조언 스레드는 매일 오전 6시에 게시됩니다.</p>오전 0시(미국 동부 표준시)에 새 글이 올라오면 이전 글은 보관됩니다. 이 시간이 가까워지면 새 글이 올라올 때까지 기다렸다가 질문을 올리는 것이 가장 빠른 답변을 받을 수 있습니다. <span><a href="https://www.reddit.com/r/apple/comments/1oalu41/daily_advice_thread_october_19_2025/">[link]</a></span>   <span><a href="https://www.reddit.com/r/apple/comments/1oalu41/daily_advice_thread_october_19_2025/">[댓글]</a></span></content><id>t3_1oalu41</id><link href="https://www.reddit.com/r/apple/comments/1oalu41/daily_advice_thread_october_19_2025/" /><updated>2025-10-19T10:01:37+00:00</updated><published>2025-10-19T10:01:37+00:00</published>
이런 형태로 들어오는데 이걸 일단 잘 읽기 위해 pprint를 통해
{'entries': [{'author': {'name': '/u/AutoModerator', 'uri': 'https://www.reddit.com/user/AutoModerator'},
'categories': [{'label': 'r/apple', 'term': 'apple'}],
'content': '<!-- SC_OFF --><div class="md"><p>Welcome to the Daily Advice Thread for <a '
'href="/r/Apple">/r/Apple</a>. This thread can be used to ask for technical advice regarding '
'Apple software and hardware, to ask questions regarding the buying or selling of Apple '
'products or to post other short questions.</p> <p>Have a question you need answered? Ask '
'away! Please remember to adhere to our rules, which can be found in the sidebar.</p> <p>Join '
'our Discord and IRC chat rooms for support:</p> <ul> <li><a '
'href="https://discord.gg/apple">Discord</a></li> <li><a '
'href="https://kiwiirc.com/client/irc.snoonet.org/apple?nick=CHANGE_ME">IRC</a></li> </ul> '
'<p>Note: Comments are sorted by /new for your convenience.</p> <p><a '
'href="https://www.reddit.com/r/apple/search?q=author%3A%22AutoModerator%22+title%3A%22Daily+Advice+Thread%22+or+title%3A%22Daily+Tech+Support+Thread%22&sort=new&t=all">Here '
'is an archive</a> of all previous Daily Advice Threads. This is best viewed on a browser. If '
'on mobile, type in the search bar [author:"AutoModerator" title:"Daily Advice '
'Thread" or title:"Daily Tech Support Thread"] (without the brackets, and '
'including the quotation marks around the titles and author.)</p> <p><strong>The Daily Advice '
'Thread is posted each day at 06:00 AM EST (</strong><a '
'href="https://www.wolframalpha.com/input/?i=6+AM+USA+EST">Click HERE for other '
'timezones</a><strong>) and then the old one is archived.</strong> It is advised to wait for '
'the new thread to post your question if this time is nearing for quickest answer time.</p> '
'</div><!-- SC_ON -->   submitted by   <a '
'href="https://www.reddit.com/user/AutoModerator"> /u/AutoModerator </a> <br/> <span><a '
'href="https://www.reddit.com/r/apple/comments/1oalu41/daily_advice_thread_october_19_2025/">[link]</a></span> '
'  <span><a '
'href="https://www.reddit.com/r/apple/comments/1oalu41/daily_advice_thread_october_19_2025/">[comments]</a></span>',
'content_type': 'html',
'id': 't3_1oalu41',
'link': 'https://www.reddit.com/r/apple/comments/1oalu41/daily_advice_thread_october_19_2025/',
'published': '2025-10-19T10:01:37+00:00',
'title': 'Daily Advice Thread - October 19, 2025',
'updated': '2025-10-19T10:01:37+00:00'}],
'feed_info': {'id': '/r/apple.rss',
'link': 'https://www.reddit.com/r/apple',
'subtitle': 'An unofficial community about Apple and all of its devices and software.',
'title': 'r/Apple: Unofficial Apple Community',
'updated': '2025-12-10T10:14:47+00:00'}}
그래도 알아볼 수 있을정도로 만든 다음에 이를 토대로 model을 작성했다.
먼저 모델은
정리하자면 SocialMediaSource는 소셜 미디어 소스 정보 모델이며
- 플랫폼 타입 (reddit, dcinside)
- 플랫폼별 식별자 (Reddit: subreddit 이름, DC Inside: 갤러리 이름)
- 표시 이름, 수집 URL, 소스 타입 (RSS, API, 웹 스크래핑)
- 수집 주기, 마지막 수집 시간, API 인증 정보 등이 있고
정리하자면 SocialMediaPost는 소셜 미디어 게시물 모델로
- 공통 필드: title, content, author, published_at, collected_at
- 메트릭 필드: likes_count, comments_count, shares_count, views_count
- Reddit 전용 필드: subreddit, upvotes, downvotes, score, thumbnail_url
- DC Inside 전용 필드: gall_name, post_num, ip, images
- 메타데이터: raw_data (JSON), is_processed
serializer는... 너무 글이 길어길 것 같아 생략하고 간단하게 작성하겠다.
- SocialMediaSourceSerializer: 소셜 미디어 소스 정보 직렬화
- BaseSocialMediaPostSerializer: 소셜 미디어 게시물 기본 Serializer
- 공통 필드와 메서드 정의
- source_detail, source_name, platform 등 추가 필드 제공
- RedditPostSerializer: Reddit 게시물 전용 Serializer
- Reddit 특화 필드와 검증 로직 포함
- DCInsidePostSerializer: DC Inside 게시물 전용 Serializer
- DC Inside 특화 필드와 검증 로직 포함
로 Base로 쓰일 Serializer와 각 SNS의 Serializer로 나뉘어서 진행했다.
1개의 Serializer로 통합하지 않은 이유는
- DB의 관점에서 봤을때 추후 많은 데이터를 가지고 분석을 해야하는데 그때마다 JOIN하면서 데이터를 가지고오는거 자체가 효율이 떨어짐과 동시에 ORM 활용이 용이하다는 점
- SNS가 2개 뿐이라 Reddit에서 사용하지않는 dcinside 데이터는 NULL값으로 저장이 되는데 NULL값은 공간을 많이 차지하지않아 그렇게 큰 차이가 없다고 판단함.
- 개발 관점에서는 유지보수가 쉬운게 스키마가 명확하고 멍청한 내 머리로를 이해하기 쉽고 Django Admin을 지원한다.
- 검증 로직을 분리함으로써 플랫폼 별 특화된 검증 로직을 구현함으로써 명확하게 이해하기 쉽다.
- 추후 확장 시에도 BaseSerializer를 상속받아 쉽게 확장이 가능한점
- View에서도 플랫폼에 따라 적절한 Seriazlier에 맞추면 되는거라서 View에서도 더 명확하게 확인 할 수 있다.
그외 등등 이유로 Model는 통합하고 Serializer는 분리하여 개발하도록 하였다.
Service도 추가 했는데
- RedditRSSCollectorService: Reddit RSS 피드 수집 서비스
- feedparser를 사용하여 RSS 피드 파싱
- 중복 수집 방지 (URL 기반)
- 수집 작업 로그 기록
- DCInsideCollectorService: DC Inside 게시물 수집 서비스
- dcinside-python3-api를 사용하여 웹 스크래핑
- 갤러리 글 목록 및 상세 정보 수집
- 이미지 URL 및 썸네일 추출
저번에 했던 NewsArticle과 비슷하게 작성했다.
실제 동작할지는 아직 모른다..
더 중요한 내용은 아직 안했다. DCinside는 공식 RSS,API를 지원하지 않는다...
원래 계획했던 facebook, instargram 등등 많은 sns를 두고 굳이 왜 DCinside를 했냐면
facebook, instargram은 Facebook 비즈니스계정이 필수로 필요했다ㅏ...API를 쓸수가없는 상황이라 다른 SNS를 찾아보다가
웹상에서 인기있는 사이트들을 찾아보다가 디시인사이드를 찾았고 다른 검색을 해보다 Git에 크롤링을 할 수 있는 내용이 올라와있길래 clone해서 이것저것 테스트 해보고 수정 해서 내 레포지토리에 다시 올려서 import 할 수 있게 만들었다.
아래는 원본 저장소이다.
https://github.com/dobidugi/dcinside-python3-api.git
GitHub - dobidugi/dcinside-python3-api: dcinside python3 api
dcinside python3 api. Contribute to dobidugi/dcinside-python3-api development by creating an account on GitHub.
github.com
저 저장소를 clone하여 살펴보고 ai의 도움을 받아 아래와 같이 수정 및 내 레포지토리에 올려서 import 하였다.
주요 변경 사항
추가된 기능
- Selenium 기반 글 목록 가져오기 (dcapi/read/title_selenium.py)
- 봇 차단 우회를 위한 브라우저 자동화
- 헤드리스 모드 지원
- 이미지 URL 추출 기능 (dcapi/read/post.py)
- 글 내용에서 이미지 URL 자동 추출
- 로딩 GIF 필터링
제거된 기능
- 글쓰기 기능 (dcapi/write/)
- 글삭제 기능 (dcapi/delete/)
- 추천/비추천 기능 (dcapi/vote/)
3. 데이터 저장 형식
수집된 데이터는 다음 형식으로 저장됩니다.
JSON 형식
{
"gall_name": "dcbest",
"collected_at": "2025-12-10T16:27:00",
"total_posts": 51,
"posts": [
{
"post_num": "387309",
"title": "글 제목",
"writer": "작성자",
"time": "2025-12-10 16:20:00",
"view_num": "1234",
"comment_num": "56",
"up": "78",
"content": "글 내용...",
"thumbnail": "https://...",
"thumbnail_downloaded": {
"url": "https://...",
"filename": "post_387309_thumbnail.jpg",
"local_path": "dcbest_thumbnails_20251210_162700/post_387309_thumbnail.jpg"
}
}
]
}
저장되는 파일들
- JSON 파일: dcbest_posts_YYYYMMDD_HHMMSS.json - 모든 데이터를 구조화된 형식으로 저장
- 텍스트 파일: dcbest_posts_YYYYMMDD_HHMMSS.txt - 읽기 쉬운 텍스트 형식
- CSV 파일: dcbest_posts_YYYYMMDD_HHMMSS.csv - 엑셀에서 열 수 있는 형식
- 썸네일 폴더: dcbest_thumbnails_YYYYMMDD_HHMMSS/ - 각 글의 썸네일 이미지 (1개씩)
내 레포지토리 주소는
https://github.com/Limsunoh/dcinside-read-api
GitHub - Limsunoh/dcinside-read-api: DCinside의 글 읽기 및 이미지 가져오기
DCinside의 글 읽기 및 이미지 가져오기 . Contribute to Limsunoh/dcinside-read-api development by creating an account on GitHub.
github.com
로 이걸 import 하여 requirements.txt 에
git+https://github.com/Limsunoh/dcinside-read-api.git
작성하고 install -r requirements.txt를 하면
전체 수집 예제
from dcapi.read.title_selenium import main as selenium_title
import dcapi
import json
from datetime import datetime
1. 글 목록 가져오기
posts = selenium_title("dcbest", 1, 1, headless=True)
2. 각 글의 상세 정보 가져오기
all_data = []
for post in posts[1]:
detail = dcapi.read.post("dcbest", post['post_num'])
all_data.append(detail)
3. JSON으로 저장
with open('dcbest_posts.json', 'w', encoding='utf-8') as f:
json.dump({
'collected_at': datetime.now().isoformat(),
'posts': all_data
}, f, ensure_ascii=False, indent=2)
로 사용 할 수 있다.
위의 model과 serializer도 dcinside의 양식을 합쳐서 작성하는것으로 수정했다.
다음엔 비동기 방식으로 사용하는 tasks.py랑 view.py를 작성하고 테스트까지 해보려고 한다.
'AI_RSS_트래픽 프로젝트' 카테고리의 다른 글
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(13) 트러블슈팅 (0) | 2025.12.17 |
|---|---|
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(12) 데이터 수집(6) (1) | 2025.12.16 |
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(10) 데이터 수집(4) (0) | 2025.12.08 |
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(9) 데이터 수집(3) (0) | 2025.12.03 |
| 모르는 상태로 하는 RSS&분석&RAG 프로젝트(8) 데이터 수집(2) (1) | 2025.12.02 |