1. [파이썬] 셀레니움 selenium 웹 크롤링 시작
2. [파이썬] selenium 크롤링, 데이터 수집 ID, TAG, href 찾기
3. [깃허브] github에 vs code project 올리기, 업로드, Push
4. 티스토리 자동 글쓰기 API Authentication Code & Access Token 발급
5. [파이썬] 티스토리 API 이용 자동 글쓰기. 파이썬 request post
6. [파이썬] 뉴스 크롤링 티스토리에 자동 업로드하기 (마무리)
7. [파이썬] 윈도우 작업 스케줄러에서 파이썬 자동 실행시키기 (이전 포스팅)
8. [파이썬] mouse, keyboard 제어 & 티스토리 api 없이 글 쓰기 (414 제한 오류) (현재 글)
414 오류
저번 포스팅에서 다 끝냈다 생각했었다.
뭐 처음 의도대로 헤드라인 뉴스들 크롤링 하여 배치파일에 올려서 정해둔 시간에 알아서 포스팅 하게는 7번 글까지는 완성이 되어있다.
하지만 블로그를 운영하면서 퀄리티 있고 깔끔한 글을 원하는대 지금은 좀 조잡하다는 생각이 들어 계속해서 수정을 하고 싶어 졌다.
지금까지는 아래 그림처럼 포스팅 된다.
퀄리티와 깔끔함을 운운해 놓고 저런 조잡한 저퀄의 이미지는 어폐가 있지만 아무튼 중요한 건 저 것을 아래 사진처럼 바꾸고 싶어졌다.
제목과 썸네일만 말고 기사 내용도 좀 요약해서 미리보여 준다던지... 더보기를 클릭하면 링크로 이동하던지 아니면 숨겨진 텍스트를 펼쳐서 쫙 보여준다던지 그런식으로 바꾸고 싶었다.
그래서 뭐 앞에서 했던것처럼 티스토리 api를 이용하여 글쓰기를 하였는데 414 오류가 떴다.
414 Request-URI Too Long
뭐 내용이 너무 길다고 제한해 놓은 것 같다. 아.. 그래서 글자 수를 줄여야 하나 싶었는데 그러면 너무 제한이 많이 생긴다.
그래서 포기해야 되나 싶었지만 일단은 결국은 해내긴 했다.
그 과정을 작성해 보려한다.
시행착오
뭐 이 내용은 건너뛰어도 되지만 여러 시행착오를 겪을지도 모를? 분들을 위해 서술해 본다.
먼저 그리고 크롤링 하던 와중에 사용한 셀레니움을 이용해서 글을 작성해 보기로 했다.
글쓰기 url만 가져와서 셀레니움으로 크롬을 제어하여 카테고리 선택, 제목, 내용도 send_key로 입력하고 작성~
이렇게 하면 되지 않을까 막연하게 시도해 보려 했다.
결과적으로 send_key 로 제목과 내용을 입력할 수 없었다.
<input> 태그로 감싸져 있지 않아서 인지 셀레니움으로는 실패했다.
하지만 셀레니움에는 execute_script() 함수가 있다. 이것을 이용해 보려 했다.
이것도 실패했다. 저 함수안에 자바 스크립트를 문자열로 작성해 넣으면 자바스크립트를 실행할 수 있으나 내용에 뭔가의 값을 넣기는 힘들었다.
그래서 일단 티스토리 api로 글을 먼저 작성하고 셀레니움으로 크롬을 제어해 글 수정을 하기로 했다.
html += f"""
<p data-ke-size="size16"> </p>
<p data-ke-size="size16"><h2><a href={i[1]}>{i[0]}</a></h2></p>
<div style="width:700px; height:400px; text-align:center;"><img style="max-width:100%; max-height:100%;" src={i[2]}/></div>
<div class="box">
<div class="content"></div>
</div>
이런식으로 i[1]에 링크 i[0]에 제목이 이미지는 i[2]가 들어간다.
기사 내용은 나중에 div class="content" 안에 넣을 생각이었다. 자바스크립트든 jquery 든 content 클래스를 찾아서 값을 넣어주려 했으나 애초에 content class를 찾을 수 없었다. content 말고도 id로도 찾을 수 없었고 아무튼 뭔가 티스토리 쪽에서 조치롤 해놓은 것 같다. 그래서 api를 따로 만들어 논거 같기도 하고... (하기사 뭐..)
성공방법
1. 티스토리 API를 이용해 python으로 제목만 달고 자동 글쓰기
- 파라미터에 content 부분에 html로 작성된 내용을 보내지 않고 변수에 저장
2. 응답코드로 postId를 받아서 글 수정을 통해 저장해 놓은 html을 게시물에 작성하고 저장한다.
- 위 과정에서 마우스와 키보드를 제어한다.
먼저 글을 작성한 후 응답코드에서 postId 값을 추출해 냈다. xml형식으로 오는데 json으로 변환하여 사용했다.
아래 글에 파이썬에서 xml -> dictionary (json)으로 변환하는 방법이 설명되어 있다.
https://hellodoor.tistory.com/198?category=926439
이제 추출해낸 postId로 글 수정 url을 만들어서 수정을 한다. 우선 자동업로드는 6번 게시물을 참고하면 잘 작성되어 있다.
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
|
parameters = {
'access_token': '',
'blogName': 'hellodoor',
'title': str(year) + '년 ' + str(mon) + '월 ' + str(day) + '일 헤드라인 뉴스 모음/' + thumTitle,
'content': '',
'visibility': '3',
'category': '974645',
'tag': 'news, naver news, headline news, 뉴스, 네이버뉴스, 헤드라인 뉴스, python, 티스토리 api',
'acceptComment': '1'
}
response = requests.post(tistoryUrl, params=parameters)
print(response.text)
xmlData = response.text
# xml형식 -> json으로 변환
jsonStr = json.dumps(xmltodict.parse(xmlData), indent=4)
# json -> dic으로 변환
dict = json.loads(jsonStr)
print(dict['tistory'])
print(dict['tistory']['postId'])
result = []
result.append(dict['tistory']['postId'])
result.append(html)
contentWrite.editPosting(result)
|
cs |
5행 : content를 비워 놓은다. 수정할 것이기 때문에 내용은 넣을 필요 없다.
15행 : 응답을 response.text로 받는다. xml 형식으로 받아진다.
17, 19행 : xml을 dictionary 타입으로 변환한다.
25행 : 응답 코드 중 postId를 result 배열에 넣고
26행 : 원래 request를 보낼 때 content 파라미터에 넘긴 html을 배열에 넣고 28행에서 글 수정하는 함수를 호출한다.
contentWrite.py 에 editPosting 이란 함수를 호출 한 것이다.
contentWrite.py 전체 코드
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
|
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import pyautogui
import pyperclip
import chromedriver_autoinstaller
import time
import subprocess
subprocess.Popen(r'C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-port=9999 --user-data-dir="C:\chrometmp"')
chrome_ver = chromedriver_autoinstaller.get_chrome_version().split('.')[0]
option = Options()
option.add_experimental_option("debuggerAddress", "127.0.0.1.:9999")
try:
driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe', options=option)
except:
chromedriver_autoinstaller.install(True)
driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe', options=option)
driver.implicitly_wait(10)
def editPosting(data):
tistory = f'https://hellodoor.tistory.com/manage/newpost/{data[0]}?type=post&returnURL=https%3A%2F%2Fhellodoor.tistory.com%2Fmanage%2Fposts'
driver.get(tistory)
time.sleep(2)
mceu_20 = driver.find_element_by_id('mceu_20-open')
mceu_20.click()
time.sleep(0.5)
mceu_38 = driver.find_element_by_id('mceu_34')
mceu_38.click()
pyautogui.moveTo(-1495, 331)
pyautogui.click()
pyperclip.copy(data[1])
pyautogui.hotkey('ctrl', 'v')
# pyautogui.write(data[1])
btn_default = driver.find_element_by_class_name('btn-default')
btn_default.click()
foot = driver.find_element_by_class_name('layer_foot')
btns = foot.find_elements_by_tag_name('button')
for btn in btns:
btn_type = btn.get_attribute('type')
if btn_type == 'submit':
btn.click()
print(btn_type)
driver.quit()
|
cs |
좀 짧다. 여기서 selenium을 쓰긴 해야하니 21행까지는 앞서 있던 코드를 또 썼다. 전역변수로 해서 뭐 어떻게 해도 되겠지만 일단 다시 작성했다.
먼저 cmd 창에
$ pip install pyautogui
$ pip install pyperclip 을 입력한다. 클립보드와 키보드 마우스 제어를 위한 모듈이다.
21행까지의 설명은 이전 글에서 대충 되어있으니 그걸 빼고 보면 더 짧다.
23행 : editPosting(data) data로 받은 변수는 result로 보낸 배열 변수였다.
data[0]에 postId가 있고 data[1]에 html이 들어있다.
25행 : 글 수정 url이다. 티스토리 블로그에 직접 글 수정을 누르고 url을 통으로 긁어왔다. 거기서 newpost/이후가 postId가 들어가는 곳이다. data[0]을 집어 넣어서 방금 작성된 글을 수정하게 했다.
여기서 뭐 수정할 권한이 없다 뜰 수 있는데 로그인이 안되어 있어서 그렇다. 여기서 파이썬으로 실행시킨 크롬과 평소에 쓰던 크롬이 쿠키가 달라서 그렇다. 파이썬에서 실행시켜서 크롬을 띄우면 그 창을 놔두고 로그인 유지를 체크하면서 로그인 하고 글 수정이 가능한지 확인하고 다시 파이썬으로 실행시키면 쿠키가 남아있어서 권한이 있다.
위 코드를 따라하면 그 쿠키는 11행에서 chrometmp에 저장된다.
29행, 33행 : data[1]에 저장된 값은 html 값이다. 그러기에 글쓰기 모드를 HTML로 바꿔주는데 그 버튼 id 값을 찾아서 클릭 시켜 준다.
36행 : pyautogui.moveTo(-1495, 331)
37행 : pyautogui.click()
마우스 포인터를 이동시켜서 클릭한다.
내 컴퓨터에서는 저 파란부분이다. 저 곳을 클릭해야 키보드를 제어해도 저 곳에 입력할 수 있다.
moveTo(좌표, 좌표) 인 것인데 내가 원하는 곳의 좌표를 아는 방법은 여러 방법이 있지만 파이썬에서는 간단하게 알고 싶은 좌표에 마우스를 놓고
position = pyautogui.position()
print(position.x)
print(position.y)
이 코드를 사용하면 알 수 있다.
39, 40행 :
pyperclip.copy(data[1])
pyautogui.hotkey('ctrl', 'v')
html을 pyperclip.copy()로 복사한다. 클립보드에 복사해 놓는 것이다. 그리고 ctrl + v 로 붙여놓는다. 이렇게 하는 이유가 한글을 그대로 옮길 수 있기 때문이다.
아까 마우스로 클릭해 놓은 곳에 쫘르륵 입력이 된다.
44행 부터 나머지 코드들은 이제 완료 버튼과 공개발행 버튼을 찾아서 클릭해 주는 것이다.
여기까지 하면 뒷부분은 좀 아매로 했지만 어쨋건 원하는 분량의 내용을 파이썬으로 자동 업로드 하게 했다.
소스코드는 6번 글에서 요청부분 조금 수정하고 contentWrite.py 하나만 추가한 것이다.
일단 끝났다. 이제 원하는 퀄리티가 조금 나오긴 했지만 수정은 계속해서 좀 더 깔끔하게 하려 한다.
---------------------------------------------------------------------------------------------------------------------------------
아... 진짜 마우스로 포인터 이동해서 클릭하고 뭐 복사해서 넣고... 원하는 느낌은 아니였지만 여기까지 하는데도 많은 시도와 포기 시간을 뺏겨서 너무 지쳤다.
보통 코드 작성 금방 쉭쉭~~ 하고 티스토리에 그것을 정리하는게 오래걸리는데 이거는 오히려 반대로 프로젝트 자체가 뭔가 첫 시도?여서 시간을 많이 뺏기고 티스토리에는 오히려 대충대충 쉭쉭~~ 한 것 같다.
아무튼 여기까지...
'Project > Auto Upload' 카테고리의 다른 글
[파이썬] 윈도우 작업 스케줄러에서 파이썬 자동 실행 (bat 파일) (0) | 2021.09.24 |
---|---|
[파이썬] 뉴스 크롤링 티스토리에 자동 업로드하기 (마무리) (6) | 2021.09.24 |
[파이썬] 티스토리 API 이용 자동 글쓰기. 파이썬 request post (2) | 2021.09.11 |
티스토리 자동 글쓰기 API Authentication Code & Access Token 발급 (2) | 2021.09.11 |
[깃허브] github에 vs code project 올리기, 업로드, Push (0) | 2021.09.09 |
댓글