조회 수 3981 추천 수 0 댓글 7
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form
라이선스 MIT

안녕하세요?


제가 작년 이맘 때에도 파이썬을 이용하여 게시판에 새 글이 등록되면 


텔레그램으로 알림을 받는 봇에 대한 스크립트를 올렸던 것 같은데요 ^^


여러 단점을 보완하여 완전히 새로 스크립트를 작성했습니다.


핫딜 정보를 놓치지 않거나, 관리하는 게시판을 밖에서도 모니터링 하는 용도로 사용하시면 될 것 같네요~



우선 파이썬 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]으로 놓으면 될 것 같네요.



허접한 글 읽어주셔서 감사합니다!


그럼 남은 주말 즐겁게 보내시고 감기 조심하세요~ ^-^

  • profile
    title: 황금 서버 (30일)humit 2018.12.02 23:03
    약간 고칠점이 있다면 while 문에서 if문이 성립하면 break 를 이용해서 더이상 순회를 하지 않아도 될 것으로 보이네요.
    그리고 파일을 열때 w모드가 아니라 a모드로 열어서 check가 0인 경우에만 파일을 쓰게 하는 것이 좋아보입니다. ㅎ
  • profile
    이니스프리 2018.12.03 08:48

    앗 전역 앞두고 바쁘신데 제 허접한 스크립트를 봐주셔서 정말 감사합니다!

    말씀하신대로 while문 안의 if문이 성립해서 check = 1이 되면 더 이상 while문을 돌릴 필요가 없으니 break하면 되겠네요 ^^

    그런데 파일을 a모드로 열면 파일의 마지막에 새로운 내용이 추가되어

    장기적으로 파일의 길이가 계속 길어지지 않는지 여쭤봅니다~

    어느덧 12월의 첫번째 주인데 humit 님께서도 감기 조심하시고 군 복무 무탈히 잘 마무리하시길 기원합니다 :)

  • profile
    title: 황금 서버 (30일)humit 2018.12.03 10:08
    만약 커뮤니티 게시물과 같이 계속 새로운 게시물이 위쪽에 업데이트 되는 경우라면 w모드로 하셔도 되고 while문도 일치한 이후부터는 아예 종료를 하면 될 것 같네요.
  • profile
    이니스프리 2018.12.03 10:30
    옙 말씀해주신대로 수정해보겠습니다~!
    바쁘신데 답변해 주셔서 감사합니다 :)

    그리고 lines = [line.rstrip('\n') for line in open('파일명.txt', 'r', encoding='인코딩')]
    이 부분은 with open으로 파일을 열지 않았는데 따로 close를 하지 않아도 무방한지 여쭤봅니다 ^^
    사실 어떻게 close 해야하는지도 모르겠네요.
    humit 님 덕분에 파이썬에 대해 많이 배워서 정말 감사합니다 ^-^
  • profile
    title: 황금 서버 (30일)humit 2018.12.03 10:52
    저 정도 코드에 대해서는 따로 닫아주지 않더라도 상관이 없어보입니다.
    다만 규모가 커지면 직접 닫아주는 편이 좀 더 낫습니다.
  • profile
    이니스프리 2018.12.03 11:31
    옙 번번이 정말 감사합니다 ^^
    일단은 저 혼자 알림을 사용할테니 close하지 않고 그냥 사용해볼게요 :)
    그럼 즐거운 휴가 첫 날 되시고 모처럼의 점심식사 맛있게 드세요~!
  • profile
    이니스프리 2018.12.13 17:14
    제가 현재까지 테스트한 바로는 채팅방에 장시간 대화가 없을 때 IndexError가 발생하는 부분에 대해서는
    Chat_id 변수에 문자열을 직접 입력하는 방법이 가장 안정적인 것 같네요.
    더 나은 방법을 알게되면 나중에 다시 댓글을 남기겠습니다 ^^

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
58 코드 [Python] Selenium을 이용하여 특정 element를 캡처하는 스크립트 2 file 이니스프리 2019.07.03 6105
57 코드 [Python] 선택한 파일을 Dropbox API를 이용하여 업로드하고 공유링크를 받아서 이미지 호스팅 용도로 URL을 변환하기 1 file 이니스프리 2019.07.02 1166
56 코드 [JS]클라이언트에서 Ip를 얻어보자 2 Hanam09 2019.01.21 776
55 코드 [JS] http를 https로 리디렉션! 3 Hanam09 2018.12.30 840
54 코드 [PHP] 이미지를 원하는 크기(원본비율 유지)로 리사이즈 하여 출력 (원본 이미지는 수정하지 않습니다) 6 이니스프리 2018.12.20 7994
53 코드 [아미나] 네이트 실시간 검색어 순위 위젯 (아미나 캐시 적용) 3 file 이니스프리 2018.12.18 1123
52 코드 [아미나] 출석 여부를 나타내는 메인화면 위젯 4 file 이니스프리 2018.12.15 770
51 코드 [PHP] 간단한 캐싱 클래스 3 title: 황금 서버 (30일)humit 2018.12.06 855
» 코드 [Python] 텔레그램을 이용한 게시판 새 글 알림봇 7 이니스프리 2018.12.02 3981
49 코드 [아미나] 게시글을 작성하면 ID와 IP로 필터링하여 자동으로 랜덤 댓글을 남기기 (+랜덤 포인트) 7 file 이니스프리 2018.11.18 805
48 코드 [PHP] 그누보드 자동 게시글 작성 - 일본기상협회의 우리나라 날씨를 크롤링한 후 파파고로 번역하여 글 작성 4 file 이니스프리 2018.11.15 821
47 코드 [PHP] 기상청 RSS 시간별 예보 위젯 - cache 적용(?) 9 file 이니스프리 2018.10.28 991
46 코드 [오토핫키] 브라우저를 열어 지난번과 동일한 폴더에 MZK를 다운받고 압축을 네이티브로 해제하는 스크립트 file 이니스프리 2018.10.20 920
45 코드 [PHP] 기상청 중기예보를 캐러셀로 보여주는 위젯 (매우 허접합니다 ㅠㅠ) 10 file 이니스프리 2018.09.28 733
44 코드 [오토핫키] 구글 드라이브의 공유링크를 이미지 호스팅을 위한 다이렉트 링크로 바꿔주는 스크립트 10 file 이니스프리 2018.09.25 1754
43 코드 [오토핫키] 특정 사이트에 대한 ping 테스트 결과를 실행시간과 함께 로그 파일로 저장하는 스크립트 2 이니스프리 2018.09.22 2054
42 코드 [Python] 모 정부기관 사이트 파싱 후 PC 통신처럼 열람하고 싶은 게시글 번호를 입력하면 내용을 보여주는 소스 (허접) 4 이니스프리 2018.09.14 744
41 코드 파이선 셸에서 실행하면...? 3 제르엘 2018.07.22 546
40 코드 C언어 삼중자를 이용한 코드 title: 황금 서버 (30일)humit 2018.07.22 484
39 코드 폰트를 자동 설치하는 코드 1 네모 2018.07.16 978
Board Pagination Prev 1 2 3 4 Next
/ 4