# [한라대학교 공지 알림 봇] 서버 작업

- Author: @mildsalmon
- Published: 2020-02-24
- Updated: 2021-11-12
- Source: http://blex.me/@mildsalmon/%ED%95%9C%EB%9D%BC%EB%8C%80%ED%95%99%EA%B5%90-%EA%B3%B5%EC%A7%80-%EC%95%8C%EB%A6%BC-%EB%B4%87-%EC%A0%9C%EC%9E%91%EA%B8%B0-5-%EC%84%9C%EB%B2%84-%EC%9E%91%EC%97%85
- Tags: python, 텔레그램봇, 한라대학교, 웹크롤링, 공지알림봇, 서버작업

---

# Intro

서버는 AWS의 Amazon Lunux 2를 사용했다.

# PuTTY

나는 서버에 접속할때 PuTTY를 주로 사용한다. <br>
PuTTY는 SSH, Telet 등의 접속방식을 제공한다.<br>
PuTTY는 서버에 원격으로 접속하게 도와주는 프로그램이다.<br>

[다운로드](https://www.chiark.greenend.org.uk/~sgtatham/putty/)<br>
위 링크를 통해 다운받을 수 있다.

![](https://static.blex.me/images/content/2020/2/26/4fyLlwWcwFNfqep47NXe.png)

##### PuTTY 접속 방법

![](https://static.blex.me/images/content/2020/2/26/LttMZ4ghi1E94ysSiVUz.png)

![](https://static.blex.me/images/content/2020/2/26/gtaAXgx3SYuggcIqegqc.png)

빨간 부분만 잘 설정해주면 잘 접속이 된다.

##### AWS .pem을 .ppk로 변환하는 방법

![](https://static.blex.me/images/content/2020/2/26/IjzvIQm2XhlMNeacO18n.png)

위에서 `puttygen.exe`를 클릭한다.

![](https://static.blex.me/images/content/2020/2/26/50km2bK44zh4oADWBVqT.png)

![](https://static.blex.me/images/content/2020/2/26/k8lHyiOplj3Py68W3Est.png)

`Load`를 먼저 누르고 `Save private key`를 누르면 `.ppk`가 만들어진다.<br>
다른 블로그를 보면 `Generate`를 누르고 마우스를 빙글빙글 돌리라는데.<br>
난 그 방법으로 절대 리눅스 접속이 안되서 위 방법으로 했더니 잘 접속되더라.<br>

##### AWS 주소 알아내는 방법

![](https://static.blex.me/images/content/2020/2/26/R3sI3E9YqawpcnTSy3Qr.png)

![](https://static.blex.me/images/content/2020/2/26/R1Sd1ehRTxXidF9ct80o.png)

연결을 누르면 인스턴스에 연결이 뜰텐데 거기서 빨간색 박스를 확인하면 된다.

### pscp

```
SCP란. (Secure Copy Protocol)
로컬 호스트와 원격 호스트 간 또는 두 원격 호스트 간에 파일을 안전하게 전송하는 수단.
SSH(Secure Shell) 기반으로 동작.
```

윈도우에서 리눅스로 파일을 전송하기 위해 FTP, PSCP 등의 많은 프로그램이 있지만,<br>
내가 사용하는 리눅스에는 FTP 서비스를 구축하지 않았다.<br>
그래서 속도도 빠르고 간편한 PSCP를 사용하기로 헀다.<br>

![](https://static.blex.me/images/content/2020/2/26/IjzvIQm2XhlMNeacO18n.png)

정상적으로 PuTTY를 설치했다면 위와 같이 파일이 깔려 있을 것이다.<br>
그 중에서 `pageant.ext`를 클릭하자.<br>
`pageant.ext`는 pscp로 파일을 보낼때 보안 검증을 도와준다.<br>
AWS는 리눅스에 접속할때 `.pem` 형식의 키가 발급된다.<br>
PuTTY에서는 이 `.pem` 형식의 키를 `.ppk`로 변환해서 사용해야한다.<br>
즉, `.ppk`가 등록되어 있지 않으면 pscp로 파일 전송하는 것도 불가능하다.<br>

![](https://static.blex.me/images/content/2020/2/26/xNbSu0Vo2htBejmeR4gi.png)

처음 실행하면 이렇게 뜬다.

##### pscp 키 등록 방법

![](https://static.blex.me/images/content/2020/2/26/SoN7cDfCyxoImBpna7xs.png)

![](https://static.blex.me/images/content/2020/2/26/4wr5XrKn9bnyyuvVY6SI.png)

![](https://static.blex.me/images/content/2020/2/26/3PuDxK5BfCfKEPQq2Zd3.png)

등록은 어렵지 않다.<br>
저렇게 잘 뜨면 등록된거다.<br>

##### pscp 파일 전송

![](https://static.blex.me/images/content/2020/2/26/7Conl6SyCInndSiyBVxn.png)

명령어는

```
pscp 보낼파일주소/보낼파일명 받을주소:/받을폴더명
```

![](https://static.blex.me/images/content/2020/2/26/KEMeY0hNBSnuXI6pWlLt.png)

확인해보면, 잘 받아진걸 알 수 있다.

# crontab

[Crontab 정리본](https://blex.me/@mildsalmon/crontab)

이제 crontab을 이용해서 정해진 시간마다 자동으로 프로그램이 실행되게 설정해야한다.

```
crontab -l
```

![](https://static.blex.me/images/content/2020/2/26/JFbTUd6FbiYnfrZwpc72.png)

난 지금 실행중인 파일이 있어서 리스트에 뭐가 뜨는데 처음 실행하는거면 아무것도 없을 것이다.

```
crontab -e
```

위 명령어를 통해 실행주기 / 실행할 파일 명 / 로그 를 적어줘야한다.

기본 형식은
```
* * * * * python3 실행파일주소 >> 로그저장주소 2>&1
```

\* \* \* \* \* 은 실행 주기를 나타낸다.<br>
순서대로<br>
분(0-59) 시간(0-23) 일(1-31) 월(1-12) 요일(0-7)<br>
이며 0과 7은 일요일이다.<br>

내 경우에는 \*/10 \* \* \* \* 이면 10분마다 실행해주었다.

crontab은 -e를 통해 설정을 변경해주면 서비스를 재시작해야한다.<br>

```
service crond stop
service crond start
service crond status
```

를 통해 정지 후 시작 / 상태확인이 가능하다.

# 코드 수정

```python
import requests
from bs4 import BeautifulSoup
import sys
import telegram
import os
import time

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

my_token = '봇 토큰'
my_chat_id = '채널 주소 / 서비스 채널은 @*** / 테스트 체널은 -***'
req = requests.get('http://www.halla.ac.kr/mbs/kr/jsp/board/list.jsp?boardId=23401&mcategoryId=&id=kr_060101000000')

client_errors = [400, 401, 403, 404, 408]
server_errors = [500,502, 503, 504]

print(time.strftime("%c", time.localtime(time.time())))

if req.status_code in client_errors:
    print(req.status_code + ": 클라이언트 에러")
    sys.exit(1)
elif req.status_code in server_errors:
    print(req.status_code + ": 서버 에러")
    sys.exit(1)

bot = telegram.Bot(token=my_token)
html = req.text
soup = BeautifulSoup(html, "html.parser")
posts = soup.select("td > a")
num = soup.find_all(title='공지')

for i in range(len(num)):           # 공지로 위로 올라간 게시글 제외한 최신 게시글 분류
    del posts[0]

if not(os.path.isfile(os.path.join(BASE_DIR, 'latest.txt'))):
    new_file = open('latest.txt', 'w+', encoding='utf-8')
    new_file.write(posts[0].text)
    new_file.close()

with open(os.path.join(BASE_DIR, 'latest.txt'), 'r+', encoding='utf-8') as f_read:
    before = f_read.readline()

    for post in posts:
        print('post = ' + post.text)
        print('before = ' + before)
        if before == post.text:
            print('최신글입니다.')
            break
        elif before != post.text:
            url = "http://www.halla.ac.kr/mbs/kr/jsp/board/" + post.get('href')
            print(url)
            try:
                if post != posts[10]:
                    bot.sendMessage(chat_id=my_chat_id, text="일반공지 : " + post.text)
                    bot.sendMessage(chat_id=my_chat_id, text=url)
                else:
                    break
            except Exception as ex:
                print("timeout")
                break

with open(os.path.join(BASE_DIR, 'latest.txt'), 'w+', encoding='utf--8') as f_write:
    f_write.write(posts[0].text)
```

정확한 로그 확인을 위해서<br>
time 모듈을 사용해 시간을 출력해주기로 했다.<br>

# 추가 설정

python3은 따로 설치해야한다<br>
python3을 따로 설치하면 pip3를 설치해서 모듈을 설치해야한다.<br>

# 다음 시간에

드디어 끝났다.<br>
다음 챕터에서는 후기를 남길예정이다.<br>

# 참고문헌

> notice_alarm, "https://github.com/mildsalmon/notice_alarm", [mildsalmon]
