• 목록
  • 아래로
  • 위로

첨부 3

  1. Screenshot_20200515-195417_Telegram.jpg (File Size: 746.6KB/Download: 5)
  2. Screenshot_20200515-195437_Telegram.jpg (File Size: 964.4KB/Download: 5)
  3. Screenshot_20200515-195626_Telegram.jpg (File Size: 585.4KB/Download: 5)
라이선스 기타(따로 작성)

안녕하세요?

 

한 주 동안 다들 고생 많으셨네요~!

 

마스터 님의 허락을 받고 Studyforus 텔레그램 알림봇을 만들었어요 :)

 

필요로 하시는 분이 얼마나 계실지 모르겠지만요 ㄷㄷ

 

 

 

1. 스포어 알림 봇

 

내 알림 목록을 파싱하여 텔레그램으로 전송하는 스크립트입니다.

 

이 스크립트를 리눅스 크론이나 윈도우 작업스케줄러에 넣고 주기적으로 돌리면 되구요.

 

 

다음과 같은 특징이 있네요~!

 

1. 긴 댓글의 경우 내 알림 목록에서 짤리기 때문에 댓글 원문을 퍼옵니다.

 

2. 스티커의 경우 스티커를 다운받아서 텔레그램으로 전송하구요.

(다만 텔레그램에서 움짤을 지원하지 않아서 마치 JPG처럼 보입니다 ㅠㅠ)

 

3. 댓글 원문을 퍼오거나, 스티커를 다운받더라도 알림을 읽지 않은 상태를 유지합니다 ^^

 

 

from requests_html import HTMLSession
from bs4 import BeautifulSoup
import telegram, time


## 스포어에 로그인을 합니다. ##
def login(): 
    s = HTMLSession()
    s.get('https://studyforus.com')
    headers = {
        'origin': 'https://studyforus.com',
        'referer': 'https://studyforus.com'
    }
    formdata = {
        'error_return_url': '/',
        'mid': 'main',
        'vid': '',
        'ruleset': '@login',
        'act': 'procMemberLogin',
        'success_return_url': '/',
        'user_id': '***ID를 입력하세요***',
        'password': '***PW를 입력하세요***',
    }
    s.post('https://studyforus.com', headers = headers, data = formdata)
    return s


## 내 알림 목록을 크롤링합니다. ##
def parse(s):
    count = 0
    for i in range(1, 11):
        html = s.get('https://studyforus.com/index.php?mid=main&act=dispNcenterliteNotifyList&page=' + str(i)).text
        soup = BeautifulSoup(html, 'html5lib')
        trees = soup.find('table', {'class':'cl table table-striped table-hover'}).find('tbody').select('tr')
        result = []
        for t in trees:
            if t.select('td')[3].text.strip() == '읽음':
                count = 1
                break
            href = t.select('td')[2].find('a')['href']
            url = 'https://studyforus.com' + href
            msg = t.select('td')[2].text
            filename = ''

            if msg.endswith('..."라고 댓글을 남겼습니다.'): # 댓글의 경우 댓글 원문을 크롤링합니다.
                s2 = HTMLSession()
                html = s2.get(url).text
                soup = BeautifulSoup(html, 'html5lib')
                temp = soup.find('article', {'id': href.split('#')[-1]}).find('div', {'class':'cmt_body'}).find('div').text
                alarm = msg.split('"')[0] + '"' + temp + '"' + msg.split('"')[-1]
                time.sleep(0.5)
            elif '"{@sticker:' in msg: # 스티커의 경우 이미지를 다운받습니다.
                alarm = t.select('td')[2].text
                s2 = HTMLSession()
                html = s2.get(url).text
                soup = BeautifulSoup(html, 'html5lib')
                url = soup.find('article', {'id': href.split('#')[-1]}).find('div', {'class':'cmt_body'}).find('a')['style'].split('(')[1].split(')')[0][1:]
                rsp = s2.get('https://studyforus.com/' + url)
                filename = url.split('/')[-1]
                if rsp.status_code == 200:
                    with open(filename, 'wb') as f:
                        f.write(rsp.content)
            else: # 이외의 경우에는 알림 자체를 파싱합니다.
                alarm = t.select('td')[2].text

            if filename == '':
                result.append([alarm, url, 'no_image'])
            else:
                result.append([alarm, url, filename])
        if count == 1:
            break
        time.sleep(0.5)
    return result


