code/python

Python+GitHub Actions: 깃허브 프로필에 티스토리 글 목록 연동하기

devstdio 2020. 7. 19. 12:23

개요

얼마 전 GitHub에 username/username repo를 만들고 README.md에 원하는 내용을 작성하면 원하는 내용을 본인의 프로필 페이지에 표시할 수 있게 되었습니다.

(이렇게 말이죠)

티스토리 활동과 GitHub 활동 모두를 하고 있는데 저걸 이용해서 GitHub에도 본인의 블로그를 홍보해보면 어떨까.. 하는 생각으로 삽질이 시작되었습니다.

삽질

원본 코드는 이쪽에서 확인하실 수 있습니다. 직접 사용을 원하신다면 fork해가셔서 수정 후 사용하시면 될 것같습니다.

구상

일단 블로그 피드를 가져오기로 했고, 구현을 위해서는 총 5가지의 과정을 자동으로 거쳐야 합니다.

  1. 글 목록을 가져와서
  2. 최근 글 목록을 적당히 가져온 다음
  3. 적당히 가공해서 README.md에 저장하고
  4. GitHub에 바로 commit-push를 시킨다
  5. 그리고 1. - 4.를 일정 시간마다 반복하게 한다

1. 은 API를 쓰면 될 듯했고, 2. - 3.은 가져온 데이터를 적당히 Python에서 가공하면 되니 큰 문제는 아니였습니다. 4.- 5.의 경우, 사실 GitHub Actions는 아예 처음이지만 구글이라는 친구를 가지고 있으니 어떻게든 되지 않을까 생각했고요.
그리고 실행에 옮기기 위해 이것저것 검색해보는데, 현재는 거의 쓰이지 않지만 이런 류의 작업에 딱 맞는 것이 생각났습니다.

RSS

예전 블로그나 뉴스 사이트에서는 RSS 피드를 제공했습니다. RSS 피드를 구독하면 구독한 사이트에서 올라오는 글이나 뉴스 등을 한 페이지에서 바로 확인할 수 있고, 이러한 장점으로 꽤나 쓰였지만 지금은 네이티브로 지원하는 브라우저가 IE 말고는 없다시피 하고, 거의 잊혀가는 기술이라고도 할 수 있겠네요. 다만 아직도 티스토리에서는 이를 지원하고 있고, 글 목록을 바로 가져오기에도 정말 쉬워서 RSS를 사용해보기로 했습니다.

티스토리 블로그 내 RSS 설정

블로그 관리 페이지로 들어가서, 관리-블로그로 들어갑니다. 밑으로 내려보면 RSS 피드 설정이 가능한데, 공개될 피드의 개수까지 설정이 가능하니 변경하고 싶다면 변경해주세요.

글 목록 가져와서 가공하기

좌측이 Chrome, 우측이 IE입니다.

RSS 피드의 모양은 대략 이뤟게 생겼다는 것을 파악했고, 이제 Python에서 이를 가져올 방법만 파악하면 됩니다. 그리고 정말 친절하게도 Python에는 `feedparser`라는 모듈이 있네요. 그리고 RSS 피드를 가져와서 가공하는 방법도 정말 쉽습니다.

 

테스트를 위해

1
$ python -m pip install feedparser
cs

 

로 모듈을 설치해줍시다. 이후 간단하게 코드를 짜서 피드가 불러와지는 방식을 확인해봅니다.

1
2
3
4
5
6
import feedparser
 
tistory_blog_uri="https://blog.stdio.dev"
feed = feedparser.parse(tistory_blog_uri+"/rss")
 
print(feed)
cs

 

feed['entries']를 적당히 불러오면 될 것 같네요. 한 번 해봅시다.

1
2
for i in feed['entries']:
    print(i['link'], i['title'])
cs

 

훌륭합니다.

링크와 글 이름을 불러올 수 있었고, 원한다면 본문까지 불러올 수 있습니다. 글 포스팅 시간도 추가해봅시다.

1
feed['entries'][0]['published']
cs

 

를 출력해보면Fri, 17 Jul 2020 17:01:22 +0900와 같은 형식으로 출력되는 것을 확인할 수 있는데, 이것도 datetime을 이용해 가공할 수 있습니다.

 

