개요
저는 특정 홈페이지를 수시로 스크랩하여 보여주는 장고 기반의 웹페이지를 운영하고 있는데요, 그 내용을 매주 월요일에 카페에 올리고 싶어서 네이버 카페 API를 이용하게 되었습니다. (https://chemreg.info/)
네이버 카페 API를 이용하면 간단하게 할 수 있습니다. 제가 하고자 한 것은 ‘지난 한 주간 스크랩한 게시물을 모아서 네이버 카페에 올리기’ 입니다.
아래 영상은 작동 동영상입니다.
작성에 참고한 사이트 :
- Python3로 naver 카페에 글쓰기 - 이것을 따라했습니다.
- 네이버 API 문서
소스 코드
Django DB에서 데이터 읽어오는 것부터 카페에 자동으로 글을 쓰는 것 까지 모두 포함한 전체 소스 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# -*- coding: utf-8 -*-
import os
import sys
import django
import datetime
from datetime import timedelta
from selenium import webdriver
import urllib.request
from urllib.parse import urlencode
import json
import re
# Django 모델에 접근하기 위함
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
os.environ['DJANGO_SETTINGS_MODULE'] = 'chemreg.settings'
django.setup()
from news.models import Notice, Source #Notice와 Source 모델을 사용
# 네이버 계정 및 앱 정보
# 보안을 위해 환경 변수로 등록
naver_id = os.environ["naver_id"] #네이버 아이디
naver_pw = os.environ["naver_pw"] #네이버 비밀번호
naver_cid = os.environ["naver_cid"] #클라이언트 아이디
naver_csec = os.environ["naver_csec"] #클라이언트 시크릿
naver_redirect = "http://127.0.0.1:8000/" #리다이렉트 URI -> 아무거나 상관없음
driver = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver")
driver.implicitly_wait(3)
# 네이버 로그인
driver.get('https://nid.naver.com/nidlogin.login')
driver.execute_script("document.getElementsByName('id')[0].value=\'"+ naver_id + "\'")
driver.execute_script("document.getElementsByName('pw')[0].value=\'"+ naver_pw + "\'")
driver.find_element_by_xpath('//*[@id="frmNIDLogin"]/fieldset/input').click()
driver.implicitly_wait(3)
driver.find_element_by_xpath('//*[@id="frmNIDLogin"]/fieldset/span[2]/a').click()
state = "SOMETHING" # 보안을 위한 문자열 -> 아무거나 상관없음
# 네아로로 이동
req_url = 'https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=%s' % (naver_cid, naver_redirect, state)
driver.get(req_url)
# 처음 1회에 한해서 여기서 권한을 추가하는데, 이것은 수동으로 하는 게 편할 것 같아서 그냥 이렇게 놔둠
# 오류가 발생한다면 이까지만 실행하고 권한 추가는 수동으로 한다.
# 카페 관련 권한 체크하는 것 빼먹지 않도록 조심.
redirect_url = driver.current_url
temp = re.split('code=', redirect_url)
code = re.split('&state=', temp[1])[0]
driver.quit()
url = 'https://nid.naver.com/oauth2.0/token?'
data = 'grant_type=authorization_code' + '&client_id=' + naver_cid + '&client_secret=' + naver_csec + '&redirect_uri=' + naver_redirect + '&code=' + code + '&state=' + state
request = urllib.request.Request(url, data=data.encode("utf-8"))
request.add_header('X-Naver-Client-Id', naver_cid)
request.add_header('X-Naver-Client-Secret', naver_redirect)
response = urllib.request.urlopen(request)
rescode = response.getcode()
token = ''
# 정상 작동하면 token 변수에 접근토큰이 저장된다.
if rescode == 200:
response_body = response.read()
js = json.loads(response_body.decode('utf 8'))
token = js['access_token']
else:
print("Error Code:", rescode)
# 접근 토큰을 정상적으로 받아왔다면 이제 글을 쓸 차례
# 여기서부터는 게시물 내용 작성을 위한 부분. Django DB에 접근한다
source_list = Source.objects.all()
one_week_ago = datetime.datetime.today() - timedelta(days=7) # 일주일 전 날짜
# 지난 주 게시물을 가져오는 함수
def last_week_notices(pk):
return Notice.objects.filter(source__pk=pk).filter(written_date__gte=one_week_ago).order_by('-written_date','-scrapped_date')
post_content = "지난 주 화학물질 규제 관련 새 게시물 목록입니다.<br>" # 게시물 내용
for source in source_list:
notices = last_week_notices(source.pk)
if notices:
post_content += "<br> <h2><a href='{}'>{} {}</a></h2>".format(source.address, source.name, source.sub_name)
for notice in notices:
post_content += "<strong>{}</strong> {} <br>".format(str(notice.written_date)[:11], notice.title)
post_content += "<br><br>-----<br>이 글은 매주 월요일 아침에 자동으로 게시됩니다.<br>감사합니다.<br>"
# 여기까지는 장고에서 글 쓸 내용을 불러오는 내용이었음
# 여기서부터 네이버 카페 글쓰기
header = "Bearer " + token # Bearer 다음에 공백 추가
clubid = "29698650" # 카페의 고유 ID값
menuid = "2" # (상품게시판은 입력 불가)
url = "https://openapi.naver.com/v1/cafe/" + clubid + "/menu/" + menuid + "/articles"
subject = urllib.parse.quote("지난주 규제 관련 새 게시물") # 제목
content = urllib.parse.quote(post_content) # 글 내용
data = urlencode({'subject': subject, 'content': content}).encode()
request = urllib.request.Request(url, data=data)
request.add_header("Authorization", header)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if(rescode==200):
response_body = response.read()
print(response_body.decode('utf-8'))
else:
print("Error Code:" + rescode)
기타
-
처음에 권한 추가할 때 카페를 반드시 클릭해야 함. 카페가 필수 권한이 아니라 빼먹었는데, 자꾸 401에러가 떠서 한참을 고생함. 만약 빼먹었다면, 해당 아이디로 네이버 로그인 후 ‘네이버 - 내정보 - 보안설정 - 외부 사이트 연결’로 들어가서 해당 앱의 연결을 끊고 다시 로그인.
-
위의 코드에서 언급했듯이 아이디로 로그인 후 권한을 추가하는 부분은 작성을 안 했음. 수동으로 할 것.
-
서버에 올릴 때는 창이 뜨지 않도록 Headless로 바꾸고 올리면 됩니다.
1
driver = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver")
위의 내용을 아래 내용으로 바꾸어 주세요.
1
2
3
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome("/usr/lib/chromium-browser/chromedriver", chrome_options=options)
-
Previous
스터디 노트 - Udacity HTTP & Web Servers (2) The Web from Python -
Next
스터디 노트 - 0x250 직접 해보기 (메모리)