## 텔레그램으로 전송합니다. ##
def telegram_bot(result):
    token = '***토큰을 입력하세요***'
    bot = telegram.Bot(token)
    try:
        chat_id = bot.getUpdates()[-1].message.chat.id
    except:
        chat_id = '***chat_id를 입력하세요***'
    try: # 로그 파일을 확인하여 한 번 알림이 오면 다시 알림이 오지 않도록 처리합니다.
        lines = [line.rstrip('\n') for line in open('sfu_tlgr.log', 'rt', encoding='utf8')]
    except: # 파일이 존재하지 않는 경우를 예외처리합니다.
        lines = ['노데이터']
    for r in result:
        if r[0] in lines:
            continue
        msg = '<a href="' + r[1] + '">' + r[0] + '</a>'
        bot.sendMessage(chat_id=chat_id, text=msg, parse_mode=telegram.ParseMode.HTML)
        if r[2] != 'no_image':
            bot.send_photo(chat_id, open(r[2], 'rb'))
    temp = [x[0] for x in result]
    with open('sfu_tlgr.log', 'wt', encoding='utf8') as f:
        f.write('\n'.join(temp))
    return


if __name__ == '__main__':
    session = login()
    alarms = parse(session)
    telegram_bot(alarms)

 

 

 

2. 봇 핸들러

 

만약 크론탭에서 지정한 시간이 되기 전에 다시 알림을 불러오고 싶다면 아래 스크립트를 이용하시면 됩니다 :)

 

텔레그램에서 '/get'이라고 입력하면 다시 크롤링을 합니다!

 

from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
import telegram
import sfu_tlgr as sfu


def get_command(bot, update):
    session = sfu.login()
    alarms = sfu.parse(session)
    sfu.telegram_bot(alarms)
    return


def server():
    token = '***토큰을 입력합니다***'
    updater = Updater(token, use_context=True)
    get_handler = CommandHandler('get', get_command)
    updater.dispatcher.add_handler(get_handler)
    updater.start_polling(timeout=1, clean=True)
    updater.idle()
    return


if __name__ == '__main__':
    server()

 

 

 

3. 테스트 결과

 

현재까지 제가 테스트한 바로는 잘 작동하네요~!

 

네모 님에 대한 오마주로서 봇 이름은 샤로라고 했네요 ㄷㄷ

 

 

1. 스티커도 잘 파싱되네요 :)

 

Screenshot_20200515-195417_Telegram.jpg

 

 

 

2. 댓글의 경우 원문 전체를 퍼옵니다!

 

Screenshot_20200515-195437_Telegram.jpg

 

 

 

3. 메시지를 클릭하면 브라우저에서 해당 페이지로 바로 연결됩니다 ^^

 

Screenshot_20200515-195626_Telegram.jpg

 

 

 

추가할 만한 기능이 있으면 댓글로 말씀해주세요 :)

 

마스터 님께 그동안 여러모로 신세를 져서 항상 빚을 지고 있다는 생각이 들었는데...

 

비록 허접한 스크립트이지만 이걸로 조금이나마 마음의 빚을 갚는 기분이네요!

(물론 이 스크립트를 실제로 사용하실 분은 안 계시겠지만요 ㅜㅜ)

 

그럼 다들 좋은 주말 되세요 ^-^

 

Nginx님 Nginx 포함 1명이 추천

추천인 1

작성자
이니스프리 95 Lv. (70%) 732770/737280EXP

ཇོ་མོ་གླང་མ

댓글 7

Nginx
profile image
서버가 없으면 언제나 알림은 불가능..

+) 샤로도 샤로만의 장점이 있지만 샤로 보단 치노...
comment menu
2020.05.15. 21:43

신고

"Nginx님의 댓글"

이 댓글을 신고 하시겠습니까?

이니스프리 작성자 → Nginx
profile image
허접한 스크립트인데 추천해주셔서 감사합니다 :)

+) 저도 샤로가 1픽은 아니에요 ^^
comment menu
2020.05.15. 22:41

신고

"이니스프리님의 댓글"

이 댓글을 신고 하시겠습니까?

신고

"이니스프리님의 댓글"

이 댓글을 신고 하시겠습니까?

title: 황금 서버 (30일)humit
profile image
+1
https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.send_photo

이미지를 다운받지 않더라도 http 링크로 전달해줄 수 있습니다.

