본문 바로가기

How many language skills do you have?/Python

[Python] 게시판 공지사항 긁어서 텔레그램으로 보내기

앞으로 연구재단 홈페이지를 자주 들여다봐야할 것 같기도 하고.. 지금 당장은 선발 결과도 찾아봐야해서 급하게 만들었다. 

빛과 소금같은 아래 블로그를 많이 참고하였다. 자세한 내용은 링크들 참고!!

나는 그냥 내 것에 어떤식으로 적용했는지만 복기하고 공부하는 느낌으로...


1. 필요한 모듈 다운로드

pip install beautifulsoup4
pip install requests
pip install python-telegram-bot

터미널에서 위 명령어를 입력해서 다운로드 해 준다. 

잘 깔렸는지 확인해보려면 터미널에서 python 실행하고 import bs4, import requests 해 보면 된다.

 

2. 홈페이지에서 크롤링해오기 

https://ndb796.tistory.com/120

 

웹 크롤러(Web Crawler)의 개요 및 공지사항 크롤링 해보기

웹 크롤러(Web Crawler)의 개요 및 공지사항 크롤링 해보기 나동빈 ※ 웹 크롤러의 개요 ※ 웹 크롤러(Web Crawler)란 자동화된 방법으로 웹(WEB)에서 다양한 정보를 수집하는 소프트웨어를 의미합니다.

ndb796.tistory.com

from bs4 import BeautifulSoup
import requests

request = requests.get('https://nrf.re.kr/biz/notice/list?menu_no=362') 

html = request.text

soup = BeautifulSoup(html, 'html.parser')

links = soup.select('td > a')

for link in links:
    if link.has_attr('href'):
    	if link.get('href') != -1:
            print(link.text)

