조회 수 4029 추천 수 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 변수에 문자열을 직접 입력하는 방법이 가장 안정적인 것 같네요.
    더 나은 방법을 알게되면 나중에 다시 댓글을 남기겠습니다 ^^

  1. [Python] Selenium을 이용하여 특정 element를 캡처하는 스크립트

    Date2019.07.03 Category코드 By이니스프리 Views6170
    Read More
  2. [Python] 선택한 파일을 Dropbox API를 이용하여 업로드하고 공유링크를 받아서 이미지 호스팅 용도로 URL을 변환하기

    Date2019.07.02 Category코드 By이니스프리 Views1192
    Read More
  3. [JS]클라이언트에서 Ip를 얻어보자

    Date2019.01.21 Category코드 ByHanam09 Views807
    Read More
  4. [JS] http를 https로 리디렉션!

    Date2018.12.30 Category코드 ByHanam09 Views885
    Read More
  5. [PHP] 이미지를 원하는 크기(원본비율 유지)로 리사이즈 하여 출력 (원본 이미지는 수정하지 않습니다)

    Date2018.12.20 Category코드 By이니스프리 Views8016
    Read More
  6. [아미나] 네이트 실시간 검색어 순위 위젯 (아미나 캐시 적용)

    Date2018.12.18 Category코드 By이니스프리 Views1134
    Read More
  7. [아미나] 출석 여부를 나타내는 메인화면 위젯

    Date2018.12.15 Category코드 By이니스프리 Views811
    Read More
  8. [PHP] 간단한 캐싱 클래스

    Date2018.12.06 Category코드 Bytitle: 황금 서버 (30일)humit Views882
    Read More
  9. [Python] 텔레그램을 이용한 게시판 새 글 알림봇

    Date2018.12.02 Category코드 By이니스프리 Views4029
    Read More
  10. [아미나] 게시글을 작성하면 ID와 IP로 필터링하여 자동으로 랜덤 댓글을 남기기 (+랜덤 포인트)

    Date2018.11.18 Category코드 By이니스프리 Views814
    Read More
  11. [PHP] 그누보드 자동 게시글 작성 - 일본기상협회의 우리나라 날씨를 크롤링한 후 파파고로 번역하여 글 작성

    Date2018.11.15 Category코드 By이니스프리 Views844
    Read More
  12. [PHP] 기상청 RSS 시간별 예보 위젯 - cache 적용(?)

    Date2018.10.28 Category코드 By이니스프리 Views1003
    Read More
  13. [오토핫키] 브라우저를 열어 지난번과 동일한 폴더에 MZK를 다운받고 압축을 네이티브로 해제하는 스크립트

    Date2018.10.20 Category코드 By이니스프리 Views928
    Read More
  14. [PHP] 기상청 중기예보를 캐러셀로 보여주는 위젯 (매우 허접합니다 ㅠㅠ)

    Date2018.09.28 Category코드 By이니스프리 Views756
    Read More
  15. [오토핫키] 구글 드라이브의 공유링크를 이미지 호스팅을 위한 다이렉트 링크로 바꿔주는 스크립트

    Date2018.09.25 Category코드 By이니스프리 Views1778
    Read More
  16. [오토핫키] 특정 사이트에 대한 ping 테스트 결과를 실행시간과 함께 로그 파일로 저장하는 스크립트

    Date2018.09.22 Category코드 By이니스프리 Views2102
    Read More
  17. [Python] 모 정부기관 사이트 파싱 후 PC 통신처럼 열람하고 싶은 게시글 번호를 입력하면 내용을 보여주는 소스 (허접)

    Date2018.09.14 Category코드 By이니스프리 Views755
    Read More
  18. 파이선 셸에서 실행하면...?

    Date2018.07.22 Category코드 By제르엘 Views630
    Read More
  19. C언어 삼중자를 이용한 코드

    Date2018.07.22 Category코드 Bytitle: 황금 서버 (30일)humit Views504
    Read More
  20. 폰트를 자동 설치하는 코드

    Date2018.07.16 Category코드 By네모 Views1020
    Read More
Board Pagination Prev 1 2 3 4 Next
/ 4