1
2
import datetime
datetime.datetime.strptime(feed['entries'][0]['published'], "%a, %d %b %Y %H:%M:%S %z").strftime("%Y.%m.%d %H:%M")
cs

와 같은 형식으로 바꿔줄 수도 있죠(2020.07.17 17:01). 원하는 대로 자유롭게 바꿔주면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import feedparser, datetime
 
tistory_blog_uri="https://blog.stdio.dev"
feed = feedparser.parse(tistory_blog_uri+"/rss")
 
markdown_text = """# Hello, World!
(자기소개)
## Recent blog posts
""" # list of blog posts will be appended here
 
lst = []
 
dt = datetime.datetime.strptime(i['published'], "%a, %d %b %Y %H:%M:%S %z").strftime("%b %d, %Y")
 
for i in feed['entries']:
    markdown_text += f"[{i['title']}]({i['link']}) - {dt}<br>\n"
    print(i['link'], i['title'])
 
= open("README.md",mode="w", encoding="utf-8")
f.write(markdown_text)
f.close()
cs

마지막으로 README.md로 저장까지 해주면 끝납니다. 대략 이렇게 코드가 완성됐네요 서식은 따로 다른 파일에 빼서 불러와도 괜찮을 것같습니다.

커밋-푸쉬 자동화 및 스케줄 설정

이제 GitHub Actions를 이용해 이 코드를 GitHub repo 내에서 실행하도록 할 것이고, 또한 이 코드가 매일 실행되도록 할 것입니다.
우선 repo를 만들어야겠죠? 여기로 가서 GitHub 사용자 이름과 동일한 repo를 만들어줍니다.

special한 repo가 생성되었습니다.

 

이제 Actions로 가서, New Workflow-Continuous integration workflows에서 Publish Python Package 워크플로우를 만들어줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
 
name: README Updater
 
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
  schedule:
    - cron: "0 0 */1 * *"
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python 3.7
      uses: actions/setup-python@v2
      with:
        python-version: '3.7'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install feedparser
    - name: Update README
      run: |
        python main.py
    - name: Commit README
      run: |
        git add .
        git diff
        git config --local user.email "action@gihtub.com"
        git config --local user.name "GitHub Action"
        git commit -"Update README.md"
        git push
cs

 

저는 이렇게 설정했습니다. 단계적으로 뭐가 뭔지 알아봅시다.

1
2
3
4
5
6
7
8
9
name: README Updater
 
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
  schedule:
    - cron: "0 0 */1 * *"
cs

 

에서 on:을 통해 액션이 트리거될 조건을 설정합니다. repo에 push, 또는 pull_request가 있을 때에 액션이 트리거되고, 이와 별개로 이 액션이 매일 실행되도록 cron 스케줄링을 해주었습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python 3.7
      uses: actions/setup-python@v2
      with:
        python-version: '3.7'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install feedparser
cs

ubuntu-latest 환경에서 Python 3.7을 설치하고, 이후 pip를 업데이트하고 feedparser를 설치해줍니다.

 

1
2
3
    - name: Update README
      run: |
        python main.py
cs

main.py를 실행합니다.

1
2
3
4
5
6
7
8
    - name: Commit README
      run: |
        git add .
        git diff
        git config --local user.email "action@gihtub.com"
        git config --local user.name "GitHub Action"
        git commit -"Update README.md"
        git push
cs

 

README.mdcommit하고 push합니다.

대략 이런 과정으로 자동화를 진행하였고, 이후 이 액션을 저장해주면..

 

잘 돌아갑니다! 생각했던 것보다 꽤나 간단했기 때문에 앞으로도 액션을 활용할 일은 정말 많을 것 같네요.

코드는 이쪽을 참조해주시기 바라고, 직접 GitHub에 써보고 싶으시다면 fork하셔서 자신의 블로그에 맞게 변경하시면 될 것 같습니다. 

반응형

'code > python' 카테고리의 다른 글

빠른 Python 정리 11: 반복  (0) 2019.06.01
빠른 Python 정리 10: 조건  (0) 2019.05.28
빠른 Python 정리 09: set  (0) 2019.05.22
빠른 Python 정리 08: dict  (0) 2019.05.16
빠른 Python 정리 07: list & tuple  (0) 2019.05.12