위 블로그(https://ndb796.tistory.com/120)에서 긁어온 코드를 붙여놓고 url은 공지사항이 있는 페이지를 긁어왔다. 

html에서 태그를 읽는 법은 크롬에서 F12를 누르고 게시판 제목에대고 오른쪽 마우스를 클릭하면 "검사"가 있다.

이걸 누르면 Elements가 제목이 있는 부분을 표시해준다 

참고 블로그에서는 if link.get('href').find('notice') != -1: 로 알려줬는데 연구재단 홈피는 notice태그가 붙지 않아서 find('notice')를 뺐다. (숨은그림찾기라고 생각하면 됨)

그러고 실행시키면 딱 첫 페이지에 있는 공지사항 제목들만 얻을 수 있다. 

$ python test.py
2021년도 우주개발기반조성 및 성과확산사업 하반기 신규과제 공모
(안내) 차세대중형위성 5호 탑재체 개발 사업설명회 개최 계획 및 사전질의서 양식
(서식 안내) 과제중단, 주관연구기관 변경 신청서식 안내
2021년도 「공공수요 기반 혁신제품 개발·실증」 신규과제 재공모
2021년도 인문사회학술연구교수 성과확산센터 최종 선정 공고
2021년 우수학자지원사업 최종 선정 공고
2022년도 PIM반도체기술개발사업 기술수요조사 안내
2022년도 차세대지능형반도체기술개발사업 기술수요조사 안내
2022년도 차세대중형위성개발사업 5호 탑재체 개발 신규과제 공모
차세대중형위성개발사업 3호 탑재체 개발 2차 공모과제 선정결과 공고

아마 태그를 요리조리 잘 이용해먹으면 제목말고 다른것도 요리할 수 있을 텐데 나는 지식도없고 급하니까 제목만 뽑기로했다. 

 


3. 최신 공지사항 업데이트만 뽑기 

위에 건 전부 다 가져오는 건데 나는 최신 공지사항만 궁금하기 때문에 조금 더 고쳤다.

if links[0].has_attr('href'):
    if links[0].get('href') != -1:
        #print(links[0].text)
        s2=links[0].text

위에 if~~ 부분을 links의 첫 줄만 관심이 있기 때문에 for구문을 없애고 links[0]에 관한 것으로 변경했다.

그렇게 하면 최신 게시글의 제목을 s2라는 변수에 저장할 수 있게 된다.

if not os.path.isfile("/Users/myname/Documents/python_test/title.txt"):
    g=open('/Users/myname/Documents/python_test/title.txt', 'w')
    g.close()

g=open('/Users/myname/Documents/python_test/title.txt',"r")
s1=g.readline()
g.close()

if s1==s2:
    pass
else:
    s1=s2
    g=open('/Users/myname/Documents/python_test/title.txt',"w")
    g.write(s1)
    g.close()

title.txt란 폴더를 만들어서 내용을 s1 변수에 저장한다. 그 다음 새로 실행 시 마다 얻어지는 s2를 s1과 비교하여 같으면 넘어가고 다르면 s1을 s2로 바꾼 후 title 파일에 저장 (이 때 "w"를 써서 title.txt는 하나의 변수만 존재 하게 한다). 이것도 더 fancy한 방법이 있을 것 같은데.. 난 파이썬 초보라 걍 직관적으로 아예 바깥 파일에 저장하는걸 선택ㅎㅎ 


4. 텔레그램 봇에게 전달하기

이것도 검색하면 엄청나게 많은 글이 나온다. 이 분 글을 통해 처음 봇을 만들었을 때 그 봇에게 말을 걸지 않으면 getUpdates를 했을 때 id를 얻지 못하는 걸 알게되었기때문에... 이분 블로그 추천.. 

1. 어떻게 bot을 만들고 2.어떻게 token과 id를 얻는지는 아래 블로그를 보시길!

https://py-son.tistory.com/8

 

[챗봇] 파이썬 텔레그램 챗봇, 이것만 따라하면 20분 완성 (코로나 알리미 봇)

텔레그램은 챗봇을 만들기 매우매우 쉬운 편입니다. 이 포스팅을 따라하면, 다른 것 볼 필요 없이 챗봇을 만들어 볼 수 있습니다. A. 텔레그램 앱 설치 안드로이드의 구글 플레이스토어나 iOS의

py-son.tistory.com

import telegram

bot = telegram.Bot(token='683367500:AAF993XXXXXfELkzojZAvJTryFNXXXXX')
chat_id = 5XXXXX276

if s1==s2:
    pass
else:
    s1=s2
    g=open('/Users/myname/Documents/python_test/title.txt',"w")
    bot.sendMessage(chat_id=chat_id, text=s1)
    g.write(s1)
    g.close()

위의 if else 구문에 만약 제목이 다르다면! (최신 글이 올라왔다면) 텔레그램을 통해 그 제목을 보내는 것을 추가하였다.


5. 10분마다 체크하기 (linux crontab 이용)

자 이제 텔레그램으로 까지 보내기에 성공하였다. 그 다음은 주기적으로 체크를 해야하는데, 나는 오늘까지 cron의 존재를 몰랐었다. 이걸 이제 알았다니.. 엄청난 기능이다!! 이것도 엄청 잘 알려주는 블로그가 있다. 

https://jdm.kr/blog/2

 

리눅스 크론탭(Linux Crontab) 사용법 :: JDM's Blog

* 이 포스팅은 네이버 블로그에서 작성(2013.04.01)한 내용을 옮겨온 것입니다. 오늘은 리눅스 크론탭에 대해 알아볼까 합니다. 음, 윈도우에서는 스케줄러와 비슷하다고 보면 되겠네요. "특정 시간

jdm.kr

crontab은 주기적으로 파일을 실행시켜주는 기능이다 😻 나는 Mac 사용자기 때문에 쓸 수 있었다ㅎㅎ

crontab -e 를 실행시켜서 아래 명령어를 추가하였다. :wq를 해서 저장을 한다. 

SHELL=/bin/bash
*/10 * * * * /Users/myname/Documents/python_test/test.sh >> /Users/myname/Documents/python_test/log.txt 2>&1

 

나는 위의 파이썬 코드를 실행시켜주고 로그를 남기기위해 쉘 스크립트를 다시 짰다.

*/10 * *. * * 는 10분마다 한번을 의미한다. 각 * 마다 역할이 있어서 더 복잡하게 정해줄 수 도 있다.

예를 들어 매 2, 3, 4 시마다 10분에 한번씩 실행 이런식으로 (위 블로그 참조)

#!/bin/bash
SHELL=/bin/bash

echo "$(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M)"
/Users/myname/opt/anaconda3/envs/py39/bin/python3 /Users/myname/Documents/python_test/test.py
echo ""

 

그리고 엄청 중요한 설명이 빠진 게 있는데, crontab은 실행을 완전 그 컴푸타의 뿌리에서 실행을 하기 때문에 내가 로그인프로파일 (bashrc or zsh 등)에 설정해놓은것들이 하나도 안먹힌다. 그냥 돌렸더니 파이썬 모듈이 실행이 안되서 여기서 또 시간을 엄청 허비했다.

그냥 python $path/test.py 하면 되는게 아니다. 

나는 걍 아나콘다로 만든 환경에서의 파이썬을 사용했다. (module들이 다 깔려있는 파이썬 환경)

conda info --envs

를 하면 주소가 잘 나타나 있다. 

$가상환경주소/bin/python3 $path/test.py

를 입력해주면 된다. 파이썬만 실행시킬거면 그대로 crontab 에서 써도 된다. 나는 shell 파일에 넣었다. shell위치도 지정해줄것!


6. 실행 

실행하면 10분에 한번씩 돌아가고 새로운 공지사항이 뜰때만 알람이 온다. 근데 밤엔 어차피 공지사항 안올라와서 crontab내용을 모두 주석처리해놨다. 저 별들(* * * * *)을 이용해서 구체적인 시간을 정해놓을 예정! 


7. 느낀점

1. crontab의 발견.. 이걸로 다른거 응용하면 딱이겠다

2. 생각보다 텔레그램으로 보내기 넘 편하고 쉽다.. 이것도 응용할게 무궁무진하다! 

3. 각종 에러와의 싸움이었다. 하~~~ 맨땅의 헤딩하면서 배우는중 ^^.. 이 과정까지 한시간 반정도 소요됐다. 에러만 없었으면 더 빨리 끝났을 텐데.. 귀차니즘을위한 코딩공부라 아주 편파적이고 얕아서 걱정이지만.. 성취감은 좋은 듯! 언제 한번 날 잡고 코세라같은데서 코딩공부를 해 봐야겠다. ✊