Django 프로젝트에서 robots.txt 파일 제공하기

2020. 02. 17 IT/컴퓨터 > Django

 

Robots.txt 는 웹페이지의 자료를 크롤링하는 검색 엔진 봇들을 위해 어떤 페이지는 정보를 수집해도 되고, 어떤 페이지는 수집을 금할 것인지 알려주는 역할을 하는 간단한 텍스트 파일이다. 검색 엔진 봇들은 홈페이지의 링크를 타고 다니면서 정보를 수집하고 이를 검색 결과에 보여 주므로 홈페이지나 블로그가 효과적으로 검색엔진의 검색 결과에 나오게 하기 위해서 설정을 잘 해 주는것이 중요할 것이다.

 

내용은 대략 알고 있었지만 사실 실제로 블로그를 만들기 전까지는 현실적으로 어떤 것이 문제가 될 만한 내용인지 와닿지는 않았다. 그런데 블로그를 도메인에 연결하고 공개를 하고 보니 한 가지 치명적인 문제가 발견되었다. 

 

이 블로그는 글 작성후에 publish 버튼을 누르기 전에는 초안 상태로 저장되어 있다가 publish 버튼을 누르면 공개되는 방식으로 만들어져 있는데, 글 작성후 내가 분명히 publish 하지 않고 초안 상태로 놔 두었는데도 어느 정도 시간이 지나면 자꾸 저절로 publish 가 되는 버그가 발견된 것이다. 자동으로 실행되는 함수같은 것을 만든 적도 없는데 왜 이런 현상이 발생하는지 고민이었다.

 

그런데 서버 로그를 보니 구글 크롤링 봇이 페이지를 들러서 publish 링크를 누르고 다니는 것 같았다. 그래서 아직 publish 되지 않은 글들의 publish 링크에 봇이 접근하지 못하도록 해야 할 필요가 생겼다. 그동안 사이트에 robots.txt 가 없었는데, 구글 봇이 발간되지 않은 글들을 모아놓은 URL에 접근할 수 없도록 해당 내용을 robots.txt에 추가해 주었다. Django 프로젝트에서는 단순히 루트 디렉토리에 robots.txt만 업로드해 놓으면 검색 엔진이 파일을 찾을수가 없고, 따로 설정을 해서 제공해야 되는 것이라서 공부한 내용을 정리해 본다. 크게 세 가지 방법이 있다.

 

#1. 간단히 해결하려면 urls.py 에 직접 robots.txt 의 내용을 써주면 된다. lambda function 을 활용. 물론 HttpResponse 를 먼저 import 해주어야 한다.

[ urls.py ]
from django.http import HttpResponse
urlpatterns = [
    ...기존path 설정
    path('robots.txt/', lambda x: HttpResponse("User-Agent: *\nDisallow:", 
         content_type="text/plain")),
]

이 방법은 파일 하나만 손대면 되어 간단하지만, robots.txt 의 규칙이 늘어나면  추가해주기가 번거롭고 urls.py 본연의 임무인 url 매핑 이외의 내용으로 파일이 너무 지저분해지는 단점이 있겠다. 원칙적으로 각각의 코드는 자기 본래의 역할에 충실하는 것이 올바른 코딩 방향이므로 이 방법은 별로 추천하고 싶지는 않다.

 

 

 

#2. Django-robots 앱을 사용하는 방법.

링크 - Django-robots documentation

robots.txt 를 관리하기 위한 전용 앱이 있다.

$ pip install django-robots 

를 입력해서 설치할 수 있고 대규모 프로젝트의 경우에는 이 앱을 사용하면 매번 robots.txt를 push 하지 않고도 편리하게 관리할 수 있다고 한다. 혼자 쓰는 블로그같은 소규모 프로젝트에는 직접 robots.txt 를 수정해 주는 정도로 충분한것같아 아직 사용해보지는 않았다. 

 

#3. 실제 robots.txt 를 작성하여 업로드후 url을 지정해 주는 방법.

우선 robots.txt를 작성하여 원하는 디렉토리에 업로드한다. urls.py에서 경로를 정해 줄 것이기 때문에 아무데나 둬도 상관 없지만, 가급적 base.html 이 있는 프로젝트의 가장 root의 template 디렉토리에 넣는것이 관리 면에서 좋겠다. robots.txt를 업로드 후 프로젝트의 메인 urls.py 에 다음과 같이 설정해준다.

[ urls.py ]
from django.views.generic import TemplateView
urlpatterns = [
    ...기존path 설정
    path('robots.txt/', TemplateView.as_view(template_name="robots.txt", 
         content_type='text/plain')),
]

일반 html template 과 다르게 타입을 plain text 로 지정해 주는것이 추가된다. root template 디렉토리가 아닌 곳에 robots.txt를 둔 경우에는 적절하게 경로를 바꿔 주면 되겠다. 함수형 view를 사용할수도 있지만 generic class based view 인 TemplateView를 이용하면 간단하다. 

robots.txt를 직접 읽어서 서빙해 주는 방식이다. 각각의 파일이 본래 목적에 맞는 동작을 하는 점에서 1번보다는 더 좋은 방식이다. 검색 규칙을 바꾸는 것도 직접 txt 파일만 수정하면 되기 때문에 편리하다. 파일의 규칙이 자주 바뀌는 경우 로컬에서 파일 수정후 서버에 push 해 줘야 하는것은 귀찮을 수도 있겠다. 하지만 이미 완성된 사이트라면 robot 검색 규칙을 바꿀 일은 별로 없을 듯.

 

이외에 사용하는 서버에 따라 직접 robots.txt를 업로드하고 서버 세팅을 변경해서 Django 를 거치지 않고 제공하는 방법도 있지만, 일을 두 번 해야 하므로 번거롭고 서버마다 세팅이 달라 일괄 적용하기 어려운 점이 있을 것이다.

이 블로그에서는 #3의 방법으로 사용중이다. robots.txt를 설정해주면 검색엔진이 적절히 자료를 수집하는데 도움을 주고 불필요한 수집이나 오동작을 방지할 수 있으므로 어느 홈페이지든지 적절하게 설정해 주는것이 좋겠다.

 

다만 robots.txt 의 내용은 어디까지나 로봇에게 일러 주는 권장사항일 뿐 기술적으로 접근을 차단하는 것은 아니다. 정상적인 로봇이라면 권장사항을 준수하면서 크롤링하겠지만 악성코드의 경우 이를 무시하고 돌아다닐 수도 있으므로 백엔드에서 근본적으로 접근을 차단할 방법은 별도로 강구해야 할 것이다.

 

(다시 원래의 publish 기능 얘기로 돌아가면, 근본적으로는 해당 문제는 프로젝트의 소스 코드를 수정해서 해결해야 했다. Publish 기능이 담긴 view를 장고의 @login_required 데코레이터를 이용해서 막아 주어서, 글을 publish할 수 있는 링크는 로그인한 유저에게만 노출되도록 권한 조정을 통해서 해결했다.)



최근 글 목록