* 웹스크래핑에 대해서는 깊게 다루지 않습니다.
블로그에서 웹스크래핑에 대한 정보를 많이 다뤘기 때문에, 그 내용에 이어서 장고로 기반을 갖추면 좋은 이유, 그리고 어떻게 하면 장고의 데이터베이스에 우리가 원하는 데이터를 예쁘게 담을 수 있는 지에 대해 초점을 맞추겠다.
우선 ORM이라는 것이 있다. Object Relational Mapping, 즉 객체-관계 매핑이라는 것은 객체 지향 패러다임을 이용해 데이터베이스에서 데이터를 쿼리하고 조작할 수 있는 기술이다. 데이터를 효율적, 생산적으로 저장할 수 있는 데이터베이스, 그리고 그들의 언어인 SQL은 우리가 평소에 작성하는 프로그래밍 언어들과 접근 방법 등에서 차이가 있고, 비즈니스 로직에 의해 이것들을 다룰 때 그 복잡성이 깊어질 수록 프로그래밍 언어 - 데이터베이스 언어 사이의 간극이 벌어지는 상황을 최소화하고, 우리가 실제로 만나고 사용하고 동작하는 현실의 객체의 동작 방식과 유사하게 프로그램을 작성하는 객체 지향적 접근 방식으로 좀 더 현실의 언어로 프로그래밍을 하고, 또 프로그래밍의 언어에 더 집중한 코딩을 할 수 있게 해준다.
ORM을 사용하면 여러가지 장점이 있다.
- DRY (don't repeat yourself): 코드 반복을 줄여준다.
- 복잡한 SQL 쿼리와 완전히 분리되어 비즈니스 로직에 집중할 수 있다.
- 디버깅이 힘든 SQL의 문제점을 대폭 커버합니다.
- 트랜잭션을 구현하는 것이 훨씬 쉽습니다.
- 데이터 베이스를 변경하는 등의 변화에 유연하게 대응할 수 있습니다.
개발자를 고통받게 하는 단점 역시 존재한다.
- 프로그램(프로젝트)의 무게가 무거워지고 다소 설정할 것이 생긴다.
- SQL을 직접 사용할 때보다 추상적인 만큼 약간의 성능 저하가 뒤따른다.
- 라이브러리가 어떻게 동작하는지 모르는 이상 비효율적인(탐욕적인) 알고리즘을 구현하기 쉬운 초보 개발자에 의해 복잡한 쿼리가 되거나 불필요한 조회 등이 발생할 수 있다.
파이썬의 ORM에는 대표적으로 SQLAlchemy, DJANGO ORM이 있다. 플라스크 개발을 공부할 때 SQLAlchemy를 좀 더 공부해보지 않은 것이 아쉽지만, Django ORM의 장점 역시 무궁무진하니 이쪽을 더 공부해보자.
장고 프로젝트를 생성하고, 마이그레이션을 마치고 나면, 데이터베이스가 생긴다. 그리고 이 데이터베이스에 직접 개발한 크롤러를 연결하여 데이터를 쌓으려고 하면, 에러에 부딪힌다.
장고 프로젝트에서 어떠한 동작을 하는 애플리케이션을 만들었을 때, 프로젝트에 그 사실을 알려야 한다. settings.py에 INSTALLED_APPS에 해당 프로젝트를 등록해주면 된다.
일정한 기간마다 데이터를 습득해야 하는 크롤러라면 Django-CRONTAB을 사용한다. 크론이란 특정 주기마다 동작하는 프로그램을 작성할 때 필수적인 스케줄 기능이다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crawler.apps.CrawlerConfig',
'django_crontab',
]
CRONJOBS = [
('0 * * * *', 'crawler.ranking_bot_v2.hourly'),
('10 0 * * *', 'crawler.ranking_bot_v2.daily'),
]
이런 식으로 job을 등록해주면 된다. 그리고 배포 단계에서
python manage.py crontab add
를 실행해주면 스케줄러 등록이 된다.
그리고 크롤러가 동작하는 파일 안에 django를 임포트해줘야 해당 코드의 결과물들이 장고에서 만들어주는 데이터베이스에 안정적으로 자리잡을 수 있다.
import os
from django.db import IntegrityError
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ranker.settings")
import django
if 'setup' in dir(django):
django.setup()
import requests
from crawler.models import OneStoreDL # django ORM
# 여기 위의 코드는 거의 필수적으로 들어가는 구성요소라 생각하면 된다.
def get_soup(appid):
one_url = "https://m.onestore.co.kr/mobilepoc/web/apps/appsDetail/spec.omp?prodId="+appid
from bs4 import BeautifulSoup # 위에서 임포트해줘도 되지만 이 함수에서만 사용하는 모듈이라 여기서 임포트
response = requests.get(one_url).text
return BeautifulSoup(response, "html.parser")
def get_one_store_app_download_count(date: TimeIndex, appid: str, app: App):
soup = get_soup(appid)
download = soup.select_one("li:-soup-contains('다운로드수') > span").text
d_string = soup.select_one("li:-soup-contains('출시일') > span").text
genre = soup.select_one("li:-soup-contains('장르') > span").text
volume = soup.select_one("li:-soup-contains('용량') > span").text
style = soup.select_one("#header > div > div > div.header-co-right > span").get('style')
icon_url = style.removeprefix("background-image:url(").removesuffix(")")
import datetime
array = [i for i in map(int, d_string.split("."))]
released = datetime.date(year=array[0], month=array[1], day=array[2])
d_counts = int(download.replace(",", ""))
ones_app = OneStoreDL(
date_id=date.id,
app_id=app.id,
market_appid=appid,
downloads=d_counts,
genre=genre,
volume=volume,
released=released,
icon_url=icon_url,
app_name=app_name,
)
ones_app.save()
# 장고의 ORM을 이렇게 사용한다. 객체의 프로퍼티를 설정하고 .save()를 해주기만 하면 끝
# 사용할 때에는 OneStoreDL.objects.filter(app_name="바람의나라연").first() 와 같이 사용하면 된다!
이런 식으로 코드를 작성해 주면 된다. 이제부터 장고의 프로젝트 안에서 내부적으로 동작하는 크롤러를 사용할 수 있다!! 참고로 해당 코드는 원스토어의 앱 아이디를 받아 다운로드 수 등의 수치를 크롤링하는 코드이다. 냠냠 끗
(개인 기록용이라 설명이 불친절합니다 죄송함니다)
'Python' 카테고리의 다른 글
[프로젝트후기] 모바일 어플마켓 크롤러 개발 후기 근데 슬랙봇을 곁들인 (0) | 2022.03.09 |
---|---|
[파이썬웹개발] 장고에 딱 붙고 착 붙는 데이터베이스는 무엇일까? (0) | 2022.03.01 |
[장고웹개발] 장고와 친해져 봅시다. (부제: 요즘도 장고 쓰냐) (1) | 2022.02.15 |
내 티스토리는 무슨 키워드로 많이 유입될까??? 워드클라우드 다시 맛보기 (0) | 2022.02.11 |
[파이썬으로 웹스크래핑]RSS?? 그게 이거랑 무슨 상관인데 (1) | 2022.01.12 |
댓글