안녕하세요?
제가 작년 이맘 때에도 파이썬을 이용하여 게시판에 새 글이 등록되면
텔레그램으로 알림을 받는 봇에 대한 스크립트를 올렸던 것 같은데요 ^^
여러 단점을 보완하여 완전히 새로 스크립트를 작성했습니다.
핫딜 정보를 놓치지 않거나, 관리하는 게시판을 밖에서도 모니터링 하는 용도로 사용하시면 될 것 같네요~
우선 파이썬 3.X에서 문제없이 작동되도록 했고, 최대한 간결하게 만들어봤어요.
작년에 작성한 글은 크론탭에서 설정한 시간간격 사이에 2개 이상의 새 게시글이 등록되어도
가장 최신글 하나만을 확인할 수 있고 나머지는 누락되는 치명적인 문제점이 있었는데요 ㅠㅠ
기존에 파싱한 결과의 리스트와 확인 시점에서 파싱한 리스트의 요소를 하나씩 비교해서
누락되는 알림이 없도록 했습니다 :)
미처 고려하지 못한 부분이지만 방금 막 생각이 나서 말씀을 드리면요.
새 글이 게시판 목록의 한 페이지를 넘는 경우까지 대비하려면
파싱하실 때 페이지 넘버로 사용되는 URL 파라미터값을 적절히 넣어서 while문으로 돌리면 거의 해결되겠죠.
(일단 아래 스크립트에서는 그 부분까지 다루지는 않았습니다)
import requests, telegram from bs4 import BeautifulSoup bot = telegram.Bot(token='토큰') try: chat_id = bot.getUpdates()[-1].message.chat.id except: chat_id = 챗아이디 req = requests.get('웹페이지 URL') req.encoding = '인코딩' // UTF-8이 디폴트이므로 UTF-8인 경우에는 생략하면 됩니다. html = req.text soup = BeautifulSoup(html, 'html.parser') boardlist = soup.select_one('CSS 셀렉터') // 구체적인 파싱 부분은 사이트마다 다를테니 생략하겠습니다. titles = boardlist.select('CSS 셀렉터') lines = [line.rstrip('\n') for line in open('파일명.txt', 'r', encoding='인코딩')] // 파일 -> 리스트 f = open('파일명.txt', 'w', encoding='인코딩') for title in titles: // 기존의 파싱 결과와 하나씩 대조하여 일치하는 것이 없으면 텔레그램 메시지를 보냅니다. count = 0 check = 0 while (count < len(lines)): if title.text == lines[count]: check = 1 count += 1 if check == 0: bot.sendMessage(chat_id=chat_id, text=title.text) f.write(title.text + '\n') f.close()
for문을 사용하여 기존의 파싱 결과와 대조하는 부분에 대해서는
조금 우회적인 방법을 사용한 것 같은데 솔직히 제 수준으로는 더 나은 아이디어를 찾지 못하겠더군요 ㅠㅠ
그리고 sendMessage에서 에러가 발생하면 TXT 파일이 불완전하게 생성되는 문제도 있구요.
주의할 점을 몇 가지 말씀드리면
우선 pip install telegram이 아니라 pip install python-telegram-bot으로 설치해야 합니다.
(import telegram이라고 해서 헷갈리지 마세요)
BotFather로 토큰 생성하고나서 봇에게 아무 말이나 한 마디 해야 봇이 채팅방을 제대로 인식할거구요.
이 파일을 처음으로 실행하면 리스트를 저장한 TXT 파일이 없을테니 당연히 에러가 발생합니다.
적당히 TXT 파일을 생성해놓고 실행하시거나, 파일을 읽는 부분을 제외하고 실행시켜야겠죠 ㅎㅎ
그리고 채팅방에 장시간 대화가 없을 때 IndexError가 발생하는 부분에 대해서는
제가 예전에 스포어에 글도 남겼고 이 스크립트에서도 try~except문으로 해결하려고 했지만
(except문에서 Chat ID는 @get_id_bot 등을 사용하시면 간단히 확인할 수 있습니다)
보다 확실한 해결방법에 대해 더 공부해보겠습니다 ㅠㅠ
알림봇을 혼자 사용하는 경우에는 예전에 네모 님께서 말씀해주셨듯이 getUpdates()[0]으로 놓으면 될 것 같네요.
허접한 글 읽어주셔서 감사합니다!
그럼 남은 주말 즐겁게 보내시고 감기 조심하세요~ ^-^
그리고 파일을 열때 w모드가 아니라 a모드로 열어서 check가 0인 경우에만 파일을 쓰게 하는 것이 좋아보입니다. ㅎ