이렇게 하면 이미지 다운로드 트래픽과 업로드 트래픽을 줄이실 수 있어요 :)
comment menu
2020.05.15. 23:21

신고

"humit님의 댓글"

이 댓글을 신고 하시겠습니까?

이니스프리 작성자 → humit
profile image
헐퀴~ 이런 기능이 있는지 처음 알았네요!
덕분에 또 많이 배우고 가네요~
항상 감사드립니다 ^-^
그럼 humit 님께서도 굿밤 되세요 :)
comment menu
2020.05.15. 23:27

신고

"이니스프리님의 댓글"

이 댓글을 신고 하시겠습니까?

title: 황금 서버 (30일)humit → 이니스프리
profile image
comment menu
2020.05.15. 23:32

신고

"humit님의 댓글"

이 댓글을 신고 하시겠습니까?

신고

"이니스프리님의 댓글"

이 댓글을 신고 하시겠습니까?

권한이 없습니다.
번호 분류 제목 글쓴이 날짜 조회 수
76 코드 [파이썬] 유튜브 영상을 다운받아 일정 간격으로 캡쳐하여 10장씩 merge하기 image 이니스프리 이니스프리 20.05.27.17:33 49
75 자료 [Autohotkey] 매분 정각에 전체화면을 캡쳐하는 스크립트 4 file 이니스프리 이니스프리 20.05.22.21:32 97
코드 [Python/Telegram] Studyforus 알림봇 (댓글, 스티커 파싱) 7 image 이니스프리 이니스프리 20.05.15.20:24 151
73 자료 한국어+영어 기초적 욕설필터 REGEX image title: NEW투명 시간버그 수정(오버플로우)개인정보처리.. 20.03.28.17:11 171
72 코드 [Python] url 주소로부터 IP 주소 알아내기 humit title: 황금 서버 (30일)humit 20.02.20.01:31 319
71 코드 [Python] 네이버 실시간 검색어 3 humit title: 황금 서버 (30일)humit 20.01.23.17:47 487
70 코드 Koa에서 자동으로 라우팅 채워주기 Seia Seia 20.01.22.19:46 211
69 코드 JavaScript에서 파이썬 문자열 처리 함수 중 하나 (바인딩)를 구현 7 Seia Seia 20.01.20.19:12 253
68 코드 [Python] Google Image Search 결과를 받아오기 image 이니스프리 이니스프리 19.12.09.17:38 425
67 코드 [파이썬] Requests를 사용한 네이버 카페 크롤링 - 일정수 이상의 리플이 달린 게시글만 텔레그램 알림 3 image 이니스프리 이니스프리 19.11.17.15:20 1548
66 코드 [JS] 클라이언트단 GET Parameter Hanam09 Hanam09 19.11.16.18:39 242
65 코드 [Python] 싸이월드 미니홈피 백업 스크립트 이니스프리 이니스프리 19.11.07.20:06 1219
64 코드 [Python] PIL을 이용한 Animated GIF의 리사이징 image 이니스프리 이니스프리 19.11.03.17:58 278
63 코드 [PyQt] sir.kr에서 스크랩한 게시글을 보여주는 윈도우앱 (검색 및 정렬 가능) 7 image 이니스프리 이니스프리 19.08.09.19:25 466
62 코드 [아미나] Dropbox API를 이용한 이미지 호스팅 보드스킨 11 image 이니스프리 이니스프리 19.07.13.10:01 594
61 코드 [Python] 네이버 모바일 이미지 검색에서의 이미지 파일을 멀티스레드로 다운받고 1개의 파일로 병합 11 image 이니스프리 이니스프리 19.07.12.01:22 617
60 코드 [PHP/Javascript] 아미나에 자동으로 게시글을 생성하고 Ajax로 전송하여 결과를 표시하기 2 image 이니스프리 이니스프리 19.07.09.06:24 353
59 코드 [Python] Selenium을 이용하여 특정 element를 캡처하는 스크립트 2 image 이니스프리 이니스프리 19.07.03.20:17 1496
58 코드 [Python] 선택한 파일을 Dropbox API를 이용하여 업로드하고 공유링크를 받아서 이미지 호스팅 용도로 URL을 변환하기 1 image 이니스프리 이니스프리 19.07.02.01:32 494
57 코드 [JS]클라이언트에서 Ip를 얻어보자 2 Hanam09 Hanam09 19.01.21.22:17 462